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

commit ff8478ebefc0eb511fcf147b1e5aa6d7d009f118
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue Mar 31 14:03:17 2020 +0100

    Make the HTTP/2 connection ID and stream Id available to applications
---
 java/org/apache/catalina/Globals.java             | 16 ++++++++++
 java/org/apache/catalina/connector/Request.java   | 27 ++++++++++++++++
 java/org/apache/coyote/AbstractProcessor.java     | 39 +++++++++++++++++++++++
 java/org/apache/coyote/ActionCode.java            | 14 +++++++-
 java/org/apache/coyote/http2/StreamProcessor.java | 12 +++++++
 webapps/docs/changelog.xml                        |  5 +++
 webapps/docs/config/http2.xml                     |  9 ++++++
 7 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/catalina/Globals.java 
b/java/org/apache/catalina/Globals.java
index 5472e37..eec8215 100644
--- a/java/org/apache/catalina/Globals.java
+++ b/java/org/apache/catalina/Globals.java
@@ -51,6 +51,22 @@ public final class Globals {
 
 
     /**
+     * The request attribute used to expose the current connection ID 
associated
+     * with the request, if any. Used with multiplexing protocols such as
+     * HTTTP/2.
+     */
+    public static final String CONNECTION_ID = 
"org.apache.coyote.connectionID";
+
+
+    /**
+     * The request attribute used to expose the current stream ID associated
+     * with the request, if any. Used with multiplexing protocols such as
+     * HTTTP/2.
+     */
+    public static final String STREAM_ID = "org.apache.coyote.streamID";
+
+
+    /**
      * The request attribute that is set to {@code Boolean.TRUE} if some 
request
      * parameters have been ignored during request parameters parsing. It can
      * happen, for example, if there is a limit on the total count of parseable
diff --git a/java/org/apache/catalina/connector/Request.java 
b/java/org/apache/catalina/connector/Request.java
index edff176..e36debf 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -38,6 +38,7 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.naming.NamingException;
 import javax.security.auth.Subject;
@@ -3491,5 +3492,31 @@ public class Request implements HttpServletRequest {
                         // NO-OP
                     }
                 });
+        specialAttributes.put(Globals.CONNECTION_ID,
+                new SpecialAttributeAdapter() {
+                    @Override
+                    public Object get(Request request, String name) {
+                        AtomicReference<Object> result = new 
AtomicReference<>();
+                        
request.getCoyoteRequest().action(ActionCode.CONNECTION_ID, result);
+                        return result.get();
+                    }
+                    @Override
+                    public void set(Request request, String name, Object 
value) {
+                        // NO-OP
+                    }
+                });
+        specialAttributes.put(Globals.STREAM_ID,
+                new SpecialAttributeAdapter() {
+                    @Override
+                    public Object get(Request request, String name) {
+                        AtomicReference<Object> result = new 
AtomicReference<>();
+                        
request.getCoyoteRequest().action(ActionCode.STREAM_ID, result);
+                        return result.get();
+                    }
+                    @Override
+                    public void set(Request request, String name, Object 
value) {
+                        // NO-OP
+                    }
+                });
     }
 }
diff --git a/java/org/apache/coyote/AbstractProcessor.java 
b/java/org/apache/coyote/AbstractProcessor.java
index 94546de..46b96a0 100644
--- a/java/org/apache/coyote/AbstractProcessor.java
+++ b/java/org/apache/coyote/AbstractProcessor.java
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
 import java.util.Iterator;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 import jakarta.servlet.RequestDispatcher;
 
@@ -619,6 +620,20 @@ public abstract class AbstractProcessor extends 
AbstractProcessorLight implement
             result.set(isTrailerFieldsSupported());
             break;
         }
+
+        // Identifiers associated with multiplexing protocols like HTTP/2
+        case CONNECTION_ID: {
+            @SuppressWarnings("unchecked")
+            AtomicReference<Object> result = (AtomicReference<Object>) param;
+            result.set(getConnectionID());
+            break;
+        }
+        case STREAM_ID: {
+            @SuppressWarnings("unchecked")
+            AtomicReference<Object> result = (AtomicReference<Object>) param;
+            result.set(getStreamID());
+            break;
+        }
         }
     }
 
@@ -955,6 +970,30 @@ public abstract class AbstractProcessor extends 
AbstractProcessorLight implement
 
 
     /**
+     * Protocols that support multiplexing (e.g. HTTP/2) should override this
+     * method and return the appropriate ID.
+     *
+     * @return The stream ID associated with this request or {@code null} if a
+     *         multiplexing protocol is not being used
+      */
+    protected Object getConnectionID() {
+        return null;
+    }
+
+
+    /**
+     * Protocols that support multiplexing (e.g. HTTP/2) should override this
+     * method and return the appropriate ID.
+     *
+     * @return The stream ID associated with this request or {@code null} if a
+     *         multiplexing protocol is not being used
+     */
+    protected Object getStreamID() {
+        return null;
+    }
+
+
+    /**
      * Flush any pending writes. Used during non-blocking writes to flush any
      * remaining data from a previous incomplete write.
      *
diff --git a/java/org/apache/coyote/ActionCode.java 
b/java/org/apache/coyote/ActionCode.java
index 12dd23d..52628cf 100644
--- a/java/org/apache/coyote/ActionCode.java
+++ b/java/org/apache/coyote/ActionCode.java
@@ -265,5 +265,17 @@ public enum ActionCode {
      * once an HTTP/1.1 response has been committed, it will no longer support
      * trailer fields.
      */
-    IS_TRAILER_FIELDS_SUPPORTED
+    IS_TRAILER_FIELDS_SUPPORTED,
+
+    /**
+     * Obtain the connection identifier for the request. Used with multiplexing
+     * protocols such as HTTP/2.
+     */
+    CONNECTION_ID,
+
+    /**
+     * Obtain the stream identifier for the request. Used with multiplexing
+     * protocols such as HTTP/2.
+     */
+    STREAM_ID
 }
