/**
   * Handle the HTTP status code (and corresponding message) generated while processing the
   * specified Request to produce the specified Response. Any exceptions that occur during
   * generation of the error report are logged and swallowed.
   *
   * @param request The request being processed
   * @param response The response being generated
   */
  private void status(Request request, Response response) {

    int statusCode = response.getStatus();

    // Handle a custom error page for this status code
    Context context = request.getContext();
    if (context == null) return;

    /* Only look for error pages when isError() is set.
     * isError() is set when response.sendError() is invoked. This
     * allows custom error pages without relying on default from
     * web.xml.
     */
    if (!response.isError()) return;

    ErrorPage errorPage = context.findErrorPage(statusCode);
    if (errorPage == null) {
      // Look for a default error page
      errorPage = context.findErrorPage(0);
    }
    if (errorPage != null && response.setErrorReported()) {
      response.setAppCommitted(false);
      request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, Integer.valueOf(statusCode));

      String message = response.getMessage();
      if (message == null) message = "";
      request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message);
      request.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, errorPage.getLocation());
      request.setAttribute(Globals.DISPATCHER_TYPE_ATTR, DispatcherType.ERROR);

      Wrapper wrapper = request.getWrapper();
      if (wrapper != null)
        request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME, wrapper.getName());
      request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI());
      if (custom(request, response, errorPage)) {
        try {
          response.finishResponse();
        } catch (ClientAbortException e) {
          // Ignore
        } catch (IOException e) {
          container.getLogger().warn("Exception Processing " + errorPage, e);
        }
      }
    }
  }
Beispiel #2
0
  /**
   * Invoke the next Valve in the sequence. When the invoke returns, check the response state, and
   * output an error report is necessary.
   *
   * @param request The servlet request to be processed
   * @param response The servlet response to be created
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a servlet error occurs
   */
  @Override
  public void invoke(Request request, Response response) throws IOException, ServletException {

    // Perform the request
    getNext().invoke(request, response);

    if (response.isCommitted()) {
      return;
    }

    Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);

    if (request.isAsyncStarted() && response.getStatus() < 400 && throwable == null) {
      return;
    }

    if (throwable != null) {

      // The response is an error
      response.setError();

      // Reset the response (if possible)
      try {
        response.reset();
      } catch (IllegalStateException e) {
        // Ignore
      }

      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }

    response.setSuspended(false);

    try {
      report(request, response, throwable);
    } catch (Throwable tt) {
      ExceptionUtils.handleThrowable(tt);
    }

    if (request.isAsyncStarted()) {
      request.getAsyncContext().complete();
    }
  }
