Author: markt Date: Mon Sep 18 13:42:59 2017 New Revision: 1808707 URL: http://svn.apache.org/viewvc?rev=1808707&view=rev Log: Add an option to control how to respond to requests with invalid HTTP header names
Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractNioInputBuffer.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Processor.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalInputBuffer.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java tomcat/tc8.0.x/trunk/test/org/apache/coyote/http11/TestInternalInputBuffer.java tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml tomcat/tc8.0.x/trunk/webapps/docs/config/http.xml Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Mon Sep 18 13:42:59 2017 @@ -37,6 +37,30 @@ public abstract class AbstractHttp11Prot // ------------------------------------------------ HTTP specific properties // ------------------------------------------ managed in the ProtocolHandler + private boolean rejectIllegalHeaderName = false; + /** + * If an HTTP request is received that contains an illegal header name (i.e. + * the header name is not a token) will the request be rejected (with a 400 + * response) or will the illegal header be ignored. + * + * @return {@code true} if the request will be rejected or {@code false} if + * the header will be ignored + */ + public boolean getRejectIllegalHeaderName() { return rejectIllegalHeaderName; } + /** + * If an HTTP request is received that contains an illegal header name (i.e. + * the header name is not a token) should the request be rejected (with a + * 400 response) or should the illegal header be ignored. + * + * @param rejectIllegalHeaderName {@code true} to reject requests with + * illegal header names, {@code false} to + * ignore the header + */ + public void setRejectIllegalHeaderName(boolean rejectIllegalHeaderName) { + this.rejectIllegalHeaderName = rejectIllegalHeaderName; + } + + private int socketBuffer = 9000; public int getSocketBuffer() { return socketBuffer; } public void setSocketBuffer(int socketBuffer) { Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java Mon Sep 18 13:42:59 2017 @@ -35,7 +35,6 @@ public abstract class AbstractInputBuffe */ protected static final StringManager sm = StringManager.getManager(Constants.Package); - /** * Associated Coyote request. */ @@ -110,6 +109,9 @@ public abstract class AbstractInputBuffe protected int lastActiveFilter; + protected boolean rejectIllegalHeaderName; + + // ------------------------------------------------------------- Properties /** Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractNioInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractNioInputBuffer.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractNioInputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractNioInputBuffer.java Mon Sep 18 13:42:59 2017 @@ -76,12 +76,14 @@ public abstract class AbstractNioInputBu /** * Alternate constructor. */ - public AbstractNioInputBuffer(Request request, int headerBufferSize) { + public AbstractNioInputBuffer(Request request, int headerBufferSize, + boolean rejectIllegalHeaderName) { this.request = request; headers = request.getMimeHeaders(); this.headerBufferSize = headerBufferSize; + this.rejectIllegalHeaderName = rejectIllegalHeaderName; filterLibrary = new InputFilter[0]; activeFilters = new InputFilter[0]; @@ -475,9 +477,10 @@ public abstract class AbstractNioInputBu headerData.lastSignificantChar = pos; break; } else if (!HttpParser.isToken(chr)) { - // If a non-token header is detected, skip the line and - // ignore the header + // Non-token characters are illegal in header names + // Parsing continues so the error can be reported in context headerData.lastSignificantChar = pos; + // skipLine() will handle the error return skipLine(); } @@ -616,11 +619,14 @@ public abstract class AbstractNioInputBu pos++; } - if (getLog().isDebugEnabled()) { - getLog().debug(sm.getString("iib.invalidheader", new String(buf, - headerData.start, + if (rejectIllegalHeaderName || getLog().isDebugEnabled()) { + String message = sm.getString("iib.invalidheader", new String(buf, headerData.start, headerData.lastSignificantChar - headerData.start + 1, - StandardCharsets.ISO_8859_1))); + StandardCharsets.ISO_8859_1)); + if (rejectIllegalHeaderName) { + throw new IllegalArgumentException(message); + } + getLog().debug(message); } headerParsePos = HeaderParsePosition.HEADER_START; Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Mon Sep 18 13:42:59 2017 @@ -60,12 +60,13 @@ public class Http11AprProcessor extends // ----------------------------------------------------------- Constructors - public Http11AprProcessor(int headerBufferSize, AprEndpoint endpoint, int maxTrailerSize, - Set<String> allowedTrailerHeaders, int maxExtensionSize, int maxSwallowSize) { + public Http11AprProcessor(int headerBufferSize, boolean rejectIllegalHeaderName, + AprEndpoint endpoint, int maxTrailerSize, Set<String> allowedTrailerHeaders, + int maxExtensionSize, int maxSwallowSize) { super(endpoint); - inputBuffer = new InternalAprInputBuffer(request, headerBufferSize); + inputBuffer = new InternalAprInputBuffer(request, headerBufferSize, rejectIllegalHeaderName); request.setInputBuffer(inputBuffer); outputBuffer = new InternalAprOutputBuffer(response, headerBufferSize); Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Mon Sep 18 13:42:59 2017 @@ -290,9 +290,10 @@ public class Http11AprProtocol extends A @Override protected Http11AprProcessor createProcessor() { Http11AprProcessor processor = new Http11AprProcessor( - proto.getMaxHttpHeaderSize(), (AprEndpoint)proto.endpoint, - proto.getMaxTrailerSize(), proto.getAllowedTrailerHeadersAsSet(), - proto.getMaxExtensionSize(), proto.getMaxSwallowSize()); + proto.getMaxHttpHeaderSize(), proto.getRejectIllegalHeaderName(), + (AprEndpoint)proto.endpoint, proto.getMaxTrailerSize(), + proto.getAllowedTrailerHeadersAsSet(), proto.getMaxExtensionSize(), + proto.getMaxSwallowSize()); proto.configureProcessor(processor); // APR specific configuration processor.setClientCertProvider(proto.getClientCertProvider()); Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java Mon Sep 18 13:42:59 2017 @@ -62,12 +62,14 @@ public class Http11Nio2Processor extends // ----------------------------------------------------------- Constructors - public Http11Nio2Processor(int maxHttpHeaderSize, Nio2Endpoint endpoint, int maxTrailerSize, - Set<String> allowedTrailerHeaders, int maxExtensionSize, int maxSwallowSize) { + public Http11Nio2Processor(int maxHttpHeaderSize, boolean rejectIllegalHeaderName, + Nio2Endpoint endpoint, int maxTrailerSize, Set<String> allowedTrailerHeaders, + int maxExtensionSize, int maxSwallowSize) { super(endpoint); - inputBuffer = new InternalNio2InputBuffer(request, maxHttpHeaderSize); + inputBuffer = new InternalNio2InputBuffer(request, maxHttpHeaderSize, + rejectIllegalHeaderName); request.setInputBuffer(inputBuffer); outputBuffer = new InternalNio2OutputBuffer(response, maxHttpHeaderSize); Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Nio2Protocol.java Mon Sep 18 13:42:59 2017 @@ -229,9 +229,10 @@ public class Http11Nio2Protocol extends @Override public Http11Nio2Processor createProcessor() { Http11Nio2Processor processor = new Http11Nio2Processor( - proto.getMaxHttpHeaderSize(), (Nio2Endpoint) proto.endpoint, - proto.getMaxTrailerSize(), proto.getAllowedTrailerHeadersAsSet(), - proto.getMaxExtensionSize(), proto.getMaxSwallowSize()); + proto.getMaxHttpHeaderSize(), proto.getRejectIllegalHeaderName(), + (Nio2Endpoint) proto.endpoint, proto.getMaxTrailerSize(), + proto.getAllowedTrailerHeadersAsSet(), proto.getMaxExtensionSize(), + proto.getMaxSwallowSize()); proto.configureProcessor(processor); register(processor); return processor; Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Mon Sep 18 13:42:59 2017 @@ -64,12 +64,14 @@ public class Http11NioProcessor extends // ----------------------------------------------------------- Constructors - public Http11NioProcessor(int maxHttpHeaderSize, NioEndpoint endpoint, int maxTrailerSize, - Set<String> allowedTrailerHeaders, int maxExtensionSize, int maxSwallowSize) { + public Http11NioProcessor(int maxHttpHeaderSize, boolean rejectIllegalHeaderName, + NioEndpoint endpoint, int maxTrailerSize, Set<String> allowedTrailerHeaders, + int maxExtensionSize, int maxSwallowSize) { super(endpoint); - inputBuffer = new InternalNioInputBuffer(request, maxHttpHeaderSize); + inputBuffer = new InternalNioInputBuffer(request, maxHttpHeaderSize, + rejectIllegalHeaderName); request.setInputBuffer(inputBuffer); outputBuffer = new InternalNioOutputBuffer(response, maxHttpHeaderSize); Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Mon Sep 18 13:42:59 2017 @@ -264,9 +264,10 @@ public class Http11NioProtocol extends A @Override public Http11NioProcessor createProcessor() { Http11NioProcessor processor = new Http11NioProcessor( - proto.getMaxHttpHeaderSize(), (NioEndpoint)proto.endpoint, - proto.getMaxTrailerSize(), proto.getAllowedTrailerHeadersAsSet(), - proto.getMaxExtensionSize(), proto.getMaxSwallowSize()); + proto.getMaxHttpHeaderSize(), proto.getRejectIllegalHeaderName(), + (NioEndpoint)proto.endpoint, proto.getMaxTrailerSize(), + proto.getAllowedTrailerHeadersAsSet(), proto.getMaxExtensionSize(), + proto.getMaxSwallowSize()); proto.configureProcessor(processor); register(processor); return processor; Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Processor.java Mon Sep 18 13:42:59 2017 @@ -49,12 +49,13 @@ public class Http11Processor extends Abs // ------------------------------------------------------------ Constructor - public Http11Processor(int headerBufferSize, JIoEndpoint endpoint, int maxTrailerSize, - Set<String> allowedTrailerHeaders, int maxExtensionSize, int maxSwallowSize) { + public Http11Processor(int headerBufferSize, boolean rejectIllegalHeaderName, + JIoEndpoint endpoint, int maxTrailerSize, Set<String> allowedTrailerHeaders, + int maxExtensionSize, int maxSwallowSize) { super(endpoint); - inputBuffer = new InternalInputBuffer(request, headerBufferSize); + inputBuffer = new InternalInputBuffer(request, headerBufferSize, rejectIllegalHeaderName); request.setInputBuffer(inputBuffer); outputBuffer = new InternalOutputBuffer(response, headerBufferSize); Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/Http11Protocol.java Mon Sep 18 13:42:59 2017 @@ -165,9 +165,10 @@ public class Http11Protocol extends Abst @Override protected Http11Processor createProcessor() { Http11Processor processor = new Http11Processor( - proto.getMaxHttpHeaderSize(), (JIoEndpoint)proto.endpoint, - proto.getMaxTrailerSize(), proto.getAllowedTrailerHeadersAsSet(), - proto.getMaxExtensionSize(), proto.getMaxSwallowSize()); + proto.getMaxHttpHeaderSize(), proto.getRejectIllegalHeaderName(), + (JIoEndpoint)proto.endpoint, proto.getMaxTrailerSize(), + proto.getAllowedTrailerHeadersAsSet(), proto.getMaxExtensionSize(), + proto.getMaxSwallowSize()); proto.configureProcessor(processor); // BIO specific configuration processor.setDisableKeepAlivePercentage(proto.getDisableKeepAlivePercentage()); Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java Mon Sep 18 13:42:59 2017 @@ -53,7 +53,8 @@ public class InternalAprInputBuffer exte /** * Alternate constructor. */ - public InternalAprInputBuffer(Request request, int headerBufferSize) { + public InternalAprInputBuffer(Request request, int headerBufferSize, + boolean rejectIllegalHeaderName) { this.request = request; headers = request.getMimeHeaders(); @@ -65,6 +66,8 @@ public class InternalAprInputBuffer exte bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500); } + this.rejectIllegalHeaderName = rejectIllegalHeaderName; + inputStreamInputBuffer = new SocketInputBuffer(); filterLibrary = new InputFilter[0]; @@ -390,8 +393,9 @@ public class InternalAprInputBuffer exte colon = true; headerValue = headers.addValue(buf, start, pos - start); } else if (!HttpParser.isToken(buf[pos])) { - // If a non-token header is detected, skip the line and - // ignore the header + // Non-token characters are illegal in header names + // Parsing continues so the error can be reported in context + // skipLine() will handle the error skipLine(start); return true; } @@ -521,9 +525,13 @@ public class InternalAprInputBuffer exte pos++; } - if (log.isDebugEnabled()) { - log.debug(sm.getString("iib.invalidheader", new String(buf, start, - lastRealByte - start + 1, StandardCharsets.ISO_8859_1))); + if (rejectIllegalHeaderName || log.isDebugEnabled()) { + String message = sm.getString("iib.invalidheader", new String(buf, start, + lastRealByte - start + 1, StandardCharsets.ISO_8859_1)); + if (rejectIllegalHeaderName) { + throw new IllegalArgumentException(message); + } + log.debug(message); } } Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalInputBuffer.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalInputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalInputBuffer.java Mon Sep 18 13:42:59 2017 @@ -52,13 +52,16 @@ public class InternalInputBuffer extends /** * Default constructor. */ - public InternalInputBuffer(Request request, int headerBufferSize) { + public InternalInputBuffer(Request request, int headerBufferSize, + boolean rejectIllegalHeaderName) { this.request = request; headers = request.getMimeHeaders(); buf = new byte[headerBufferSize]; + this.rejectIllegalHeaderName = rejectIllegalHeaderName; + inputStreamInputBuffer = new InputStreamInputBuffer(); filterLibrary = new InputFilter[0]; @@ -349,8 +352,9 @@ public class InternalInputBuffer extends colon = true; headerValue = headers.addValue(buf, start, pos - start); } else if (!HttpParser.isToken(buf[pos])) { - // If a non-token header is detected, skip the line and - // ignore the header + // Non-token characters are illegal in header names + // Parsing continues so the error can be reported in context + // skipLine() will handle the error skipLine(start); return true; } @@ -499,9 +503,13 @@ public class InternalInputBuffer extends pos++; } - if (log.isDebugEnabled()) { - log.debug(sm.getString("iib.invalidheader", new String(buf, start, - lastRealByte - start + 1, StandardCharsets.ISO_8859_1))); + if (rejectIllegalHeaderName || log.isDebugEnabled()) { + String message = sm.getString("iib.invalidheader", new String(buf, start, + lastRealByte - start + 1, StandardCharsets.ISO_8859_1)); + if (rejectIllegalHeaderName) { + throw new IllegalArgumentException(message); + } + log.debug(message); } } Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNio2InputBuffer.java Mon Sep 18 13:42:59 2017 @@ -50,8 +50,9 @@ public class InternalNio2InputBuffer ext // ----------------------------------------------------------- Constructors - public InternalNio2InputBuffer(Request request, int headerBufferSize) { - super(request, headerBufferSize); + public InternalNio2InputBuffer(Request request, int headerBufferSize, + boolean rejectIllegalHeaderName) { + super(request, headerBufferSize, rejectIllegalHeaderName); inputStreamInputBuffer = new SocketInputBuffer(); } Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Mon Sep 18 13:42:59 2017 @@ -47,8 +47,9 @@ public class InternalNioInputBuffer exte /** * Alternate constructor. */ - public InternalNioInputBuffer(Request request, int headerBufferSize) { - super(request, headerBufferSize); + public InternalNioInputBuffer(Request request, int headerBufferSize, + boolean rejectIllegalHeaderName) { + super(request, headerBufferSize, rejectIllegalHeaderName); inputStreamInputBuffer = new SocketInputBuffer(); } Modified: tomcat/tc8.0.x/trunk/test/org/apache/coyote/http11/TestInternalInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/test/org/apache/coyote/http11/TestInternalInputBuffer.java?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/test/org/apache/coyote/http11/TestInternalInputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/test/org/apache/coyote/http11/TestInternalInputBuffer.java Mon Sep 18 13:42:59 2017 @@ -33,6 +33,7 @@ import static org.junit.Assert.assertTru import org.junit.Test; import org.apache.catalina.Context; +import org.apache.catalina.connector.Connector; import org.apache.catalina.startup.SimpleHttpClient; import org.apache.catalina.startup.TesterServlet; import org.apache.catalina.startup.Tomcat; @@ -130,6 +131,28 @@ public class TestInternalInputBuffer ext @Test + public void testBug51557Valid() { + + Bug51557Client client = new Bug51557Client("X-Bug51557Valid", "1234"); + + client.doRequest(); + assertTrue(client.isResponse200()); + assertEquals("1234abcd", client.getResponseBody()); + assertTrue(client.isResponseBodyOK()); + } + + + @Test + public void testBug51557Invalid() { + + Bug51557Client client = new Bug51557Client("X-Bug51557=Invalid", "1234", true); + + client.doRequest(); + assertTrue(client.isResponse400()); + } + + + @Test public void testBug51557NoColon() { Bug51557Client client = new Bug51557Client("X-Bug51557NoColon"); @@ -220,17 +243,25 @@ public class TestInternalInputBuffer ext */ private class Bug51557Client extends SimpleHttpClient { - private String headerName; - private String headerLine; + private final String headerName; + private final String headerLine; + private final boolean rejectIllegalHeaderName; public Bug51557Client(String headerName) { this.headerName = headerName; this.headerLine = headerName; + this.rejectIllegalHeaderName = false; } public Bug51557Client(String headerName, String headerValue) { + this(headerName, headerValue, false); + } + + public Bug51557Client(String headerName, String headerValue, + boolean rejectIllegalHeaderName) { this.headerName = headerName; this.headerLine = headerName + ": " + headerValue; + this.rejectIllegalHeaderName = rejectIllegalHeaderName; } private Exception doRequest() { @@ -243,8 +274,11 @@ public class TestInternalInputBuffer ext root.addServletMappingDecoded("/test", "Bug51557"); try { + Connector connector = tomcat.getConnector(); + connector.setProperty("rejectIllegalHeaderName", + Boolean.toString(rejectIllegalHeaderName)); tomcat.start(); - setPort(tomcat.getConnector().getLocalPort()); + setPort(connector.getLocalPort()); // Open connection connect(); Modified: tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc8.0.x/trunk/webapps/docs/changelog.xml Mon Sep 18 13:42:59 2017 @@ -121,6 +121,10 @@ Poller if a connection is closed at the same time as new data arrives on that connection. (markt) </fix> + <add> + Add an option to reject requests that contain HTTP headers with invalid + (non-token) header names with a 400 response. (markt) + </add> </changelog> </subsection> <subsection name="WebSocket"> Modified: tomcat/tc8.0.x/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/webapps/docs/config/http.xml?rev=1808707&r1=1808706&r2=1808707&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/webapps/docs/config/http.xml (original) +++ tomcat/tc8.0.x/trunk/webapps/docs/config/http.xml Mon Sep 18 13:42:59 2017 @@ -521,6 +521,15 @@ expected concurrent requests (synchronous and asynchronous).</p> </attribute> + <attribute name="rejectIllegalHeaderName" required="false"> + <p>If an HTTP request is received that contains an illegal header name + (i.e. the header name is not a token) this setting determines if the + request will be rejected with a 400 response (<code>true</code>) or if the + illegal header be ignored (<code>false</code>). The default value is + <code>false</code> which will cause the request to be processed but the + illegal header will be ignored.</p> + </attribute> + <attribute name="restrictedUserAgents" required="false"> <p>The value is a regular expression (using <code>java.util.regex</code>) matching the <code>user-agent</code> header of HTTP clients for which --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org