You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/09/18 13:43:00 UTC

svn commit: r1808707 - in /tomcat/tc8.0.x/trunk: java/org/apache/coyote/http11/ test/org/apache/coyote/http11/ webapps/docs/ webapps/docs/config/

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org