FileDocCategorySizeDatePackage
StandardHostValve.javaAPI DocGlassfish v2 API23350Fri May 04 22:31:54 BST 2007org.apache.catalina.core

StandardHostValve

public final class StandardHostValve extends org.apache.catalina.valves.ValveBase
Valve that implements the default basic behavior for the StandardHost container implementation.

USAGE CONSTRAINT: This implementation is likely to be useful only when processing HTTP requests.

author
Craig R. McClanahan
author
Remy Maucherat
version
$Revision: 1.22 $ $Date: 2007/05/05 05:31:54 $

Fields Summary
private static com.sun.org.apache.commons.logging.Log
log
private static final ClassLoader
standardHostValveClassLoader
private static final String
info
The descriptive information related to this implementation.
private static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
private org.apache.catalina.Valve
errorReportValve
Constructors Summary
Methods Summary
protected booleancustom(org.apache.catalina.Request request, org.apache.catalina.Response response, org.apache.catalina.deploy.ErrorPage errorPage)
Handle an HTTP status code or Java exception by forwarding control to the location included in the specified errorPage object. It is assumed that the caller has already recorded any request attributes that are to be forwarded to this page. Return true if we successfully utilized the specified error page location, or false if the default error report should be rendered.

param
request The request being processed
param
response The response being generated
param
errorPage The errorPage directive we are obeying


        if (debug >= 1)
            log("Processing " + errorPage);

        // Validate our current environment
        /* GlassFish 6386229
        if (!(request instanceof HttpRequest)) {
            if (debug >= 1)
                log(" Not processing an HTTP request --> default handling");
            return (false);     // NOTE - Nothing we can do generically
        }
        */
        HttpServletRequest hreq =
            (HttpServletRequest) request.getRequest();
        /* GlassFish 6386229
        if (!(response instanceof HttpResponse)) {
            if (debug >= 1)
                log("Not processing an HTTP response --> default handling");
            return (false);     // NOTE - Nothing we can do generically
        }
        */
        HttpServletResponse hres =
            (HttpServletResponse) response.getResponse();

        ((HttpRequest) request).setPathInfo(errorPage.getLocation());

        try {

            // Reset the response if possible (else IllegalStateException)
            //hres.reset();
            // Reset the response (keeping the real error code and message)
            Integer statusCodeObj =
                (Integer) hreq.getAttribute(Globals.STATUS_CODE_ATTR);
            int statusCode = statusCodeObj.intValue();
            String message = 
                (String) hreq.getAttribute(Globals.ERROR_MESSAGE_ATTR);
            ((HttpResponse) response).reset(statusCode, message);

            // Forward control to the specified location
            ServletContext servletContext =
                request.getContext().getServletContext();
            RequestDispatcher rd =
                servletContext.getRequestDispatcher(errorPage.getLocation());
            rd.forward(hreq, hres);

            // If we forward, the response is suspended again
            response.setSuspended(false);

            // Indicate that we have successfully processed this custom page
            return (true);

        } catch (Throwable t) {

            // Report our failure to process this custom page
            log("Exception Processing " + errorPage, t);
            return (false);

        }

    
protected static org.apache.catalina.deploy.ErrorPagefindErrorPage(org.apache.catalina.Context context, java.lang.Throwable exception)
Find and return the ErrorPage instance for the specified exception's class, or an ErrorPage instance for the closest superclass for which there is such a definition. If no associated ErrorPage instance is found, return null.

param
context The Context in which to search
param
exception The exception for which to find an ErrorPage


        if (exception == null)
            return (null);
        Class clazz = exception.getClass();
        String name = clazz.getName();
        while (!Object.class.equals(clazz)) {
            ErrorPage errorPage = context.findErrorPage(name);
            if (errorPage != null)
                return (errorPage);
            clazz = clazz.getSuperclass();
            if (clazz == null)
                break;
            name = clazz.getName();
        }
        return (null);

    
public java.lang.StringgetInfo()
Return descriptive information about this Valve implementation.

    // END SJSAS 6374691


    // ------------------------------------------------------------- Properties


                
       

        return (info);

    
private voidhandleHostErrorPage(org.apache.catalina.Response response, org.apache.catalina.deploy.ErrorPage errorPage, int statusCode)
Copies the contents of the given error page to the response, and updates the status message with the reason string of the error page.

