| /* |
| * Copyright 1999-2001,2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| package org.apache.catalina.core; |
| |
| |
| import java.io.IOException; |
| |
| import javax.servlet.ServletException; |
| import javax.servlet.ServletRequest; |
| import javax.servlet.ServletRequestEvent; |
| import javax.servlet.ServletRequestListener; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import org.apache.catalina.Container; |
| import org.apache.catalina.Globals; |
| import org.apache.catalina.Wrapper; |
| import org.apache.catalina.connector.Request; |
| import org.apache.catalina.connector.Response; |
| import org.apache.catalina.util.StringManager; |
| import org.apache.catalina.valves.ValveBase; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.tomcat.util.buf.MessageBytes; |
| |
| /** |
| * Valve that implements the default basic behavior for the |
| * <code>StandardContext</code> container implementation. |
| * <p> |
| * <b>USAGE CONSTRAINT</b>: This implementation is likely to be useful only |
| * when processing HTTP requests. |
| * |
| * @author Craig R. McClanahan |
| * @version $Revision$ $Date$ |
| */ |
| |
| final class StandardContextValve |
| extends ValveBase { |
| |
| |
| // ----------------------------------------------------- Instance Variables |
| |
| |
| /** |
| * The descriptive information related to this implementation. |
| */ |
| private static final String info = |
| "org.apache.catalina.core.StandardContextValve/1.0"; |
| |
| |
| /** |
| * The string manager for this package. |
| */ |
| private static final StringManager sm = |
| StringManager.getManager(Constants.Package); |
| |
| |
| private static Log log = LogFactory.getLog(StandardContextValve.class); |
| |
| |
| private StandardContext context = null; |
| |
| |
| // ------------------------------------------------------------- Properties |
| |
| |
| /** |
| * Return descriptive information about this Valve implementation. |
| */ |
| public String getInfo() { |
| |
| return (info); |
| |
| } |
| |
| |
| // --------------------------------------------------------- Public Methods |
| |
| |
| /** |
| * Cast to a StandardContext right away, as it will be needed later. |
| * |
| * @see org.apache.catalina.Contained#setContainer(org.apache.catalina.Container) |
| */ |
| public void setContainer(Container container) { |
| super.setContainer(container); |
| context = (StandardContext) container; |
| } |
| |
| |
| /** |
| * Select the appropriate child Wrapper to process this request, |
| * based on the specified request URI. If no matching Wrapper can |
| * be found, return an appropriate HTTP error. |
| * |
| * @param request Request to be processed |
| * @param response Response to be produced |
| * @param valveContext Valve context used to forward to the next Valve |
| * |
| * @exception IOException if an input/output error occurred |
| * @exception ServletException if a servlet error occurred |
| */ |
| public final void invoke(Request request, Response response) |
| throws IOException, ServletException { |
| |
| // Disallow any direct access to resources under WEB-INF or META-INF |
| MessageBytes requestPathMB = request.getRequestPathMB(); |
| if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0)) |
| || (requestPathMB.equalsIgnoreCase("/META-INF")) |
| || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0)) |
| || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) { |
| String requestURI = request.getDecodedRequestURI(); |
| notFound(requestURI, response); |
| return; |
| } |
| |
| // Wait if we are reloading |
| while (context.getPaused()) { |
| try { |
| Thread.sleep(1000); |
| } catch (InterruptedException e) { |
| ; |
| } |
| } |
| |
| // Select the Wrapper to be used for this Request |
| Wrapper wrapper = request.getWrapper(); |
| if (wrapper == null) { |
| String requestURI = request.getDecodedRequestURI(); |
| notFound(requestURI, response); |
| return; |
| } |
| |
| // Normal request processing |
| Object instances[] = context.getApplicationEventListeners(); |
| |
| ServletRequestEvent event = null; |
| |
| if ((instances != null) |
| && (instances.length > 0)) { |
| event = new ServletRequestEvent |
| (((StandardContext) container).getServletContext(), |
| request.getRequest()); |
| // create pre-service event |
| for (int i = 0; i < instances.length; i++) { |
| if (instances[i] == null) |
| continue; |
| if (!(instances[i] instanceof ServletRequestListener)) |
| continue; |
| ServletRequestListener listener = |
| (ServletRequestListener) instances[i]; |
| try { |
| listener.requestInitialized(event); |
| } catch (Throwable t) { |
| container.getLogger().error(sm.getString("requestListenerValve.requestInit", |
| instances[i].getClass().getName()), t); |
| ServletRequest sreq = request.getRequest(); |
| sreq.setAttribute(Globals.EXCEPTION_ATTR,t); |
| return; |
| } |
| } |
| } |
| |
| wrapper.getPipeline().getFirst().invoke(request, response); |
| |
| if ((instances !=null ) && |
| (instances.length > 0)) { |
| // create post-service event |
| for (int i = 0; i < instances.length; i++) { |
| if (instances[i] == null) |
| continue; |
| if (!(instances[i] instanceof ServletRequestListener)) |
| continue; |
| ServletRequestListener listener = |
| (ServletRequestListener) instances[i]; |
| try { |
| listener.requestDestroyed(event); |
| } catch (Throwable t) { |
| container.getLogger().error(sm.getString("requestListenerValve.requestDestroy", |
| instances[i].getClass().getName()), t); |
| ServletRequest sreq = request.getRequest(); |
| sreq.setAttribute(Globals.EXCEPTION_ATTR,t); |
| } |
| } |
| } |
| |
| } |
| |
| |
| // -------------------------------------------------------- Private Methods |
| |
| |
| /** |
| * Report a "bad request" error for the specified resource. FIXME: We |
| * should really be using the error reporting settings for this web |
| * application, but currently that code runs at the wrapper level rather |
| * than the context level. |
| * |
| * @param requestURI The request URI for the requested resource |
| * @param response The response we are creating |
| */ |
| private void badRequest(String requestURI, HttpServletResponse response) { |
| |
| try { |
| response.sendError(HttpServletResponse.SC_BAD_REQUEST, requestURI); |
| } catch (IllegalStateException e) { |
| ; |
| } catch (IOException e) { |
| ; |
| } |
| |
| } |
| |
| |
| /** |
| * Report a "forbidden" error for the specified resource. |
| * |
| * @param requestURI The request URI for the requested resource |
| * @param response The response we are creating |
| */ |
| private void forbidden(String requestURI, HttpServletResponse response) { |
| |
| try { |
| response.sendError(HttpServletResponse.SC_FORBIDDEN, requestURI); |
| } catch (IllegalStateException e) { |
| ; |
| } catch (IOException e) { |
| ; |
| } |
| |
| } |
| |
| |
| /** |
| * Report a "not found" error for the specified resource. FIXME: We |
| * should really be using the error reporting settings for this web |
| * application, but currently that code runs at the wrapper level rather |
| * than the context level. |
| * |
| * @param requestURI The request URI for the requested resource |
| * @param response The response we are creating |
| */ |
| private void notFound(String requestURI, HttpServletResponse response) { |
| |
| try { |
| response.sendError(HttpServletResponse.SC_NOT_FOUND, requestURI); |
| } catch (IllegalStateException e) { |
| ; |
| } catch (IOException e) { |
| ; |
| } |
| |
| } |
| |
| |
| } |