示例#1
0
  @Override
  public void reset() {
    resetForForward();
    _status = 200;
    _reason = null;
    _contentLength = -1;
    _fields.clear();

    String connection = _channel.getRequest().getHttpFields().getStringField(HttpHeader.CONNECTION);
    if (connection != null) {
      String[] values = connection.split(",");
      for (int i = 0; values != null && i < values.length; i++) {
        HttpHeaderValue cb = HttpHeaderValue.CACHE.get(values[0].trim());

        if (cb != null) {
          switch (cb) {
            case CLOSE:
              _fields.put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.toString());
              break;

            case KEEP_ALIVE:
              if (HttpVersion.HTTP_1_0.is(_channel.getRequest().getProtocol()))
                _fields.put(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.toString());
              break;
            case TE:
              _fields.put(HttpHeader.CONNECTION, HttpHeaderValue.TE.toString());
              break;
          }
        }
      }
    }
  }
  @Override
  public void exchangeTerminated(HttpExchange exchange, Result result) {
    super.exchangeTerminated(exchange, result);

    Response response = result.getResponse();
    HttpFields responseHeaders = response.getHeaders();

    String closeReason = null;
    if (result.isFailed()) closeReason = "failure";
    else if (receiver.isShutdown()) closeReason = "server close";

    if (closeReason == null) {
      if (response.getVersion().compareTo(HttpVersion.HTTP_1_1) < 0) {
        // HTTP 1.0 must close the connection unless it has
        // an explicit keep alive or it's a CONNECT method.
        boolean keepAlive =
            responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.KEEP_ALIVE.asString());
        boolean connect = HttpMethod.CONNECT.is(exchange.getRequest().getMethod());
        if (!keepAlive && !connect) closeReason = "http/1.0";
      } else {
        // HTTP 1.1 or greater closes only if it has an explicit close.
        if (responseHeaders.contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString()))
          closeReason = "http/1.1";
      }
    }

    if (closeReason != null) {
      if (LOG.isDebugEnabled()) LOG.debug("Closing, reason: {} - {}", closeReason, connection);
      connection.close();
    } else {
      if (response.getStatus() == HttpStatus.SWITCHING_PROTOCOLS_101) connection.remove();
      else release();
    }
  }
示例#3
0
 /**
  * Sends an error 500, performing a special logic to detect whether the request is suspended, to
  * avoid concurrent writes from the application.
  *
  * <p>It may happen that the application suspends, and then throws an exception, while an
  * application spawned thread writes the response content; in such case, we attempt to commit the
  * error directly bypassing the {@link ErrorHandler} mechanisms and the response OutputStream.
  *
  * @param x the Throwable that caused the problem
  */
 protected void handleException(Throwable x) {
   try {
     _request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, x);
     _request.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, x.getClass());
     if (_state.isSuspended()) {
       HttpFields fields = new HttpFields();
       fields.add(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE);
       ResponseInfo info =
           new ResponseInfo(
               _request.getHttpVersion(),
               fields,
               0,
               HttpStatus.INTERNAL_SERVER_ERROR_500,
               null,
               _request.isHead());
       boolean committed = sendResponse(info, null, true);
       if (!committed) LOG.warn("Could not send response error 500: " + x);
       _request.getAsyncContext().complete();
     } else if (isCommitted()) {
       if (!(x instanceof EofException)) LOG.warn("Could not send response error 500: " + x);
     } else {
       _response.setHeader(HttpHeader.CONNECTION.asString(), HttpHeaderValue.CLOSE.asString());
       _response.sendError(500, x.getMessage());
     }
   } catch (IOException e) {
     // We tried our best, just log
     LOG.debug("Could not commit response error 500", e);
   }
 }