param
response The response object
param
errorPage The error page whose contents are to be copied
param
statusCode The status code


        ServletOutputStream ostream = null;
        PrintWriter writer = null;
        FileReader reader = null;
        BufferedInputStream istream = null;
        IOException ioe = null;

        String message = errorPage.getReason();
        if (message != null) {
            ((HttpResponse) response).reset(statusCode, message);
        }
         
        try {
            ostream = response.getResponse().getOutputStream();
        } catch (IllegalStateException e) {
            // If it fails, we try to get a Writer instead if we're
            // trying to serve a text file
            writer = response.getResponse().getWriter();
        }

        if (writer != null) {
            reader = new FileReader(errorPage.getLocation());
            ioe = ResponseUtil.copy(reader, writer);
            try {
                reader.close();
            } catch (Throwable t) {
                ;
            }
        } else {
            istream = new BufferedInputStream(
                new FileInputStream(errorPage.getLocation()));
            ioe = ResponseUtil.copy(istream, ostream);
            try {
                istream.close();
            } catch (Throwable t) {
                ;
            }
        }

        // Rethrow any exception that may have occurred
        if (ioe != null) {
            throw ioe;
        }
    
public intinvoke(org.apache.catalina.Request request, org.apache.catalina.Response response)
IASRI 4665318 public void invoke(Request request, Response response, ValveContext valveContext) throws IOException, ServletException {

     // END OF IASRI 4665318

        // Select the Context to be used for this Request
        Context context = request.getContext();
        if (context == null) {
            /* S1AS 4878272
            ((HttpServletResponse) response.getResponse()).sendError
                (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                 sm.getString("standardHost.noContext"));
            */
            // BEGIN S1AS 4878272
            ((HttpServletResponse) response.getResponse()).sendError
                (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.setDetailMessage(sm.getString("standardHost.noContext"));
            // END S1AS 4878272
            // START OF IASRI 4665318
            // return;     // NOTE - Not much else we can do generically
            return END_PIPELINE;
            // END OF IASRI 4665318
        }

        // Bind the context CL to the current thread
        if( context.getLoader() != null ) {
            // Not started - it should check for availability first
            // This should eventually move to Engine, it's generic.
            Thread.currentThread().setContextClassLoader
                    (context.getLoader().getClassLoader());
        }
                 
        // START GlassFish Issue 1057
        // Update the session last access time for our session (if any)
        HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
        hreq.getSession(false);
        // END GlassFish Issue 1057

        // Ask this Context to process this request
        // START OF IASRI 4665318
        context.getPipeline().invoke(request, response);
        return END_PIPELINE;
    
protected voidlog(java.lang.String message)
Log a message on the Logger associated with our Container (if any).

param
message Message to be logged


        Logger logger = container.getLogger();
        if (logger != null)
            logger.log(this.toString() + ": " + message);
        else
            System.out.println(this.toString() + ": " + message);

    
protected voidlog(java.lang.String message, java.lang.Throwable throwable)
Log a message on the Logger associated with our Container (if any).

param
message Message to be logged
param
throwable Associated exception


        Logger logger = container.getLogger();
        if (logger != null)
            logger.log(this.toString() + ": " + message, throwable);
        else {
            System.out.println(this.toString() + ": " + message);
            throwable.printStackTrace(System.out);
        }

    
public voidpostInvoke(org.apache.catalina.Request request, org.apache.catalina.Response response)

        // START SJSAS 6374990
        if (((ServletResponse) response).isCommitted()) {
            return;
        }
        // END SJSAS 6374990

        HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
        // END OF IASRI 4665318
        // Error page processing
        response.setSuspended(false);

        Throwable t = (Throwable) hreq.getAttribute(Globals.EXCEPTION_ATTR);

        if (t != null) {
            throwable(request, response, t);
        } else {
            status(request, response);
        }

        Thread.currentThread().setContextClassLoader
            (standardHostValveClassLoader);

        // START SJSAS 6374691
        if (errorReportValve != null) {
            errorReportValve.postInvoke(request, response);
        }
        // END SJSAS 6374691
    
voidsetErrorReportValve(org.apache.catalina.Valve errorReportValve)

        this.errorReportValve = errorReportValve;
    
protected voidstatus(org.apache.catalina.Request request, org.apache.catalina.Response response)
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


        /* 6386229
        // Do nothing on non-HTTP responses
        if (!(response instanceof HttpResponse))
            return;
        */
        HttpResponse hresponse = (HttpResponse) response;
        /* 6386229
        if (!(response.getResponse() instanceof HttpServletResponse))
            return;
        */
        int statusCode = hresponse.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.
         */
        if (!response.isError()) {
            return;
        }

        ErrorPage errorPage = context.findErrorPage(statusCode);
        if (errorPage != null) {
            response.setAppCommitted(false);
            ServletRequest sreq = request.getRequest();
            ServletResponse sresp = response.getResponse();
            sreq.setAttribute(Globals.STATUS_CODE_ATTR,
                              Integer.valueOf(statusCode));
            String message = RequestUtil.filter(hresponse.getMessage());
            if (message == null)
                message = "";
            sreq.setAttribute(Globals.ERROR_MESSAGE_ATTR, message);
            sreq.setAttribute
                (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
                 errorPage.getLocation());
            sreq.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
                              Integer.valueOf(ApplicationFilterFactory.ERROR));
            
             
            Wrapper wrapper = request.getWrapper();
            if (wrapper != null)
                sreq.setAttribute(Globals.SERVLET_NAME_ATTR,
                                  wrapper.getName());
            if (sreq instanceof HttpServletRequest)
                sreq.setAttribute(Globals.EXCEPTION_PAGE_ATTR,
                                  ((HttpServletRequest) sreq).getRequestURI());
            if (custom(request, response, errorPage)) {
                try {
                    sresp.flushBuffer();
                } catch (IOException e) {
                    log("Exception Processing " + errorPage, e);
                }
            }
        }
        // START SJSAS 6324911
        else {
            errorPage = ((StandardHost) getContainer()).findErrorPage(
                                                        statusCode);
            if (errorPage != null) {
                try {
                    handleHostErrorPage(response, errorPage, statusCode);
                } catch (Exception e) {
                    log("Exception Processing " + errorPage, e);
                }
            }
        }
        // END SJSAS 6324911
    
protected voidthrowable(org.apache.catalina.Request request, org.apache.catalina.Response response, java.lang.Throwable throwable)
Handle the specified Throwable encountered while processing the specified Request to produce the specified Response. Any exceptions that occur during generation of the exception report are logged and swallowed.

param
request The request being processed
param
response The response being generated
param
exception The exception that occurred (which possibly wraps a root cause exception

        Context context = request.getContext();
        if (context == null)
            return;
        
        Throwable realError = throwable;
        
        if (realError instanceof ServletException) {
            realError = ((ServletException) realError).getRootCause();
            if (realError == null) {
                realError = throwable;
            }
        } 

        // If this is an aborted request from a client just log it and return
        if (realError instanceof ClientAbortException ) {
            if (log.isDebugEnabled()) {
                log.debug
                    (sm.getString("standardHost.clientAbort",
                                  realError.getCause().getMessage()));
            }
            return;
        }

        ErrorPage errorPage = findErrorPage(context, throwable);
        if ((errorPage == null) && (realError != throwable)) {
            errorPage = findErrorPage(context, realError);
        }

        if (errorPage != null) {
            response.setAppCommitted(false);
            ServletRequest sreq = request.getRequest();
            ServletResponse sresp = response.getResponse();
            sreq.setAttribute
                (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
                 errorPage.getLocation());
            sreq.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
                              Integer.valueOf(ApplicationFilterFactory.ERROR));
            sreq.setAttribute
                (Globals.STATUS_CODE_ATTR,
                 Integer.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
            sreq.setAttribute(Globals.ERROR_MESSAGE_ATTR,
                              throwable.getMessage());
            sreq.setAttribute(Globals.EXCEPTION_ATTR,
                              realError);
            Wrapper wrapper = request.getWrapper();
            if (wrapper != null)
                sreq.setAttribute(Globals.SERVLET_NAME_ATTR,
                                  wrapper.getName());
            /* GlassFish 6386229
            if (sreq instanceof HttpServletRequest)
                sreq.setAttribute(Globals.EXCEPTION_PAGE_ATTR,
                                  ((HttpServletRequest) sreq).getRequestURI());
            */
            // START GlassFish 6386229
            sreq.setAttribute(Globals.EXCEPTION_PAGE_ATTR,
                              ((HttpServletRequest) sreq).getRequestURI());
            // END GlassFish 6386229
            sreq.setAttribute(Globals.EXCEPTION_TYPE_ATTR,
                              realError.getClass());
            if (custom(request, response, errorPage)) {
                try {
                    sresp.flushBuffer();
                } catch (IOException e) {
                    log("Exception Processing " + errorPage, e);
                }
            }
        } else {
            // A custom error-page has not been defined for the exception
            // that was thrown during request processing. Check if an
            // error-page for error code 500 was specified and if so, 
            // send that page back as the response.
            ServletResponse sresp = (ServletResponse) response;

            /* GlassFish 6386229
            if (sresp instanceof HttpServletResponse) {
                ((HttpServletResponse) sresp).setStatus(
                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                // The response is an error
                response.setError();

                status(request, response);
            }
            */
            // START GlassFish 6386229
            ((HttpServletResponse) sresp).setStatus(
                HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            // The response is an error
            response.setError();

            status(request, response);
            // END GlassFish 6386229
        }