Author: markt Date: Mon Oct 1 09:32:23 2012 New Revision: 1392247 URL: http://svn.apache.org/viewvc?rev=1392247&view=rev Log: Implement maxHeaderCount attribute on HTTP Connectors. It is equivalent of LimitRequestFields directive of Apache HTTPD
Modified: tomcat/tc5.5.x/trunk/STATUS.txt tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProtocol.java tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11BaseProtocol.java tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/LocalStrings.properties tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/MimeHeaders.java tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/AprEndpoint.java tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml tomcat/tc5.5.x/trunk/container/webapps/docs/config/http.xml Modified: tomcat/tc5.5.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/STATUS.txt?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/STATUS.txt (original) +++ tomcat/tc5.5.x/trunk/STATUS.txt Mon Oct 1 09:32:23 2012 @@ -28,36 +28,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK/ PATCHES PROPOSED TO BACKPORT: [ New proposals should be added at the end of the list ] -* Implement maxHeaderCount attribute on HTTP Connectors. - It is equivalent of LimitRequestFields directive of Apache HTTPD - See r1356239 in Tomcat 6. - - Notes: - 1. Implemented for HTTP protocol only. (MimeHeaders.setLimit() is called - by HTTP protocol processors only). - - I suppose that users of AJP can leverage the LimitRequestFields directive - in Apache HTTPD server. - - 2. The feature is manageable through JMX on the ProtocolHandler MBean. - - Unlike later Tomcat versions, I did not add setter/getter methods to - Connector class and did not expose the property on Connector MBean. - - Note that Catalina MBeans are not visible in Tomcat 5.5 by default. - See r1356696 for instructions. - - 3. To test the feature one can use - http://localhost:8080/servlets-examples/servlet/RequestHeaderExample - - Refreshing the page in Firefox changes the number of headers in incoming request - (adds 'cache-control' for "F5" refresh, adds 'pragma=no-cache' for "Ctrl+F5" refresh). - - Patch: - http://people.apache.org/~kkolinko/patches/2012-07-03_tc55_maxHeaderCount_v1.patch - +1: kkolinko, markt, kfujino - -1: - * Various DIGEST improvements ported from Tomcat 7 http://people.apache.org/~markt/patches/2012-08-28-digest-tc5.patch +1: markt, kkolinko, kfujino Modified: tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProcessor.java Mon Oct 1 09:32:23 2012 @@ -803,6 +803,8 @@ public class Http11AprProcessor implemen if (!disableUploadTimeout) { Socket.timeoutSet(socket, timeout * 1000); } + // Set this every time in case limit has been changed via JMX + request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount()); inputBuffer.parseHeaders(); } catch (IOException e) { error = true; Modified: tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProtocol.java (original) +++ tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11AprProtocol.java Mon Oct 1 09:32:23 2012 @@ -367,6 +367,15 @@ public class Http11AprProtocol implement setAttribute("maxHttpHeaderSize", "" + valueI); } + public int getMaxHeaderCount() { + return ep.getMaxHeaderCount(); + } + + public void setMaxHeaderCount(int maxHeaderCount) { + ep.setMaxHeaderCount(maxHeaderCount); + setAttribute("maxHeaderCount", "" + maxHeaderCount); + } + public String getRestrictedUserAgents() { return restrictedUserAgents; } Modified: tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11BaseProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11BaseProtocol.java?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11BaseProtocol.java (original) +++ tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11BaseProtocol.java Mon Oct 1 09:32:23 2012 @@ -377,6 +377,15 @@ public class Http11BaseProtocol implemen setAttribute("maxHttpHeaderSize", "" + valueI); } + public int getMaxHeaderCount() { + return ep.getMaxHeaderCount(); + } + + public void setMaxHeaderCount(int maxHeaderCount) { + ep.setMaxHeaderCount(maxHeaderCount); + setAttribute("maxHeaderCount", "" + maxHeaderCount); + } + public String getRestrictedUserAgents() { return restrictedUserAgents; } Modified: tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/tc5.5.x/trunk/connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java Mon Oct 1 09:32:23 2012 @@ -839,6 +839,8 @@ public class Http11Processor implements if (!disableUploadTimeout) { socket.setSoTimeout(timeout); } + // Set this every time in case limit has been changed via JMX + request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount()); inputBuffer.parseHeaders(); } catch (IOException e) { error = true; Modified: tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/LocalStrings.properties?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/LocalStrings.properties (original) +++ tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/LocalStrings.properties Mon Oct 1 09:32:23 2012 @@ -22,3 +22,5 @@ parameters.invalidChunk=Invalid chunk st parameters.maxCountFail=More than the maximum number of request parameters (GET plus POST) for a single request ([{0}]) were detected. Any parameters beyond this limit have been ignored. To change this limit, set the maxParameterCount attribute on the Connector. parameters.multipleDecodingFail=Character decoding failed. A total of [{0}] failures were detected but only the first was logged. Enable debug level logging for this logger to log all failures. parameters.noequal=Parameter starting at position [{0}] and ending at position [{1}] with a value of [{0}] was not followed by an '=' character + +headers.maxCountFail=More than the maximum allowed number of headers ([{0}]) were detected. Modified: tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/MimeHeaders.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/MimeHeaders.java?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/MimeHeaders.java (original) +++ tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/http/MimeHeaders.java Mon Oct 1 09:32:23 2012 @@ -22,6 +22,7 @@ import java.io.StringWriter; import java.util.Enumeration; import org.apache.tomcat.util.buf.MessageBytes; +import org.apache.tomcat.util.res.StringManager; /* XXX XXX XXX Need a major rewrite !!!! */ @@ -96,7 +97,10 @@ public class MimeHeaders { * XXX make it configurable ( fine-tuning of web-apps ) */ public static final int DEFAULT_HEADER_SIZE=8; - + + private static final StringManager sm = + StringManager.getManager("org.apache.tomcat.util.http"); + /** * The header fields. */ @@ -109,12 +113,30 @@ public class MimeHeaders { private int count; /** + * The limit on the number of header fields. + */ + private int limit = -1; + + /** * Creates a new MimeHeaders object using a default buffer size. */ public MimeHeaders() { } /** + * Set limit on the number of header fields. + */ + public void setLimit(int limit) { + this.limit = limit; + if (limit > 0 && headers.length > limit && count < limit) { + // shrink header list array + MimeHeaderField tmp[] = new MimeHeaderField[limit]; + System.arraycopy(headers, 0, tmp, 0, count); + headers = tmp; + } + } + + /** * Clears all header fields. */ // [seguin] added for consistency -- most other objects have recycle(). @@ -213,11 +235,19 @@ public class MimeHeaders { * field has not had its name or value initialized. */ private MimeHeaderField createHeader() { + if (limit > -1 && count >= limit) { + throw new IllegalStateException(sm.getString( + "headers.maxCountFail", new Integer(limit))); + } MimeHeaderField mh; int len = headers.length; if (count >= len) { // expand header list array - MimeHeaderField tmp[] = new MimeHeaderField[count * 2]; + int newLength = count * 2; + if (limit > 0 && newLength > limit) { + newLength = limit; + } + MimeHeaderField tmp[] = new MimeHeaderField[newLength]; System.arraycopy(headers, 0, tmp, 0, len); headers = tmp; } Modified: tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/AprEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/AprEndpoint.java (original) +++ tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/AprEndpoint.java Mon Oct 1 09:32:23 2012 @@ -455,6 +455,18 @@ public class AprEndpoint { public void setSSLVerifyDepth(int SSLVerifyDepth) { this.SSLVerifyDepth = SSLVerifyDepth; } + /** + * The maximum number of headers in a request that are allowed. + * 100 by default. A value of less than 0 means no limit. + */ + private int maxHeaderCount = 100; // as in Apache HTTPD server + public int getMaxHeaderCount() { + return maxHeaderCount; + } + public void setMaxHeaderCount(int maxHeaderCount) { + this.maxHeaderCount = maxHeaderCount; + } + // --------------------------------------------------------- Public Methods Modified: tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java (original) +++ tomcat/tc5.5.x/trunk/connectors/util/java/org/apache/tomcat/util/net/PoolTcpEndpoint.java Mon Oct 1 09:32:23 2012 @@ -89,7 +89,12 @@ public class PoolTcpEndpoint implements protected int socketTimeout=-1; private boolean lf = true; - + /** + * The maximum number of headers in a request that are allowed. + * 100 by default. A value of less than 0 means no limit. + */ + private int maxHeaderCount = 100; // as in Apache HTTPD server + // ------ Leader follower fields @@ -273,6 +278,14 @@ public class PoolTcpEndpoint implements } } + public int getMaxHeaderCount() { + return maxHeaderCount; + } + + public void setMaxHeaderCount(int maxHeaderCount) { + this.maxHeaderCount = maxHeaderCount; + } + public int getCurrentThreadCount() { return curThreads; } Modified: tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml (original) +++ tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml Mon Oct 1 09:32:23 2012 @@ -76,6 +76,9 @@ Ensure that the chunked input filter is correctly recycled between requests. (kkolinko/jim) </fix> + <add> + Implement the maxHeaderCount for the HTTP connectors. (kkolinko) + </add> </changelog> </subsection> <subsection name="Webapps"> Modified: tomcat/tc5.5.x/trunk/container/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/webapps/docs/config/http.xml?rev=1392247&r1=1392246&r2=1392247&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/webapps/docs/config/http.xml (original) +++ tomcat/tc5.5.x/trunk/container/webapps/docs/config/http.xml Mon Oct 1 09:32:23 2012 @@ -277,6 +277,13 @@ this attribute is set to "true".</p> </attribute> + <attribute name="maxHeaderCount" required="false"> + <p>The maximum number of headers in a request that are allowed by the + container. A request that contains more headers than the specified limit + will be rejected. A value of less than 0 means no limit. + If not specified, a default of 100 is used.</p> + </attribute> + <attribute name="maxHttpHeaderSize" required="false"> <p>The maximum size of the request and response HTTP header, specified in bytes. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org