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 2020/03/31 13:05:41 UTC
[tomcat] 03/03: Make the HTTP/2 connection ID and stream Id
available to applications
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org