w3c.css.servlet.CssValidator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cssvalidator Show documentation
Show all versions of cssvalidator Show documentation
Backend for the W3C CSS Validation Service
//
// $Id$
// From Philippe Le Hegaret ([email protected])
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.servlet;
import org.w3c.css.css.CssParser;
import org.w3c.css.css.DocumentParser;
import org.w3c.css.css.StyleReport;
import org.w3c.css.css.StyleReportFactory;
import org.w3c.css.css.StyleSheet;
import org.w3c.css.css.StyleSheetParser;
import org.w3c.css.css.TagSoupStyleSheetHandler;
import org.w3c.css.error.ErrorReport;
import org.w3c.css.error.ErrorReportFactory;
import org.w3c.css.index.IndexGenerator;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.Codecs;
import org.w3c.css.util.CssVersion;
import org.w3c.css.util.FakeFile;
import org.w3c.css.util.HTTPURL;
import org.w3c.css.util.NVPair;
import org.w3c.css.util.Utf8Properties;
import org.w3c.css.util.Util;
import org.w3c.www.mime.MimeType;
import org.w3c.www.mime.MimeTypeFormatException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ProtocolException;
import java.net.URL;
/**
* This class is a servlet to use the validator.
*
* @version $Revision$
*/
@SuppressWarnings("serial")
public final class CssValidator extends HttpServlet {
final static String texthtml = "text/html";
final static String applxhtml = "application/xhtml+xml";
final static String textplain = "text/plain";
final static String textcss = "text/css";
final static String textunknown = "text/unknown";
final static String soap12 = "application/soap+xml";
final static String json = "application/json";
final static String opt_file = "file";
final static String opt_text = "text";
final static String opt_lang = "lang";
final static String opt_output = "output";
final static String opt_warning = "warning";
final static String opt_error = "error";
final static String opt_profile = "profile";
final static String opt_usermedium = "usermedium";
final static String opt_vextwarning = "vextwarning";
final static String opt_type = "type";
public final static String server_name =
"Jigsaw/2.3.0 W3C_CSS_Validator_JFouffa/2.0 (See )";
final static String headers_name = "X-W3C-Validator-";
/**
* Create a new CssValidator.
*/
public CssValidator() {
}
/**
* Initializes the servlet and logs the initialization. The init method is
* called once, automatically, by the network service each time it loads
* the servlet. It is guaranteed to finish before any service requests are
* accepted. On fatal initialization errors, an UnavailableException should
* be thrown. Do not call the method System.exit.
*
*
* The init method stores the ServletConfig object. Servlet writers who
* specialize this method should call either super.init, or store the
* ServletConfig object themselves. If an implementor decides to store the
* ServletConfig object in a different location, then the getServletConfig
* method must also be overridden.
*
*
*
* Init parameters:
* - debug
*
true
if you want to be in debug mode.
* - aural
*
true
if you want to be in aural mode.
* - import
*
false
if you don't want to activate the import
* statement. For security reasons, you shoud be careful when you lunch the
* servlet on a HTTP server with special access authorization.
* - input
*
html
if the user have an HTML input or
* xml
otherwise. deprecated
*
*
* @param config servlet configuration information.
* @throws ServletException if a servlet exception has occurred.
*/
public void init(ServletConfig config) throws ServletException {
String pval;
super.init(config);
// [SECURITY] don't forget this !
Util.servlet = true;
pval = config.getInitParameter("debug");
if (pval != null && !pval.isEmpty()) {
// servlet debug mode
// define a boolean property CSS.StyleSheet.debug if you want more
// debug.
Util.onDebug = pval.equals("true");
System.err.println("RUN IN DEBUG MODE: "
+ Util.onDebug);
} else if (Util.onDebug) {
System.err.println("RUN IN DEBUG MODE" +
" but activated outside the servlet");
}
pval = config.getInitParameter("import");
if (pval != null && !pval.isEmpty() && pval.equals("false")) {
Util.importSecurity = true;
}
pval = config.getInitParameter("entitysize");
if (pval != null && !pval.isEmpty()) {
try {
Util.maxEntitySize = Long.parseLong(pval);
} catch (NumberFormatException nfe) {
// the definition was wrong
nfe.printStackTrace();
}
}
// The following code will check if the index files are missing or outdated
// If so, the files will be regenerated
// This is done in a Thread so that the validation can carry on.
new Thread() {
public void run() {
IndexGenerator.generatesIndex(true);
}
}.start();
}
private PrintWriter getLocalPrintWriter(OutputStream os, String encoding)
throws IOException {
if (encoding != null) {
return new PrintWriter(new OutputStreamWriter(os, encoding));
} else {
return new PrintWriter(new OutputStreamWriter(os,
Utf8Properties.ENCODING));
}
}
private void processVendorExtensionParameter(
String vendorExtensionParameter, ApplContext context) {
if (vendorExtensionParameter == null ||
vendorExtensionParameter.isEmpty()) {
vendorExtensionParameter =
getServletConfig().getInitParameter("vendorExtensionsAsWarnings");
}
context.setTreatVendorExtensionsAsWarnings(Boolean.valueOf(vendorExtensionParameter));
// TODO for now we use the same parameter for both vendor extensions and CSS Hacks.
context.setTreatCssHacksAsWarnings(Boolean.valueOf(vendorExtensionParameter));
}
/**
* Performs the HTTP GET operation.
* An HTTP BAD_REQUEST error is reported if
* an error occurs. This servlet writers shouldn't set the headers for the
* requested entity (content type and encoding).
*
*
* Note that the GET operation is expected to be safe, without
* any side effects for which users might be held responsible. For example,
* most form queries have no side effects. Requests intended to change
* stored data should use some other HTTP method. (There have been cases of
* significant security breaches reported because web-based applications
* used GET inappropriately.)
*
*
* The GET operation is also expected to be idempotent, meaning
* that it can safely be repeated. This is not quite the same as being
* safe, but in some common examples the requirements have the same result.
* For example, repeating queries is both safe and idempotent
* (unless payment is required!), but buying something or modifying data
* is neither safe nor idempotent.
*
*
*
* Forms parameters:
* - URL
*
- the URL to be parsed.
*
- submitURL
*
- if the user want to parse an URL.
*
- text
*
- The text to be parsed.
*
- submitTEXT
*
- if the user want to parse the text.
*
- output
*
- HTML if the user want an HTML output or XML otherwise.
*
- input
*
- HTML if the user have an HTML input or XML otherwise.
*
*
* @param req encapsulates the request to the servlet.
* @param res encapsulates the response from the servlet.
* @throws ServletException if the request could not be handled.
* @throws IOException if detected when handling the request.
* @see org.w3c.css.css.StyleSheetGenerator
*/
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
boolean errorReport = true;
int warningLevel = 2;
CssParser parser = null;
String lang = null;
try {
lang = req.getParameter(opt_lang);
} catch (Exception e) {
lang = null;
}
if (lang == null || lang.isEmpty()) {
lang = req.getHeader("Accept-Language");
} else {
lang += ',' + req.getHeader("Accept-Language");
}
ApplContext ac = new ApplContext(lang);
ac.setLink(req.getQueryString());
ac.setContentEncoding(req.getHeader("Accept-Charset"));
String output = req.getParameter(opt_output);
String uri = null;
try {
uri = req.getParameter("uri"); // null if the parameter does not exist
// exist
} catch (Exception ex) {
// pb in URI decoding (bad escaping, most probably)
handleError(res, ac, output, "No file", new IOException(
"Invalid escape sequence in URI"), false);
}
String text = null;
try {
text = req.getParameter(opt_text);
} catch (Exception ex) {
// pb in URI decoding (bad escaping, most probably)
// not sure it will work here, as it may be catched by the first
// getParameter call
handleError(res, ac, output, "Invalid text", new IOException(
"Invalid escape sequence in URI"), false);
}
String warning = req.getParameter(opt_warning);
String error = req.getParameter(opt_error);
String profile = req.getParameter(opt_profile);
String usermedium = req.getParameter(opt_usermedium);
String type = req.getParameter(opt_type);
InputStream in = req.getInputStream();
if (type == null)
type = "none";
String credential = req.getHeader("Authorization");
if ((credential != null) && (credential.length() > 1)) {
ac.setCredential(credential);
}
// CSS version
ac.setCssVersionAndProfile(profile);
// media, only if we are not using CSS1
if (ac.getCssVersion() != CssVersion.CSS1) {
if (usermedium == null || usermedium.isEmpty()) {
usermedium = "all";
}
ac.setMedium(usermedium);
}
if (req.getParameter("debug") != null) {
Util.onDebug = req.getParameter("debug").equals("true");
if (Util.onDebug) {
System.err.println("SWITCH DEBUG MODE REQUEST");
}
} else {
Util.onDebug = false;
}
//text = Util.suppressWhiteSpace(text);
uri = Util.suppressWhiteSpace(uri);
if (output == null) {
output = texthtml;
}
if (Util.onDebug) {
System.err.println("[DEBUG] version is : " + ac.getCssVersionString()
+ " profile is " + ac.getProfileString()
+ " medium is " + usermedium);
}
// verify the request
if ((uri == null) && (text == null)) {
// res.sendError(res.SC_BAD_REQUEST,
// "You have send an invalid request.");
handleError(res, ac, output, "No file",
new IOException(ac.getMsg().getServletString("invalid-request")),
false);
return;
}
in.close();
// set the warning output
if (warning != null) {
if (warning.equals("no")) {
warningLevel = -1;
} else {
try {
warningLevel = Integer.parseInt(warning);
} catch (Exception e) {
System.err.println(e);
}
}
ac.setWarningLevel(warningLevel);
}
// set the error report
if (error != null && error.equals("no")) {
errorReport = false;
}
// Allow vendor extensions to just show up as warnings.
processVendorExtensionParameter(req.getParameter(opt_vextwarning), ac);
// debug mode
Util.verbose("\nServlet request ");
if (uri != null) {
Util.verbose("Source file : " + uri);
} else {
Util.verbose("TEXTAREA Input");
}
// verbose("From " + req.getRemoteHost() +
// " (" + req.getRemoteAddr() + ") at " + (new Date()) );
if (uri != null) {
// HTML document
try {
uri = HTTPURL.getURL(uri).toString(); // needed to be sure
// that it is a valid
// url
uri = uri.replaceAll(" ", "%20");
if (Util.checkURI(uri)) {
DocumentParser URLparser = new DocumentParser(ac, uri);
handleRequest(ac, res, uri, URLparser.getStyleSheet(), output,
warningLevel, errorReport);
} else {
res.setHeader("Rejected", "Requested URI Forbidden by Rule");
handleError(res, ac, output, "Forbidden", new IOException(
"URI Forbidden by rule"), false);
}
} catch (ProtocolException pex) {
if (Util.onDebug) {
pex.printStackTrace();
}
res.setHeader("WWW-Authenticate", pex.getMessage());
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
} catch (Exception e) {
handleError(res, ac, output, uri, e, true);
}
} else if (text != null) {
String fileName = "TextArea";
Util.verbose("- " + fileName + " Data -");
Util.verbose(text);
Util.verbose("- End of " + fileName + " Data");
InputStream is = new ByteArrayInputStream(text.getBytes());
fileName = "file://localhost/" + fileName;
try {
if ("css".equals(type) || ("none".equals(type) && isCSS(text))) {
// if CSS:
parser = new StyleSheetParser();
parser.parseStyleElement(ac, is, null, usermedium,
new URL(fileName), 0);
handleRequest(ac, res, fileName, parser
.getStyleSheet(), output, warningLevel, errorReport);
} else {
// else, trying HTML
// HTMLParserStyleSheetHandler handler = new HTMLParserStyleSheetHandler(null, ac);
TagSoupStyleSheetHandler handler = new TagSoupStyleSheetHandler(null, ac);
handler.parse(is, fileName);
handleRequest(ac, res, fileName, handler.getStyleSheet(), output,
warningLevel, errorReport);
}
} catch (ProtocolException pex) {
if (Util.onDebug) {
pex.printStackTrace();
}
res.setHeader("WWW-Authenticate", pex.getMessage());
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
} catch (Exception e) {
handleError(res, ac, output, fileName, e, false);
}
}
Util.verbose("CssValidator: Request terminated.\n");
}
/**
* This method is used for the direct input
* If the <style> tag is found, it may be an HTML entry
* The exception is when this tag is inside comment
* It might also be an HTML document with no CSS => why ?
* Or with only imports (we can't chack thoses imports...)
*
* @param text, the textarea to test
* @return false if it contains the style tag well formed
*/
private boolean isCSS(String text) {
try {
text = text.toLowerCase();
int p = text.indexOf("");
} catch (Exception e) {
System.err.println("error: " + e.getMessage());
return true;
}
}
/**
* Performs the HTTP POST operation. An HTTP BAD_REQUEST error is reported
* if an error occurs. The headers that are set should include content type,
* length, and encoding. Setting content length allows the servlet to take
* advantage of HTTP "connection keep alive". If content length can not be
* set in advance, the performance penalties associated with not using keep
* alives will sometimes be avoided if the response entity fits in an
* internal buffer. The servlet implementor must write the headers before
* the response data because the headers can be flushed at any time after
* the data starts to be written.
*
*
* This method does not need to be either "safe" or "idempotent". Operations
* requested through POST could be ones for which users need to be held
* accountable. Specific examples including updating stored data or buying
* things online.
*
*
*
* Forms parameters:
* - file
*
- The input file to be parsed.
*
- output
*
- The format output.
*
- input
*
- HTML if the user have an HTML input or XML otherwise.
*
*
* @param req encapsulates the request to the servlet
* @param res encapsulates the response from the servlet
* @throws ServletException if the request could not be handled
* @throws IOException if detected when handling the request
* @see org.w3c.css.css.StyleSheetGenerator
*/
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String lang = null;
try {
lang = req.getParameter("lang");
} catch (Exception e) {
lang = null;
}
boolean errorReport = true;
int warningLevel = 2;
CssParser parser = null;
FakeFile file = null;
String text = null;
String output = null;
//boolean XMLinput = false;
String warning = null;
String error = null;
String profile = "none";
String usermedium = "all";
String vendorExtensionAsWarnings = null;
String inputType = "none";
ServletInputStream in = req.getInputStream();
byte[] buf = new byte[2048];
byte[] general = new byte[65536];
int count = 0;
int len;
if (req.getParameter("debug") != null) {
Util.onDebug = req.getParameter("debug").equals("true");
if (Util.onDebug) {
System.err.println("SWITCH DEBUG MODE REQUEST");
}
} else {
Util.onDebug = false;
}
Util.verbose("\nCssValidator: Servlet request ");
// verbose("From " + req.getRemoteHost() +
// " (" + req.getRemoteAddr() + ") at " + (new Date()) );
Util.verbose("Content-length : " + req.getContentLength());
if (req.getContentType().trim().startsWith("multipart/form-data")) {
Util.verbose("Content-type : multipart/form-data");
}
try {
while ((len = in.readLine(buf, 0, buf.length)) != -1) {
if (len >= 2 && buf[len - 1] == '\n' && buf[len - 2] == '\r') {
len -= 1;
buf[len - 1] = (byte) '\n';
}
if (len != 0 && buf[len - 1] == '\r') {
buf[len - 1] = (byte) '\n';
}
if (general.length < (count + len)) {
byte[] old = general;
general = new byte[old.length * 2];
System.arraycopy(old, 0, general, 0, old.length);
}
System.arraycopy(buf, 0, general, count, len);
count += len;
}
} finally {
in.close();
}
try {
buf = new byte[count];
System.arraycopy(general, 0, buf, 0, count);
for (NVPair pair : Codecs.mpFormDataDecode(buf, req.getContentType())) {
switch (pair.getName()) {
case opt_file:
file = (FakeFile) pair.getValue();
break;
case opt_text:
text = (String) pair.getValue();
break;
case opt_lang:
lang = (String) pair.getValue();
break;
case opt_output:
output = (String) pair.getValue();
break;
case opt_warning:
warning = (String) pair.getValue();
break;
case opt_error:
error = (String) pair.getValue();
break;
case opt_profile:
profile = (String) pair.getValue();
break;
case opt_usermedium:
usermedium = (String) pair.getValue();
break;
case opt_vextwarning:
vendorExtensionAsWarnings = (String) pair.getValue();
break;
case opt_type:
inputType = (String) pair.getValue();
break;
default:
// log extra parameters?
}
}
} catch (Exception e) {
System.out.println("Oups! Error in Util/Codecs.java?!?");
e.printStackTrace();
}
if (lang == null || lang.isEmpty()) {
lang = req.getHeader("Accept-Language");
} else {
lang += ',' + req.getHeader("Accept-Language");
}
ApplContext ac = new ApplContext(lang);
ac.setLink(req.getQueryString());
if (output == null) {
output = texthtml;
}
// set the warning output
if (warning != null) {
if (warning.equals("no")) {
warningLevel = -1;
} else {
try {
warningLevel = Integer.parseInt(warning);
} catch (Exception e) {
System.err.println(e);
}
}
ac.setWarningLevel(warningLevel);
}
// set the error report
if (error != null && error.equals("no")) {
errorReport = false;
}
// Allow vendor extensions to just show up as warnings.
processVendorExtensionParameter(vendorExtensionAsWarnings, ac);
ac.setCssVersionAndProfile(profile);
if (ac.getCssVersion() == CssVersion.CSS1) {
if (usermedium != null && !"all".equals(usermedium)) {
// explicitly set to a non -default value
// let's raise an issue later.
ac.setMedium(usermedium);
}
} else {
if (usermedium == null || usermedium.isEmpty()) {
usermedium = "all";
}
ac.setMedium(usermedium);
}
// CSS version
String fileName = "";
InputStream is = null;
boolean isCSS = false;
if (file != null) {
isCSS = file.getContentType().equals(textcss);
if (file.getSize() == 0) {
file.write("\n".getBytes(), 0, 1);
isCSS = true;
}
ac.setFakeFile(file);
fileName = file.getName();
Util.verbose("File : " + fileName);
} else {
ac.setFakeText(text);
fileName = "TextArea";
Util.verbose("- " + fileName + " Data -");
Util.verbose(text);
Util.verbose("- End of " + fileName + " Data");
//quick test that works in most cases to determine wether it's
//HTML or CSS
// TODO hardcode options using defined strings instead of in the code
switch (inputType) {
case "css":
isCSS = true;
break;
case "html":
isCSS = false;
break;
case "none":
default:
isCSS = isCSS(text);
}
}
fileName = "file://localhost/" + fileName;
try {
URL u = new URL(fileName);
is = ac.getFakeInputStream(u);
ac.setFakeURL(fileName);
if (isCSS) {
//if CSS:
parser = new StyleSheetParser();
parser.parseStyleElement(ac, is, null, ac.getMedium(),
new URL(fileName), 0);
handleRequest(ac, res, fileName, parser.getStyleSheet(),
output, warningLevel, errorReport);
} else {
// else, trying HTML
// HTMLParserStyleSheetHandler handler = new HTMLParserStyleSheetHandler(null, ac);
TagSoupStyleSheetHandler handler = new TagSoupStyleSheetHandler(null, ac);
handler.parse(is, fileName);
handleRequest(ac, res, fileName, handler.getStyleSheet(),
output, warningLevel, errorReport);
}
} catch (ProtocolException pex) {
if (Util.onDebug) {
//pex.printStackTrace();
}
res.setHeader("WWW-Authenticate", pex.getMessage());
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
} catch (Exception e) {
handleError(res, ac, output, fileName, e, false);
}
Util.verbose("CssValidator: Request terminated.\n");
}
private void handleRequest(ApplContext ac, HttpServletResponse res,
String title, StyleSheet styleSheet,
String output, int warningLevel,
boolean errorReport) throws Exception {
buildHeader(ac, res, output);
if (styleSheet == null) {
throw new IOException(ac.getMsg().getServletString("process") + " "
+ title);
}
String outformat;
// if the output parameter was a mime type, we convert it
// to an understandable value for the StyleReportFactory
switch (output) {
case texthtml:
outformat = ("text/xml".equals(ac.getInput())) ? "xhtml" : "html";
break;
case soap12:
outformat = soap12;
break;
case json:
outformat = "json";
break;
case textplain:
outformat = "text";
break;
default:
outformat = output;
}
styleSheet.findConflicts(ac);
StyleReport style = StyleReportFactory.getStyleReport(ac, title,
styleSheet, outformat, warningLevel);
if (!errorReport) {
style.desactivateError();
}
PrintWriter out = getLocalPrintWriter(res.getOutputStream(), ac
.getContentEncoding());
int nb_errors = styleSheet.getErrors().getErrorCount();
res.setHeader(headers_name + "Errors", String.valueOf(nb_errors));
res.setHeader(headers_name + "Status", nb_errors == 0 ? "Valid" : "Invalid");
try {
style.print(out);
} finally {
out.close();
}
}
/**
* Generates the response header
*
* @param ac
* @param res
* @param output
* @throws MimeTypeFormatException
*/
private void buildHeader(ApplContext ac, HttpServletResponse res,
String output) {
// I don't want cache for the response (inhibits proxy)
res.setHeader("Pragma", "no-cache"); // @@deprecated
res.setHeader("Cache-Control", "no-cache");
// Here is a little joke :-)
// res.setHeader("Server", server_name);
if (output == null) {
output = new String(texthtml);
}
// set the content-type for the response
MimeType outputMt = null;
if (output.equals(texthtml) || output.equals("html")) {
outputMt = MimeType.TEXT_HTML.getClone();
} else if (output.equals(applxhtml) || output.equals("xhtml")) {
outputMt = MimeType.APPLICATION_XHTML_XML.getClone();
} else if (output.equals(soap12) || output.equals("soap12")) {
// invert the comments on the following lines to (de)activate
// the soap Mime Type
try {
outputMt = new MimeType(soap12);
} catch (MimeTypeFormatException e) {
outputMt = MimeType.TEXT_PLAIN.getClone();
}
//outputMt = MimeType.TEXT_PLAIN.getClone();
} else if (output.equals("ucn")) {
outputMt = MimeType.APPLICATION_XML.getClone();
} else if (output.equals("json")) {
try {
outputMt = new MimeType(json);
} catch (MimeTypeFormatException e) {
outputMt = MimeType.TEXT_PLAIN.getClone();
}
} else {
// Change this line if you want text/html output when incorrect
// output is passed
outputMt = MimeType.TEXT_PLAIN.getClone();
}
if (ac != null) {
// ignore content encoding if output is SOAP
if (output.equals("soap12")) {
ac.setContentEncoding(null);
}
if (ac.getContentEncoding() != null) {
outputMt.setParameter("charset", ac.getContentEncoding());
}
res.setContentType(outputMt.toString());
if (ac.getContentLanguage() != null) {
res.setHeader("Content-Language", ac.getContentLanguage());
} else {
res.setHeader("Content-Language", "en");
}
} else {
res.setHeader("Content-Language", "en");
res.setHeader("charset", Utf8Properties.ENCODING);
}
res.setHeader("Vary", "Accept-Language");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "content-type,accept-charset");
res.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, OPTIONS");
res.setHeader("Access-Control-Max-Age", "600");
}
private void handleError(HttpServletResponse res, ApplContext ac,
String output, String title, Exception e,
boolean validURI)
throws IOException {
System.err.println("[ERROR VALIDATOR] " + title);
System.err.println(e.toString());
e.printStackTrace();
buildHeader(ac, res, output);
res.setStatus(500);
if ((e instanceof java.net.UnknownHostException) ||
((e instanceof java.io.FileNotFoundException) &&
((e.getMessage().indexOf("Not Found") != -1) ||
(e.getMessage().indexOf("Service Unavailable") != -1)))) {
validURI = true;
} else {
validURI = false;
}
PrintWriter out = getLocalPrintWriter(res.getOutputStream(), ac
.getContentEncoding());
ErrorReport error = ErrorReportFactory.getErrorReport(ac, title, output,
e, validURI);
res.setHeader(headers_name + "Status", "Abort");
try {
error.print(out);
} finally {
out.close();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy