Java Code Examples for org.apache.catalina.connector.Request#getAttribute()

The following examples show how to use org.apache.catalina.connector.Request#getAttribute() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AuthenticatorBase.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
/**
 * Look for the X509 certificate chain in the Request under the key
 * <code>javax.servlet.request.X509Certificate</code>. If not found, trigger
 * extracting the certificate chain from the Coyote request.
 *
 * @param request
 *            Request to be processed
 *
 * @return The X509 certificate chain if found, <code>null</code> otherwise.
 */
protected X509Certificate[] getRequestCertificates(final Request request)
        throws IllegalStateException {

    X509Certificate certs[] =
            (X509Certificate[]) request.getAttribute(Globals.CERTIFICATES_ATTR);

    if ((certs == null) || (certs.length < 1)) {
        try {
            request.getCoyoteRequest().action(ActionCode.REQ_SSL_CERTIFICATE, null);
            certs = (X509Certificate[]) request.getAttribute(Globals.CERTIFICATES_ATTR);
        } catch (IllegalStateException ise) {
            // Request body was too large for save buffer
            // Return null which will trigger an auth failure
        }
    }

    return certs;
}
 
Example 2
Source File: AccessLogValve.java    From tomcatsrc with Apache License 2.0 6 votes vote down vote up
@Override
public void addElement(StringBuilder buf, Date date, Request request,
        Response response, long time) {
    Object value = null;
    if (request != null) {
        value = request.getAttribute(header);
    } else {
        value = "??";
    }
    if (value != null) {
        if (value instanceof String) {
            buf.append((String) value);
        } else {
            buf.append(value.toString());
        }
    } else {
        buf.append('-');
    }
}
 
Example 3
Source File: AbstractAccessLogValve.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
@Override
public void addElement(CharArrayWriter buf, Date date, Request request,
        Response response, long time) {
    String value = null;
    if (requestAttributesEnabled) {
        Object host = request.getAttribute(REMOTE_HOST_ATTRIBUTE);
        if (host != null) {
            value = host.toString();
        }
    }
    if (value == null || value.length() == 0) {
        value = request.getRemoteHost();
    }
    if (value == null || value.length() == 0) {
        value = "-";
    }

    if (ipv6Canonical) {
        value = IPv6Utils.canonize(value);
    }
    buf.append(value);
}
 
Example 4
Source File: AccessLogValve.java    From Tomcat7.0.67 with Apache License 2.0 6 votes vote down vote up
@Override
public void addElement(StringBuilder buf, Date date, Request request,
        Response response, long time) {
    // Don't need to flush since trigger for log message is after the
    // response has been committed
    long length = response.getBytesWritten(false);
    if (length <= 0) {
        // Protect against nulls and unexpected types as these values
        // may be set by untrusted applications
        Object start = request.getAttribute(
                Globals.SENDFILE_FILE_START_ATTR);
        if (start instanceof Long) {
            Object end = request.getAttribute(
                    Globals.SENDFILE_FILE_END_ATTR);
            if (end instanceof Long) {
                length = ((Long) end).longValue() -
                        ((Long) start).longValue();
            }
        }
    }
    if (length <= 0 && conversion) {
        buf.append('-');
    } else {
        buf.append(length);
    }
}
 
Example 5
Source File: AccessLogValve.java    From tomcatsrc with Apache License 2.0 6 votes vote down vote up
@Override
public void addElement(StringBuilder buf, Date date, Request request,
        Response response, long time) {
    String value = null;
    if (requestAttributesEnabled) {
        Object host = request.getAttribute(REMOTE_HOST_ATTRIBUTE);
        if (host != null) {
            value = host.toString();
        }
    }
    if (value == null || value.length() == 0) {
        value = request.getRemoteHost();
    }
    if (value == null || value.length() == 0) {
        value = "-";
    }
    buf.append(value);
}
 