Beispiel #3
0
  /**
   * Log the interesting request parameters, invoke the next Valve in the sequence, and log the
   * interesting response parameters.
   *
   * @param request The servlet request to be processed
   * @param response The servlet response to be created
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a servlet error occurs
   */
  public void invoke(Request request, Response response) throws IOException, ServletException {

    Log log = container.getLogger();

    // Log pre-service information
    log.info("REQUEST URI       =" + request.getRequestURI());
    log.info("          authType=" + request.getAuthType());
    log.info(" characterEncoding=" + request.getCharacterEncoding());
    log.info("     contentLength=" + request.getContentLength());
    log.info("       contentType=" + request.getContentType());
    log.info("       contextPath=" + request.getContextPath());
    Cookie cookies[] = request.getCookies();
    if (cookies != null) {
      for (int i = 0; i < cookies.length; i++)
        log.info("            cookie=" + cookies[i].getName() + "=" + cookies[i].getValue());
    }
    Enumeration hnames = request.getHeaderNames();
    while (hnames.hasMoreElements()) {
      String hname = (String) hnames.nextElement();
      Enumeration hvalues = request.getHeaders(hname);
      while (hvalues.hasMoreElements()) {
        String hvalue = (String) hvalues.nextElement();
        log.info("            header=" + hname + "=" + hvalue);
      }
    }
    log.info("            locale=" + request.getLocale());
    log.info("            method=" + request.getMethod());
    Enumeration pnames = request.getParameterNames();
    while (pnames.hasMoreElements()) {
      String pname = (String) pnames.nextElement();
      String pvalues[] = request.getParameterValues(pname);
      StringBuffer result = new StringBuffer(pname);
      result.append('=');
      for (int i = 0; i < pvalues.length; i++) {
        if (i > 0) result.append(", ");
        result.append(pvalues[i]);
      }
      log.info("         parameter=" + result.toString());
    }
    log.info("          pathInfo=" + request.getPathInfo());
    log.info("          protocol=" + request.getProtocol());
    log.info("       queryString=" + request.getQueryString());
    log.info("        remoteAddr=" + request.getRemoteAddr());
    log.info("        remoteHost=" + request.getRemoteHost());
    log.info("        remoteUser="******"requestedSessionId=" + request.getRequestedSessionId());
    log.info("            scheme=" + request.getScheme());
    log.info("        serverName=" + request.getServerName());
    log.info("        serverPort=" + request.getServerPort());
    log.info("       servletPath=" + request.getServletPath());
    log.info("          isSecure=" + request.isSecure());
    log.info("---------------------------------------------------------------");

    // Perform the request
    getNext().invoke(request, response);

    // Log post-service information
    log.info("---------------------------------------------------------------");
    log.info("          authType=" + request.getAuthType());
    log.info("     contentLength=" + response.getContentLength());
    log.info("       contentType=" + response.getContentType());
    Cookie rcookies[] = response.getCookies();
    for (int i = 0; i < rcookies.length; i++) {
      log.info(
          "            cookie="
              + rcookies[i].getName()
              + "="
              + rcookies[i].getValue()
              + "; domain="
              + rcookies[i].getDomain()
              + "; path="
              + rcookies[i].getPath());
    }
    String rhnames[] = response.getHeaderNames();
    for (int i = 0; i < rhnames.length; i++) {
      String rhvalues[] = response.getHeaderValues(rhnames[i]);
      for (int j = 0; j < rhvalues.length; j++)
        log.info("            header=" + rhnames[i] + "=" + rhvalues[j]);
    }
    log.info("           message=" + response.getMessage());
    log.info("        remoteUser="******"            status=" + response.getStatus());
    log.info("===============================================================");
  }
  private void oneTest(
      String allow,
      String deny,
      boolean denyStatus,
      boolean addConnectorPort,
      boolean auth,
      String property,
      String type,
      boolean allowed) {
    // PREPARE
    RequestFilterValve valve = null;
    Connector connector = new Connector();
    Context context = new StandardContext();
    Request request = new Request();
    Response response = new MockResponse();
    StringBuilder msg = new StringBuilder();
    int expected = allowed ? OK : FORBIDDEN;

    connector.setPort(PORT);
    request.setConnector(connector);
    request.setContext(context);
    request.setCoyoteRequest(new org.apache.coyote.Request());

    if (type == null) {
      fail("Invalid test with null type");
    }
    if (property != null) {
      if (type.equals("Addr")) {
        valve = new RemoteAddrValve();
        request.setRemoteAddr(property);
        msg.append(" ip='" + property + "'");
      } else if (type.equals("Host")) {
        valve = new RemoteHostValve();
        request.setRemoteHost(property);
        msg.append(" host='" + property + "'");
      } else {
        fail("Invalid test type" + type);
      }
    }
    valve.setNext(new TerminatingValve());

    if (allow != null) {
      valve.setAllow(allow);
      msg.append(" allow='" + allow + "'");
    }
    if (deny != null) {
      valve.setDeny(deny);
      msg.append(" deny='" + deny + "'");
    }
    if (denyStatus) {
      valve.setDenyStatus(CUSTOM);
      msg.append(" denyStatus='" + CUSTOM + "'");
      if (!allowed) {
        expected = CUSTOM;
      }
    }
    if (addConnectorPort) {
      if (valve instanceof RemoteAddrValve) {
        ((RemoteAddrValve) valve).setAddConnectorPort(true);
      } else if (valve instanceof RemoteHostValve) {
        ((RemoteHostValve) valve).setAddConnectorPort(true);
      } else {
        fail("Can only set 'addConnectorPort' for RemoteAddrValve and RemoteHostValve");
      }
      msg.append(" addConnectorPort='true'");
    }
    if (auth) {
      context.setPreemptiveAuthentication(true);
      valve.setInvalidAuthenticationWhenDeny(true);
      msg.append(" auth='true'");
    }

    // TEST
    try {
      valve.invoke(request, response);
    } catch (IOException ex) {
      // Ignore
    } catch (ServletException ex) {
      // Ignore
    }

    // VERIFY
    if (!allowed && auth) {
      assertEquals(msg.toString(), OK, response.getStatus());
      assertEquals(msg.toString(), "invalid", request.getHeader("authorization"));
    } else {
      assertEquals(msg.toString(), expected, response.getStatus());
    }
  }
