luehe 2004/10/27 15:58:17 Modified: catalina/src/share/org/apache/catalina/core StandardWrapper.java catalina/src/share/org/apache/catalina Wrapper.java catalina/src/share/org/apache/catalina/connector CoyoteAdapter.java Log: If TRACE has been disabled, return appropriate error code (405, instead of the current 403) and include Allow header in response, in order to comply with HTTP 1.1 spec: 10.4.6 405 Method Not Allowed The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource. Revision Changes Path 1.54 +69 -2 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardWrapper.java Index: StandardWrapper.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v retrieving revision 1.53 retrieving revision 1.54 diff -u -r1.53 -r1.54 --- StandardWrapper.java 26 Oct 2004 21:55:43 -0000 1.53 +++ StandardWrapper.java 27 Oct 2004 22:58:17 -0000 1.54 @@ -17,11 +17,12 @@ package org.apache.catalina.core; - +import java.lang.reflect.Method; import java.io.PrintStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Stack; import java.security.AccessController; import java.security.PrivilegedActionException; @@ -551,6 +552,44 @@ } + /** + * Gets the names of the methods supported by the underlying servlet. + * + * This is the same set of methods included in the Allow response header + * in response to an OPTIONS request method processed by the underlying + * servlet. + * + * @return Array of names of the methods supported by the underlying + * servlet + */ + public String[] getServletMethods() throws ServletException { + + HashSet allow = new HashSet(); + allow.add("TRACE"); + allow.add("OPTIONS"); + + Method[] methods = getAllDeclaredMethods(loadServlet().getClass()); + for (int i=0; methods != null && i<methods.length; i++) { + Method m = methods[i]; + + if (m.getName().equals("doGet")) { + allow.add("GET"); + allow.add("HEAD"); + } else if (m.getName().equals("doPost")) { + allow.add("POST"); + } else if (m.getName().equals("doPut")) { + allow.add("PUT"); + } else if (m.getName().equals("doDelete")) { + allow.add("DELETE"); + } + } + + String[] methodNames = new String[allow.size()]; + return (String[]) allow.toArray(methodNames); + + } + + // --------------------------------------------------------- Public Methods @@ -1488,6 +1527,34 @@ sb.append(']'); return (sb.toString()); + } + + + private Method[] getAllDeclaredMethods(Class c) { + + if (c.equals(javax.servlet.http.HttpServlet.class)) { + return null; + } + + Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass()); + + Method[] thisMethods = c.getDeclaredMethods(); + if (thisMethods == null) { + return parentMethods; + } + + if ((parentMethods != null) && (parentMethods.length > 0)) { + Method[] allMethods = + new Method[parentMethods.length + thisMethods.length]; + System.arraycopy(parentMethods, 0, allMethods, 0, + parentMethods.length); + System.arraycopy(thisMethods, 0, allMethods, parentMethods.length, + thisMethods.length); + + thisMethods = allMethods; + } + + return thisMethods; } 1.6 +14 -1 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/Wrapper.java Index: Wrapper.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/Wrapper.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Wrapper.java 26 May 2004 15:28:42 -0000 1.5 +++ Wrapper.java 27 Oct 2004 22:58:17 -0000 1.6 @@ -132,6 +132,19 @@ /** + * Gets the names of the methods supported by the underlying servlet. + * + * This is the same set of methods included in the Allow response header + * in response to an OPTIONS request method processed by the underlying + * servlet. + * + * @return Array of names of the methods supported by the underlying + * servlet + */ + public String[] getServletMethods() throws ServletException; + + + /** * Is this servlet currently unavailable? */ public boolean isUnavailable(); 1.8 +32 -13 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/CoyoteAdapter.java Index: CoyoteAdapter.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/connector/CoyoteAdapter.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- CoyoteAdapter.java 19 Oct 2004 15:28:13 -0000 1.7 +++ CoyoteAdapter.java 27 Oct 2004 22:58:17 -0000 1.8 @@ -171,10 +171,11 @@ * Parse additional request parameters. */ protected boolean postParseRequest(org.apache.coyote.Request req, - Request request, - org.apache.coyote.Response res, - Response response) - throws Exception { + Request request, + org.apache.coyote.Response res, + Response response) + throws Exception { + // XXX the processor needs to set a correct scheme and port prior to this point, // in ajp13 protocols dont make sense to get the port from the connector.. // XXX the processor may have set a correct scheme and port prior to this point, @@ -190,14 +191,6 @@ request.setSecure(connector.getSecure()); } - // Filter trace method - if (!connector.getAllowTrace() - && req.method().equalsIgnoreCase("TRACE")) { - res.setStatus(403); - res.setMessage("TRACE method is not allowed"); - return false; - } - // FIXME: the code below doesnt belongs to here, // this is only have sense // in Http11, not in ajp13.. @@ -270,6 +263,32 @@ request.getMappingData()); request.setContext((Context) request.getMappingData().context); request.setWrapper((Wrapper) request.getMappingData().wrapper); + + // Filter trace method + if (!connector.getAllowTrace() + && req.method().equalsIgnoreCase("TRACE")) { + Wrapper wrapper = request.getWrapper(); + String header = null; + if (wrapper != null) { + String[] methods = wrapper.getServletMethods(); + if (methods != null) { + for (int i=0; i<methods.length; i++) { + if ("TRACE".equals(methods[i])) { + continue; + } + if (header == null) { + header = methods[i]; + } else { + header += ", " + methods[i]; + } + } + } + } + res.setStatus(405); + res.addHeader("Allow", header); + res.setMessage("TRACE method is not allowed"); + return false; + } // Possible redirect MessageBytes redirectPathMB = request.getMappingData().redirectPath;
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]