Example 6
Source File: AbstractAccessLogValve.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
@Override
public void addElement(CharArrayWriter buf, Date date, Request request,
        Response response, long time) {
    // Don't need to flush since trigger for log message is after the
    // response has been committed
    long length = response.getBytesWritten(false);
    if (length <= 0) {
        // Protect against nulls and unexpected types as these values
        // may be set by untrusted applications
        Object start = request.getAttribute(
                Globals.SENDFILE_FILE_START_ATTR);
        if (start instanceof Long) {
            Object end = request.getAttribute(
                    Globals.SENDFILE_FILE_END_ATTR);
            if (end instanceof Long) {
                length = ((Long) end).longValue() -
                        ((Long) start).longValue();
            }
        }
    }
    if (length <= 0 && conversion) {
        buf.append('-');
    } else {
        buf.append(Long.toString(length));
    }
}
 
Example 7
Source File: AbstractAccessLogValve.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
@Override
public void addElement(CharArrayWriter buf, Date date, Request request,
        Response response, long time) {
    Object value = null;
    if (request != null) {
        value = request.getAttribute(header);
    } else {
        value = "??";
    }
    if (value != null) {
        if (value instanceof String) {
            buf.append((String) value);
        } else {
            buf.append(value.toString());
        }
    } else {
        buf.append('-');
    }
}
 
Example 8
Source File: AccessLogValve.java    From tomcatsrc with Apache License 2.0 6 votes vote down vote up
@Override
public void addElement(StringBuilder buf, Date date, Request request,
        Response response, long time) {
    if (requestAttributesEnabled && portType == PortType.LOCAL) {
        Object port = request.getAttribute(SERVER_PORT_ATTRIBUTE);
        if (port == null) {
            buf.append(request.getServerPort());
        } else {
            buf.append(port);
        }
    } else {
        if (portType == PortType.LOCAL) {
            buf.append(Integer.toString(request.getServerPort()));
        } else {
            buf.append(Integer.toString(request.getRemotePort()));
        }
    }
}
 
Example 9
Source File: AbstractAccessLogValve.java    From Tomcat8-Source-Read with MIT License 5 votes vote down vote up
/**
 * Log a message summarizing the specified request and response, according
 * to the format specified by the <code>pattern</code> property.
 *
 * @param request Request being processed
 * @param response Response being processed
 *
 * @exception IOException if an input/output error has occurred
 * @exception ServletException if a servlet error has occurred
 */
@Override
public void invoke(Request request, Response response) throws IOException,
        ServletException {
    if (tlsAttributeRequired) {
        // The log pattern uses TLS attributes. Ensure these are populated
        // before the request is processed because with NIO2 it is possible
        // for the connection to be closed (and the TLS info lost) before
        // the access log requests the TLS info. Requesting it now causes it
        // to be cached in the request.
        request.getAttribute(Globals.CERTIFICATES_ATTR);
    }
    getNext().invoke(request, response);
}
 
Example 10
Source File: AccessLogValve.java    From Tomcat7.0.67 with Apache License 2.0 5 votes vote down vote up
@Override
public void addElement(StringBuilder buf, Date date, Request request,
        Response response, long time) {
    if (requestAttributesEnabled) {
        Object proto = request.getAttribute(PROTOCOL_ATTRIBUTE);
        if (proto == null) {
            buf.append(request.getProtocol());
        } else {
            buf.append(proto);
        }
    } else {
        buf.append(request.getProtocol());
    }
}
 
Example 11
Source File: AbstractKeycloakAuthenticatorValve.java    From keycloak with Apache License 2.0 5 votes vote down vote up
protected void logoutInternal(Request request) {
    KeycloakSecurityContext ksc = (KeycloakSecurityContext)request.getAttribute(KeycloakSecurityContext.class.getName());
    if (ksc != null) {
        CatalinaHttpFacade facade = new OIDCCatalinaHttpFacade(request, null);
        KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
        if (ksc instanceof RefreshableKeycloakSecurityContext) {
            ((RefreshableKeycloakSecurityContext) ksc).logout(deployment);
        }

        AdapterTokenStore tokenStore = getTokenStore(request, facade, deployment);
        tokenStore.logout();
        request.removeAttribute(KeycloakSecurityContext.class.getName());
    }
    request.setUserPrincipal(null);
}
 
Example 12
Source File: AccessLogValve.java    From tomcatsrc with Apache License 2.0 5 votes vote down vote up
@Override
public void addElement(StringBuilder buf, Date date, Request request,
        Response response, long time) {
    if (requestAttributesEnabled) {
        Object addr = request.getAttribute(REMOTE_ADDR_ATTRIBUTE);
        if (addr == null) {
            buf.append(request.getRemoteAddr());
        } else {
            buf.append(addr);
        }
    } else {
        buf.append(request.getRemoteAddr());
    }
}
 
Example 13
Source File: AbstractAccessLogValve.java    From Tomcat8-Source-Read with MIT License 5 votes vote down vote up
@Override
public void addElement(CharArrayWriter buf, Date date, Request request,
        Response response, long time) {
    if (requestAttributesEnabled) {
        Object proto = request.getAttribute(PROTOCOL_ATTRIBUTE);
        if (proto == null) {
            buf.append(request.getProtocol());
        } else {
            buf.append(proto.toString());
        }
    } else {
        buf.append(request.getProtocol());
    }
}
 
Example 14
Source File: JDBCAccessLogValve.java    From Tomcat8-Source-Read with MIT License 4 votes vote down vote up
@Override
public void log(Request request, Response response, long time) {
    if (!getState().isAvailable()) {
        return;
    }

    final String EMPTY = "" ;

    String remoteHost;
    if(resolveHosts) {
        if (requestAttributesEnabled) {
            Object host = request.getAttribute(REMOTE_HOST_ATTRIBUTE);
            if (host == null) {
                remoteHost = request.getRemoteHost();
            } else {
                remoteHost = (String) host;
            }
        } else {
            remoteHost = request.getRemoteHost();
        }
    } else {
        if (requestAttributesEnabled) {
            Object addr = request.getAttribute(REMOTE_ADDR_ATTRIBUTE);
            if (addr == null) {
                remoteHost = request.getRemoteAddr();
            } else {
                remoteHost = (String) addr;
            }
        } else {
            remoteHost = request.getRemoteAddr();
        }
    }
    String user = request.getRemoteUser();
    String query=request.getRequestURI();

    long bytes = response.getBytesWritten(true);
    if(bytes < 0) {
        bytes = 0;
    }
    int status = response.getStatus();
    String virtualHost = EMPTY;
    String method = EMPTY;
    String referer = EMPTY;
    String userAgent = EMPTY;
    String logPattern = pattern;
    if (logPattern.equals("combined")) {
        virtualHost = request.getServerName();
        method = request.getMethod();
        referer = request.getHeader("referer");
        userAgent = request.getHeader("user-agent");
    }
    synchronized (this) {
      int numberOfTries = 2;
      while (numberOfTries>0) {
        try {
            open();

            ps.setString(1, remoteHost);
            ps.setString(2, user);
            ps.setTimestamp(3, new Timestamp(getCurrentTimeMillis()));
            ps.setString(4, query);
            ps.setInt(5, status);

            if(useLongContentLength) {
                ps.setLong(6, bytes);
            } else {
                if (bytes > Integer.MAX_VALUE) {
                    bytes = -1 ;
                }
                ps.setInt(6, (int) bytes);
            }
            if (logPattern.equals("combined")) {
                  ps.setString(7, virtualHost);
                  ps.setString(8, method);
                  ps.setString(9, referer);
                  ps.setString(10, userAgent);
            }
            ps.executeUpdate();
            return;
          } catch (SQLException e) {
            // Log the problem for posterity
              container.getLogger().error(sm.getString("jdbcAccessLogValve.exception"), e);

            // Close the connection so that it gets reopened next time
            if (conn != null) {
                close();
            }
          }
          numberOfTries--;
       }
    }

}
 
Example 15
Source File: ErrorReportValve.java    From Tomcat8-Source-Read with MIT License 4 votes vote down vote up
/**
 * Invoke the next Valve in the sequence. When the invoke returns, check
 * the response state. If the status code is greater than or equal to 400
 * or an uncaught exception was thrown then the error handling will be
 * triggered.
 *
 * @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()) {
        if (response.setErrorReported()) {
            // Error wasn't previously reported but we can't write an error
            // page because the response has already been committed. Attempt
            // to flush any data that is still to be written to the client.
            try {
                response.flushBuffer();
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
            }
            // Close immediately to signal to the client that something went
            // wrong
            response.getCoyoteResponse().action(ActionCode.CLOSE_NOW,
                    request.getAttribute(RequestDispatcher.ERROR_EXCEPTION));
        }
        return;
    }

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

    // If an async request is in progress and is not going to end once this
    // container thread finishes, do not process any error page here.
    if (request.isAsync() && !request.isAsyncCompleting()) {
        return;
    }

    if (throwable != null && !response.isError()) {
        // Make sure that the necessary methods have been called on the
        // response. (It is possible a component may just have set the
        // Throwable. Tomcat won't do that but other components might.)
        // These are safe to call at this point as we know that the response
        // has not been committed.
        response.reset();
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }

    // One way or another, response.sendError() will have been called before
    // execution reaches this point and suspended the response. Need to
    // reverse that so this valve can write to the response.
    response.setSuspended(false);

    try {
        report(request, response, throwable);
    } catch (Throwable tt) {
        ExceptionUtils.handleThrowable(tt);
    }
}
 
Example 16
Source File: ErrorReportValve.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
/**
 * Invoke the next Valve in the sequence. When the invoke returns, check
 * the response state. If the status code is greater than or equal to 400
 * or an uncaught exception was thrown then the error handling will be
 * triggered.
 *
 * @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()) {
        if (response.setErrorReported()) {
            // Error wasn't previously reported but we can't write an error
            // page because the response has already been committed. Attempt
            // to flush any data that is still to be written to the client.
            try {
                response.flushBuffer();
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
            }
            // Close immediately to signal to the client that something went
            // wrong
            response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
        }
        return;
    }

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

    // If an async request is in progress and is not going to end once this
    // container thread finishes, do not trigger error page handling - it
    // will be triggered later if required.
    if (request.isAsync() && !request.isAsyncCompleting()) {
        return;
    }

    if (throwable != null && !response.isError()) {
        // Make sure that the necessary methods have been called on the
        // response. (It is possible a component may just have set the
        // Throwable. Tomcat won't do that but other components might.)
        // These are safe to call at this point as we know that the response
        // has not been committed.
        response.reset();
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }

    // One way or another, response.sendError() will have been called before
    // execution reaches this point and suspended the response. Need to
    // reverse that so this valve can write to the response.
    response.setSuspended(false);

    try {
        report(request, response, throwable);
    } catch (Throwable tt) {
        ExceptionUtils.handleThrowable(tt);
    }
}
 
Example 17
Source File: JDBCAccessLogValve.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
@Override
public void log(Request request, Response response, long time) {
    if (!getState().isAvailable()) {
        return;
    }

    final String EMPTY = "" ;

    String remoteHost;
    if(resolveHosts) {
        if (requestAttributesEnabled) {
            Object host = request.getAttribute(REMOTE_HOST_ATTRIBUTE);
            if (host == null) {
                remoteHost = request.getRemoteHost();
            } else {
                remoteHost = (String) host;
            }
        } else {
            remoteHost = request.getRemoteHost();
        }
    } else {
        if (requestAttributesEnabled) {
            Object addr = request.getAttribute(REMOTE_ADDR_ATTRIBUTE);
            if (addr == null) {
                remoteHost = request.getRemoteAddr();
            } else {
                remoteHost = (String) addr;
            }
        } else {
            remoteHost = request.getRemoteAddr();
        }
    }
    String user = request.getRemoteUser();
    String query=request.getRequestURI();

    long bytes = response.getBytesWritten(true);
    if(bytes < 0) {
        bytes = 0;
    }
    int status = response.getStatus();
    String virtualHost = EMPTY;
    String method = EMPTY;
    String referer = EMPTY;
    String userAgent = EMPTY;
    String logPattern = pattern;
    if (logPattern.equals("combined")) {
        virtualHost = request.getServerName();
        method = request.getMethod();
        referer = request.getHeader("referer");
        userAgent = request.getHeader("user-agent");
    }
    synchronized (this) {
      int numberOfTries = 2;
      while (numberOfTries>0) {
        try {
            open();

            ps.setString(1, remoteHost);
            ps.setString(2, user);
            ps.setTimestamp(3, new Timestamp(getCurrentTimeMillis()));
            ps.setString(4, query);
            ps.setInt(5, status);

            if(useLongContentLength) {
                ps.setLong(6, bytes);
            } else {
                if (bytes > Integer.MAX_VALUE) {
                    bytes = -1 ;
                }
                ps.setInt(6, (int) bytes);
            }
            if (logPattern.equals("combined")) {
                  ps.setString(7, virtualHost);
                  ps.setString(8, method);
                  ps.setString(9, referer);
                  ps.setString(10, userAgent);
            }
            ps.executeUpdate();
            return;
          } catch (SQLException e) {
            // Log the problem for posterity
              container.getLogger().error(sm.getString("jdbcAccessLogValve.exception"), e);

            // Close the connection so that it gets reopened next time
            if (conn != null) {
                close();
            }
          }
          numberOfTries--;
       }
    }

}
 
Example 18
Source File: CrossSubdomainSessionValve.java    From scipio-erp with Apache License 2.0 4 votes vote down vote up
protected void replaceCookie(Request request, Response response, Cookie cookie) {

        Delegator delegator = (Delegator) request.getAttribute("delegator");
        // copy the existing session cookie, but use a different domain (only if domain is valid)
        String cookieDomain = null;
        cookieDomain = EntityUtilProperties.getPropertyValue("url", "cookie.domain", "", delegator);

        if (UtilValidate.isEmpty(cookieDomain)) {
            String serverName = request.getServerName();
            String[] domainArray = serverName.split("\\.");
            // check that the domain isn't an IP address
            if (domainArray.length == 4) {
                boolean isIpAddress = true;
                for (String domainSection : domainArray) {
                    if (!UtilValidate.isIntegerInRange(domainSection, 0, 255)) {
                        isIpAddress = false;
                        break;
                    }
                }
                if (isIpAddress) {
                    return;
                }
            }
            if (domainArray.length > 2) {
                cookieDomain = "." + domainArray[domainArray.length - 2] + "." + domainArray[domainArray.length - 1];
            }
        }


        if (UtilValidate.isNotEmpty(cookieDomain)) {
            Cookie newCookie = new Cookie(cookie.getName(), cookie.getValue());
            if (cookie.getPath() != null) {
                newCookie.setPath(cookie.getPath());
            }
            newCookie.setDomain(cookieDomain);
            newCookie.setMaxAge(cookie.getMaxAge());
            newCookie.setVersion(cookie.getVersion());
            if (cookie.getComment() != null) {
                newCookie.setComment(cookie.getComment());
            }
            newCookie.setSecure(cookie.getSecure());
            newCookie.setHttpOnly(cookie.isHttpOnly());

            // if the response has already been committed, our replacement strategy will have no effect
            if (response.isCommitted()) {
                Debug.logError("CrossSubdomainSessionValve: response was already committed!", module);
            }

            // find the Set-Cookie header for the existing cookie and replace its value with new cookie
            MimeHeaders mimeHeaders = request.getCoyoteRequest().getMimeHeaders();
            for (int i = 0, size = mimeHeaders.size(); i < size; i++) {
                if (mimeHeaders.getName(i).equals("Set-Cookie")) {
                    MessageBytes value = mimeHeaders.getValue(i);
                    if (value.indexOf(cookie.getName()) >= 0) {
                        String newCookieValue = request.getContext().getCookieProcessor().generateHeader(newCookie);
                        if (Debug.verboseOn()) Debug.logVerbose("CrossSubdomainSessionValve: old Set-Cookie value: " + value.toString(), module);
                        if (Debug.verboseOn()) Debug.logVerbose("CrossSubdomainSessionValve: new Set-Cookie value: " + newCookieValue, module);
                        value.setString(newCookieValue);
                    }
                }
            }
        }
    }
 
Example 19
Source File: AccessValve.java    From DataHubSystem with GNU Affero General Public License v3.0 4 votes vote down vote up
@Override
public void invoke (Request request, Response response) throws IOException,
   ServletException
{
   // Case of Valve disabled.
   if (!isEnable())
   {
      getNext().invoke(request, response);
      return;
   }
   
   final AccessInformation ai = new AccessInformation();
   ai.setConnectionStatus(new PendingConnectionStatus());
   
   // To be sure not to retrieve the same date trough concurrency calls.
   synchronized (this)
   {
      ai.setStartTimestamp(System.nanoTime());  
      ai.setStartDate (new Date ());
   }
   try
   {
      this.doLog(request, response, ai);
   }
   finally
   {
      Element cached_element = new Element(UUID.randomUUID(), ai);
      getCache().put(cached_element);
      
      try
      {
         // Log of the pending request command.
         if (isUseLogger()) LOGGER.info ("Access " + ai);
         
         getNext().invoke(request, response);
      }
      catch (Throwable e)
      {
         response.addHeader("cause-message", 
            e.getClass().getSimpleName() + " : " + e.getMessage());
         //ai.setConnectionStatus(new FailureConnectionStatus(e));
         response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
         //throw e;
      }
      finally
      {
         ai.setReponseSize(response.getContentLength());
         ai.setWrittenResponseSize(response.getContentWritten());
         
         if (response.getStatus()>=400)
         {
            String message = RequestUtil.filter(response.getMessage());
            if (message==null)
            {
               // The cause-message has been inserted into the reponse header
               // at error handler time. It no message is retrieved in the
               // standard response, the cause-message is used.
               message = response.getHeader("cause-message");
            }
            Throwable throwable = null;
            if (message != null) throwable = new Throwable(message);
            else throwable = (Throwable) request.getAttribute(
               RequestDispatcher.ERROR_EXCEPTION); 
            if (throwable==null) throwable = new Throwable();
            
            ai.setConnectionStatus(new FailureConnectionStatus(throwable));
         }
         else
            ai.setConnectionStatus(new SuccessConnectionStatus());
   
         ai.setEndTimestamp(System.nanoTime());
         if ((getPattern()==null) || ai.getRequest().matches(getPattern()))
         {
            cached_element.updateUpdateStatistics();
            if (isUseLogger()) LOGGER.info ("Access " + ai);
         }
      }
   }
}
 
Example 20
Source File: ErrorReportValve.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
/**
 * Invoke the next Valve in the sequence. When the invoke returns, check
 * the response state. If the status code is greater than or equal to 400
 * or an uncaught exception was thrown then the error handling will be
 * triggered.
 *
 * @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()) {
        if (response.setErrorReported()) {
            // Error wasn't previously reported but we can't write an error
            // page because the response has already been committed. Attempt
            // to flush any data that is still to be written to the client.
            try {
                response.flushBuffer();
            } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
            }
            // Close immediately to signal to the client that something went
            // wrong
            response.getCoyoteResponse().action(ActionCode.CLOSE_NOW, null);
        }
        return;
    }

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

    // If an async request is in progress and is not going to end once this
    // container thread finishes, do not process any error page here.
    if (request.isAsync() && !request.isAsyncCompleting()) {
        return;
    }

    if (throwable != null && !response.isError()) {
        // Make sure that the necessary methods have been called on the
        // response. (It is possible a component may just have set the
        // Throwable. Tomcat won't do that but other components might.)
        // These are safe to call at this point as we know that the response
        // has not been committed.
        response.reset();
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }

    // One way or another, response.sendError() will have been called before
    // execution reaches this point and suspended the response. Need to
    // reverse that so this valve can write to the response.
    response.setSuspended(false);

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