Beispiel #5
0
  /**
   * Prints out an error report.
   *
   * @param request The request being processed
   * @param response The response being generated
   * @param throwable The exception that occurred (which possibly wraps a root cause exception
   */
  protected void report(Request request, Response response, Throwable throwable) {

    // Do nothing on non-HTTP responses
    int statusCode = response.getStatus();

    // Do nothing on a 1xx, 2xx and 3xx status
    // Do nothing if anything has been written already
    if (statusCode < 400 || response.getContentWritten() > 0 || !response.isError()) {
      return;
    }

    String message = RequestUtil.filter(response.getMessage());
    if (message == null) {
      if (throwable != null) {
        String exceptionMessage = throwable.getMessage();
        if (exceptionMessage != null && exceptionMessage.length() > 0) {
          message = RequestUtil.filter((new Scanner(exceptionMessage)).nextLine());
        }
      }
      if (message == null) {
        message = "";
      }
    }

    // Do nothing if there is no report for the specified status code
    String report = null;
    try {
      report = sm.getString("http." + statusCode);
    } catch (Throwable t) {
      ExceptionUtils.handleThrowable(t);
    }
    if (report == null) {
      return;
    }

    StringBuilder sb = new StringBuilder();

    sb.append("<html><head><title>");
    sb.append(ServerInfo.getServerInfo()).append(" - ");
    sb.append(sm.getString("errorReportValve.errorReport"));
    sb.append("</title>");
    sb.append("<style><!--");
    sb.append(org.apache.catalina.util.TomcatCSS.TOMCAT_CSS);
    sb.append("--></style> ");
    sb.append("</head><body>");
    sb.append("<h1>");
    sb.append(sm.getString("errorReportValve.statusHeader", "" + statusCode, message))
        .append("</h1>");
    sb.append("<HR size=\"1\" noshade=\"noshade\">");
    sb.append("<p><b>type</b> ");
    if (throwable != null) {
      sb.append(sm.getString("errorReportValve.exceptionReport"));
    } else {
      sb.append(sm.getString("errorReportValve.statusReport"));
    }
    sb.append("</p>");
    sb.append("<p><b>");
    sb.append(sm.getString("errorReportValve.message"));
    sb.append("</b> <u>");
    sb.append(message).append("</u></p>");
    sb.append("<p><b>");
    sb.append(sm.getString("errorReportValve.description"));
    sb.append("</b> <u>");
    sb.append(report);
    sb.append("</u></p>");

    if (throwable != null) {

      String stackTrace = getPartialServletStackTrace(throwable);
      sb.append("<p><b>");
      sb.append(sm.getString("errorReportValve.exception"));
      sb.append("</b> <pre>");
      sb.append(RequestUtil.filter(stackTrace));
      sb.append("</pre></p>");

      int loops = 0;
      Throwable rootCause = throwable.getCause();
      while (rootCause != null && (loops < 10)) {
        stackTrace = getPartialServletStackTrace(rootCause);
        sb.append("<p><b>");
        sb.append(sm.getString("errorReportValve.rootCause"));
        sb.append("</b> <pre>");
        sb.append(RequestUtil.filter(stackTrace));
        sb.append("</pre></p>");
        // In case root cause is somehow heavily nested
        rootCause = rootCause.getCause();
        loops++;
      }

      sb.append("<p><b>");
      sb.append(sm.getString("errorReportValve.note"));
      sb.append("</b> <u>");
      sb.append(sm.getString("errorReportValve.rootCauseInLogs", ServerInfo.getServerInfo()));
      sb.append("</u></p>");
    }

    sb.append("<HR size=\"1\" noshade=\"noshade\">");
    sb.append("<h3>").append(ServerInfo.getServerInfo()).append("</h3>");
    sb.append("</body></html>");

    try {
      try {
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
      } catch (Throwable t) {
        ExceptionUtils.handleThrowable(t);
        if (container.getLogger().isDebugEnabled()) {
          container.getLogger().debug("status.setContentType", t);
        }
      }
      Writer writer = response.getReporter();
      if (writer != null) {
        // If writer is null, it's an indication that the response has
        // been hard committed already, which should never happen
        writer.write(sb.toString());
      }
    } catch (IOException e) {
      // Ignore
    } catch (IllegalStateException e) {
      // Ignore
    }
  }
 @Override
 public int getStatus() {
   return response.getStatus();
 }