Esempio n. 1
0
  @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, "<", "&lt;");
          message = StringUtil.replace(message, ">", "&gt;");
        }
        String uri = request.getRequestURI();
        if (uri != null) {
          uri = StringUtil.replace(uri, "&", "&amp;");
          uri = StringUtil.replace(uri, "<", "&lt;");
          uri = StringUtil.replace(uri, ">", "&gt;");
        }

        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());
  }