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:32:16 UTC

[tomcat] branch master updated: Implement feedback on BZ 63835

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

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


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

commit f4e7cdcff5abc239866e1d69906086cf1bae78ad
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                       |  9 +++++-
 4 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
index fdeda3f..61d9a0c 100644
--- a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
+++ b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
@@ -95,6 +95,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 55045d4..7c8bff2 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.
      */
@@ -117,7 +122,7 @@ public final class Constants {
     public static final String CHUNKED = "chunked";
     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 4698174..c627f19 100644
--- a/java/org/apache/coyote/http11/Http11Processor.java
+++ b/java/org/apache/coyote/http11/Http11Processor.java
@@ -566,7 +566,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;
             }
         }
@@ -909,21 +909,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 6949d36..6419370 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -640,11 +640,18 @@
     </attribute>
 
     <attribute name="useAsyncIO" required="false">
-      <p>(bool)Use this attribute to enable or disable usage of the
+      <p>(bool) Use this attribute to enable or disable usage of the
       asynchronous IO API. The default value is <code>true</code> except when
       using the APR connector due to low performance.</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