Esempio n. 1
0
  /** @return True if the channel is ready to continue handling (ie it is not suspended) */
  public boolean handle() {
    LOG.debug("{} handle enter", this);

    setCurrentHttpChannel(this);

    String threadName = null;
    if (LOG.isDebugEnabled()) {
      threadName = Thread.currentThread().getName();
      Thread.currentThread().setName(threadName + " - " + _uri);
    }

    // Loop here to handle async request redispatches.
    // The loop is controlled by the call to async.unhandle in the
    // finally block below.  Unhandle will return false only if an async dispatch has
    // already happened when unhandle is called.
    HttpChannelState.Next next = _state.handling();
    while (next == Next.CONTINUE && getServer().isRunning()) {
      boolean error = false;
      try {
        _request.setHandled(false);
        _response.getHttpOutput().reopen();

        if (_state.isInitial()) {
          _request.setTimeStamp(System.currentTimeMillis());
          _request.setDispatcherType(DispatcherType.REQUEST);

          for (HttpConfiguration.Customizer customizer : _configuration.getCustomizers())
            customizer.customize(getConnector(), _configuration, _request);
          getServer().handle(this);
        } else {
          if (_request.getHttpChannelState().isExpired()) {
            _request.setDispatcherType(DispatcherType.ERROR);

            Throwable ex = _state.getAsyncContextEvent().getThrowable();
            String reason = "Async Timeout";
            if (ex != null) {
              reason = "Async Exception";
              _request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ex);
            }
            _request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, new Integer(500));
            _request.setAttribute(RequestDispatcher.ERROR_MESSAGE, reason);
            _request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, _request.getRequestURI());

            _response.setStatusWithReason(500, reason);

            ErrorHandler eh = _state.getContextHandler().getErrorHandler();
            if (eh instanceof ErrorHandler.ErrorPageMapper) {
              String error_page =
                  ((ErrorHandler.ErrorPageMapper) eh)
                      .getErrorPage(
                          (HttpServletRequest) _state.getAsyncContextEvent().getSuppliedRequest());
              if (error_page != null) _state.getAsyncContextEvent().setDispatchPath(error_page);
            }
          } else _request.setDispatcherType(DispatcherType.ASYNC);
          getServer().handleAsync(this);
        }
      } catch (Error e) {
        if ("ContinuationThrowable".equals(e.getClass().getSimpleName())) LOG.ignore(e);
        else {
          error = true;
          throw e;
        }
      } catch (Exception e) {
        error = true;
        if (e instanceof EofException) LOG.debug(e);
        else LOG.warn(String.valueOf(_uri), e);
        _state.error(e);
        _request.setHandled(true);
        handleException(e);
      } finally {
        if (error && _state.isAsyncStarted()) _state.errorComplete();
        next = _state.unhandle();
      }
    }

    if (threadName != null && LOG.isDebugEnabled()) Thread.currentThread().setName(threadName);
    setCurrentHttpChannel(null);

    if (next == Next.COMPLETE) {
      try {
        _state.completed();

        if (!_response.isCommitted() && !_request.isHandled()) _response.sendError(404);
        else
          // Complete generating the response
          _response.closeOutput();
      } catch (EofException | ClosedChannelException e) {
        LOG.debug(e);
      } catch (Exception e) {
        LOG.warn("complete failed", e);
      } finally {
        _request.setHandled(true);
        _transport.completed();
      }
    }

    LOG.debug("{} handle exit, result {}", this, next);

    return next != Next.WAIT;
  }