@Override public void sendError(int code, String message) throws IOException { if (isIncluding()) return; if (isCommitted()) LOG.warn("Committed before " + code + " " + message); resetBuffer(); _characterEncoding = null; setHeader(HttpHeader.EXPIRES, null); setHeader(HttpHeader.LAST_MODIFIED, null); setHeader(HttpHeader.CACHE_CONTROL, null); setHeader(HttpHeader.CONTENT_TYPE, null); setHeader(HttpHeader.CONTENT_LENGTH, null); _outputType = OutputType.NONE; setStatus(code); _reason = message; Request request = _channel.getRequest(); Throwable cause = (Throwable) request.getAttribute(Dispatcher.ERROR_EXCEPTION); if (message == null) message = cause == null ? HttpStatus.getMessage(code) : cause.toString(); // If we are allowed to have a body if (code != SC_NO_CONTENT && code != SC_NOT_MODIFIED && code != SC_PARTIAL_CONTENT && code >= SC_OK) { ErrorHandler error_handler = null; ContextHandler.Context context = request.getContext(); if (context != null) error_handler = context.getContextHandler().getErrorHandler(); if (error_handler == null) error_handler = _channel.getServer().getBean(ErrorHandler.class); if (error_handler != null) { request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, new Integer(code)); request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message); request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI()); request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME, request.getServletName()); error_handler.handle(null, _channel.getRequest(), _channel.getRequest(), this); } else { setHeader(HttpHeader.CACHE_CONTROL, "must-revalidate,no-cache,no-store"); setContentType(MimeTypes.Type.TEXT_HTML_8859_1.toString()); ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(2048); if (message != null) { message = StringUtil.replace(message, "&", "&"); message = StringUtil.replace(message, "<", "<"); message = StringUtil.replace(message, ">", ">"); } String uri = request.getRequestURI(); if (uri != null) { uri = StringUtil.replace(uri, "&", "&"); uri = StringUtil.replace(uri, "<", "<"); uri = StringUtil.replace(uri, ">", ">"); } writer.write( "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\"/>\n"); writer.write("<title>Error "); writer.write(Integer.toString(code)); writer.write(' '); if (message == null) writer.write(message); writer.write("</title>\n</head>\n<body>\n<h2>HTTP ERROR: "); writer.write(Integer.toString(code)); writer.write("</h2>\n<p>Problem accessing "); writer.write(uri); writer.write(". Reason:\n<pre> "); writer.write(message); writer.write("</pre>"); writer.write("</p>\n<hr /><i><small>Powered by Jetty://</small></i>"); writer.write("\n</body>\n</html>\n"); writer.flush(); setContentLength(writer.size()); writer.writeTo(getOutputStream()); writer.destroy(); } } else if (code != SC_PARTIAL_CONTENT) { // TODO work out why this is required? _channel.getRequest().getHttpFields().remove(HttpHeader.CONTENT_TYPE); _channel.getRequest().getHttpFields().remove(HttpHeader.CONTENT_LENGTH); _characterEncoding = null; _mimeType = null; } complete(); }
protected void commit(ByteBuffer content, boolean complete, Callback callback) { // Are we excluding because of status? Response response = _channel.getResponse(); int sc = response.getStatus(); if (sc > 0 && (sc < 200 || sc == 204 || sc == 205 || sc >= 300)) { LOG.debug("{} exclude by status {}", this, sc); noCompression(); if (sc == 304) { String request_etags = (String) _channel.getRequest().getAttribute("o.e.j.s.h.gzip.GzipHandler.etag"); String response_etag = response.getHttpFields().get(HttpHeader.ETAG); if (request_etags != null && response_etag != null) { String response_etag_gzip = etagGzip(response_etag); if (request_etags.contains(response_etag_gzip)) response.getHttpFields().put(HttpHeader.ETAG, response_etag_gzip); } } _interceptor.write(content, complete, callback); return; } // Are we excluding because of mime-type? String ct = response.getContentType(); if (ct != null) { ct = MimeTypes.getContentTypeWithoutCharset(ct); if (!_factory.isMimeTypeGzipable(StringUtil.asciiToLowerCase(ct))) { LOG.debug("{} exclude by mimeType {}", this, ct); noCompression(); _interceptor.write(content, complete, callback); return; } } // Has the Content-Encoding header already been set? HttpFields fields = response.getHttpFields(); String ce = fields.get(HttpHeader.CONTENT_ENCODING); if (ce != null) { LOG.debug("{} exclude by content-encoding {}", this, ce); noCompression(); _interceptor.write(content, complete, callback); return; } // Are we the thread that commits? if (_state.compareAndSet(GZState.MIGHT_COMPRESS, GZState.COMMITTING)) { // We are varying the response due to accept encoding header. if (_vary != null) { if (fields.contains(HttpHeader.VARY)) fields.addCSV(HttpHeader.VARY, _vary.getValues()); else fields.add(_vary); } long content_length = response.getContentLength(); if (content_length < 0 && complete) content_length = content.remaining(); _deflater = _factory.getDeflater(_channel.getRequest(), content_length); if (_deflater == null) { LOG.debug("{} exclude no deflater", this); _state.set(GZState.NOT_COMPRESSING); _interceptor.write(content, complete, callback); return; } fields.put(GZIP._contentEncoding); _crc.reset(); _buffer = _channel.getByteBufferPool().acquire(_bufferSize, false); BufferUtil.fill(_buffer, GZIP_HEADER, 0, GZIP_HEADER.length); // Adjust headers response.setContentLength(-1); String etag = fields.get(HttpHeader.ETAG); if (etag != null) fields.put(HttpHeader.ETAG, etagGzip(etag)); LOG.debug("{} compressing {}", this, _deflater); _state.set(GZState.COMPRESSING); gzip(content, complete, callback); } else callback.failed(new WritePendingException()); }