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 2019/11/15 22:34:14 UTC

[tomcat] branch 8.5.x updated: Implement feedback on BZ 63835

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
     new b1674e5  Implement feedback on BZ 63835
b1674e5 is described below

commit b1674e5f64a807b9f30e821d021c4d38ef8f7afc
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Nov 15 22:31:58 2019 +0000

    Implement feedback on BZ 63835
    
    Rename constant for header name and token to reduce confusion.
    
    Add useKeepAliveResponseHeader option to the HTTP protocol
    implementations (defaults to true).
    
    Append keep-alive token to an existing Connection header if there is one
---
 .../coyote/http11/AbstractHttp11Protocol.java      |  9 ++++++
 java/org/apache/coyote/http11/Constants.java       |  7 ++++-
 java/org/apache/coyote/http11/Http11Processor.java | 32 ++++++++++++++--------
 webapps/docs/config/http.xml                       |  8 ++++++
 4 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
index c64e555..26aea33 100644
--- a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
+++ b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
@@ -91,6 +91,15 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> {
     // ------------------------------------------------ HTTP specific properties
     // ------------------------------------------ managed in the ProtocolHandler
 
+    private boolean useKeepAliveResponseHeader = true;
+    public boolean getUseKeepAliveResponseHeader() {
+        return useKeepAliveResponseHeader;
+    }
+    public void setUseKeepAliveResponseHeader(boolean useKeepAliveResponseHeader) {
+        this.useKeepAliveResponseHeader = useKeepAliveResponseHeader;
+    }
+
+
     private String relaxedPathChars = null;
     public String getRelaxedPathChars() {
         return relaxedPathChars;
diff --git a/java/org/apache/coyote/http11/Constants.java b/java/org/apache/coyote/http11/Constants.java
index 2b840ff..c6dfa2a 100644
--- a/java/org/apache/coyote/http11/Constants.java
+++ b/java/org/apache/coyote/http11/Constants.java
@@ -108,7 +108,12 @@ public final class Constants {
      */
     @Deprecated
     public static final byte[] CLOSE_BYTES = ByteChunk.convertToBytes(CLOSE);
+    /**
+     * @deprecated Unused. Will be removed in Tomcat 10.
+     */
+    @Deprecated
     public static final String KEEPALIVE = "keep-alive";
+    public static final String KEEP_ALIVE_HEADER_VALUE_TOKEN = "keep-alive";
     /**
      * @deprecated Unused. Will be removed in Tomcat 10.
      */
@@ -124,7 +129,7 @@ public final class Constants {
             ByteChunk.convertToBytes("HTTP/1.1 100 Continue" + CRLF + CRLF);
     public static final byte[] ACK_BYTES = ByteChunk.convertToBytes("HTTP/1.1 100 " + CRLF + CRLF);
     public static final String TRANSFERENCODING = "Transfer-Encoding";
-    public static final String KEEP_ALIVE = "Keep-Alive";
+    public static final String KEEP_ALIVE_HEADER_NAME = "Keep-Alive";
     public static final byte[] _200_BYTES = ByteChunk.convertToBytes("200");
     public static final byte[] _400_BYTES = ByteChunk.convertToBytes("400");
     public static final byte[] _404_BYTES = ByteChunk.convertToBytes("404");
diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java
index c4210fb..325c3c7 100644
--- a/java/org/apache/coyote/http11/Http11Processor.java
+++ b/java/org/apache/coyote/http11/Http11Processor.java
@@ -809,7 +809,7 @@ public class Http11Processor extends AbstractProcessor {
             TokenList.parseTokenList(headers.values(Constants.CONNECTION), tokens);
             if (tokens.contains(Constants.CLOSE)) {
                 keepAlive = false;
-            } else if (tokens.contains(Constants.KEEPALIVE)) {
+            } else if (tokens.contains(Constants.KEEP_ALIVE_HEADER_VALUE_TOKEN)) {
                 keepAlive = true;
             }
         }
@@ -1147,21 +1147,31 @@ public class Http11Processor extends AbstractProcessor {
             }
         } else if (!getErrorState().isError()) {
             if (!http11) {
-                headers.addValue(Constants.CONNECTION).setString(Constants.KEEPALIVE);
+                headers.addValue(Constants.CONNECTION).setString(Constants.KEEP_ALIVE_HEADER_VALUE_TOKEN);
             }
 
-            boolean connectionKeepAlivePresent =
-                isConnectionToken(request.getMimeHeaders(), Constants.KEEPALIVE);
+            if (protocol.getUseKeepAliveResponseHeader()) {
+                boolean connectionKeepAlivePresent =
+                    isConnectionToken(request.getMimeHeaders(), Constants.KEEP_ALIVE_HEADER_VALUE_TOKEN);
 
-            if (connectionKeepAlivePresent) {
-                int keepAliveTimeout = protocol.getKeepAliveTimeout();
+                if (connectionKeepAlivePresent) {
+                    int keepAliveTimeout = protocol.getKeepAliveTimeout();
 
-                if (keepAliveTimeout > 0) {
-                    String value = "timeout=" + keepAliveTimeout / 1000L;
-                    headers.setValue(Constants.KEEP_ALIVE).setString(value);
+                    if (keepAliveTimeout > 0) {
+                        String value = "timeout=" + keepAliveTimeout / 1000L;
+                        headers.setValue(Constants.KEEP_ALIVE_HEADER_NAME).setString(value);
 
-                    if (http11) {
-                        headers.addValue(Constants.CONNECTION).setString(Constants.KEEPALIVE);
+                        if (http11) {
+                            // Append if there is already a Connection header,
+                            // else create the header
+                            MessageBytes connectionHeaderValue = headers.getValue(Constants.CONNECTION);
+                            if (connectionHeaderValue == null) {
+                                headers.addValue(Constants.CONNECTION).setString(Constants.KEEP_ALIVE_HEADER_VALUE_TOKEN);
+                            } else {
+                                connectionHeaderValue.setString(
+                                        connectionHeaderValue.getString() + ", " + Constants.KEEP_ALIVE_HEADER_VALUE_TOKEN);
+                            }
+                        }
                     }
                 }
             }
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index 2ae9b6e..5766d26 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -647,6 +647,14 @@
       recorded correctly but it will be reported (e.g. via JMX) as
       <code>-1</code> to make clear that it is not used.</p>
     </attribute>
+
+    <attribute name="useKeepAliveResponseHeader" required="false">
+      <p>(bool) Use this attribute to enable or disable the addition of the
+      <code>Keep-Alive</code> HTTP response header as described in
+      <a href="https://tools.ietf.org/html/draft-thomson-hybi-http-timeout-03">this
+      Internet-Draft</a>. The default value is <code>true</code>.</p>
+    </attribute>
+
   </attributes>
 
   </subsection>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org