diff --git a/java/org/apache/coyote/http2/StreamProcessor.java 
b/java/org/apache/coyote/http2/StreamProcessor.java
index 99e2d78..15bfcab 100644
--- a/java/org/apache/coyote/http2/StreamProcessor.java
+++ b/java/org/apache/coyote/http2/StreamProcessor.java
@@ -339,6 +339,18 @@ class StreamProcessor extends AbstractProcessor {
 
 
     @Override
+    protected Object getConnectionID() {
+        return stream.getConnectionId();
+    }
+
+
+    @Override
+    protected Object getStreamID() {
+        return stream.getIdentifier().toString();
+    }
+
+
+    @Override
     public final void recycle() {
         // StreamProcessor instances are not re-used.
         // Clear fields that can be cleared to aid GC and trigger NPEs if this
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 4979bcc..f98667e 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -145,6 +145,11 @@
         data on the request line after the URI are treated consistently. Such
         requests will now always be treated as HTTP/1.1. (markt)
       </fix>
+      <add>
+        Expose the HTTP/2 connection ID and stream ID to applications via the
+        request attributes <code>org.apache.coyote.connectionID</code> and
+        <code>org.apache.coyote.streamID</code> respectively. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Jasper">
diff --git a/webapps/docs/config/http2.xml b/webapps/docs/config/http2.xml
index 98fd49b..7d6e1ff 100644
--- a/webapps/docs/config/http2.xml
+++ b/webapps/docs/config/http2.xml
@@ -44,6 +44,15 @@
   the Servlet API is fundamentally blocking, each HTTP/2 stream requires a
   dedicated container thread for the duration of that stream.</p>
 
+  <p>Requests processed using HTTP/2 will have the following additional request
+  attributes available:</p>
+  <ul>
+    <li><code>org.apache.coyote.connectionID</code> will return the HTTP/2
+        connection ID</li>
+    <li><code>org.apache.coyote.streamID</code> will return the HTTP/2 stream
+        ID</li>
+  </ul>
+
 </section>
 
 


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

Reply via email to