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 2016/10/19 13:31:36 UTC
svn commit: r1765590 - in /tomcat/trunk: java/org/apache/coyote/http2/
test/org/apache/coyote/http2/ webapps/docs/ webapps/docs/config/
Author: markt
Date: Wed Oct 19 13:31:36 2016
New Revision: 1765590
URL: http://svn.apache.org/viewvc?rev=1765590&view=rev
Log:
Enable configuration of allowed trailer headers
Modified:
tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java
tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
tomcat/trunk/java/org/apache/coyote/http2/Stream.java
tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java
tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/config/http2.xml
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java?rev=1765590&r1=1765589&r2=1765590&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java Wed Oct 19 13:31:36 2016
@@ -17,7 +17,14 @@
package org.apache.coyote.http2;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.coyote.Adapter;
import org.apache.coyote.Processor;
@@ -54,6 +61,9 @@ public class Http2Protocol implements Up
// If a lower initial value is required, set it here but DO NOT change the
// default defined above.
private int initialWindowSize = DEFAULT_INITIAL_WINDOW_SIZE;
+ private Set<String> allowedTrailerHeaders =
+ Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
+
@Override
public String getHttpUpgradeName(boolean isSSLEnabled) {
@@ -93,7 +103,7 @@ public class Http2Protocol implements Up
result.setMaxConcurrentStreams(getMaxConcurrentStreams());
result.setMaxConcurrentStreamExecution(getMaxConcurrentStreamExecution());
result.setInitialWindowSize(getInitialWindowSize());
-
+ result.setAllowedTrailerHeaders(allowedTrailerHeaders);
return result;
}
@@ -178,4 +188,43 @@ public class Http2Protocol implements Up
public void setInitialWindowSize(int initialWindowSize) {
this.initialWindowSize = initialWindowSize;
}
+
+
+ public void setAllowedTrailerHeaders(String commaSeparatedHeaders) {
+ // Jump through some hoops so we don't end up with an empty set while
+ // doing updates.
+ Set<String> toRemove = new HashSet<>();
+ toRemove.addAll(allowedTrailerHeaders);
+ if (commaSeparatedHeaders != null) {
+ String[] headers = commaSeparatedHeaders.split(",");
+ for (String header : headers) {
+ String trimmedHeader = header.trim().toLowerCase(Locale.ENGLISH);
+ if (toRemove.contains(trimmedHeader)) {
+ toRemove.remove(trimmedHeader);
+ } else {
+ allowedTrailerHeaders.add(trimmedHeader);
+ }
+ }
+ allowedTrailerHeaders.removeAll(toRemove);
+ }
+ }
+
+
+ public String getAllowedTrailerHeaders() {
+ // Chances of a size change between these lines are small enough that a
+ // sync is unnecessary.
+ List<String> copy = new ArrayList<>(allowedTrailerHeaders.size());
+ copy.addAll(allowedTrailerHeaders);
+ StringBuilder result = new StringBuilder();
+ boolean first = true;
+ for (String header : copy) {
+ if (first) {
+ first = false;
+ } else {
+ result.append(',');
+ }
+ result.append(header);
+ }
+ return result.toString();
+ }
}
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1765590&r1=1765589&r2=1765590&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Wed Oct 19 13:31:36 2016
@@ -20,6 +20,7 @@ import java.io.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -144,6 +145,10 @@ class Http2UpgradeHandler extends Abstra
private AtomicInteger streamConcurrency = null;
private Queue<StreamProcessor> queuedProcessors = null;
+ // Limits
+ private Set<String> allowedTrailerHeaders = Collections.emptySet();
+
+
Http2UpgradeHandler(Adapter adapter, Request coyoteRequest) {
super (STREAM_ID_ZERO);
this.adapter = adapter;
@@ -1051,6 +1056,11 @@ class Http2UpgradeHandler extends Abstra
}
+ boolean isTrailerHeaderAllowed(String headerName) {
+ return allowedTrailerHeaders.contains(headerName);
+ }
+
+
// ------------------------------------------- Configuration getters/setters
public long getReadTimeout() {
@@ -1098,6 +1108,11 @@ class Http2UpgradeHandler extends Abstra
}
+ public void setAllowedTrailerHeaders(Set<String> allowedTrailerHeaders) {
+ this.allowedTrailerHeaders = allowedTrailerHeaders;
+ }
+
+
// ----------------------------------------------- Http2Parser.Input methods
@Override
Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Stream.java?rev=1765590&r1=1765589&r2=1765590&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Wed Oct 19 13:31:36 2016
@@ -268,6 +268,9 @@ class Stream extends AbstractStream impl
break;
}
default: {
+ if (headerState == HEADER_STATE_TRAILER && !handler.isTrailerHeaderAllowed(name)) {
+ break;
+ }
if ("expect".equals(name) && "100-continue".equals(value)) {
coyoteRequest.setExpectation(true);
}
Modified: tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java?rev=1765590&r1=1765589&r2=1765590&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java (original)
+++ tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java Wed Oct 19 13:31:36 2016
@@ -69,7 +69,8 @@ public abstract class Http2TestBase exte
EMPTY_HTTP2_SETTINGS_HEADER = "HTTP2-Settings: " + Base64.encodeBase64String(empty) + "\r\n";
}
- private static final String TRAILER_HEADER_NAME = "X-TrailerTest";
+ protected static final String TRAILER_HEADER_NAME = "X-TrailerTest";
+ protected static final String TRAILER_HEADER_VALUE = "test";
private Socket s;
protected HpackEncoder hpackEncoder;
@@ -354,7 +355,7 @@ public abstract class Http2TestBase exte
// Trailers
if (trailersPayload != null) {
MimeHeaders trailerHeaders = new MimeHeaders();
- trailerHeaders.addValue(TRAILER_HEADER_NAME).setString("xxxx");
+ trailerHeaders.addValue(TRAILER_HEADER_NAME).setString(TRAILER_HEADER_VALUE);
hpackEncoder.encode(trailerHeaders, trailersPayload);
trailersPayload.flip();
Modified: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java?rev=1765590&r1=1765589&r2=1765590&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java (original)
+++ tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_8_1.java Wed Oct 19 13:31:36 2016
@@ -34,7 +34,23 @@ public class TestHttp2Section_8_1 extend
@Test
public void testPostWithTrailerHeaders() throws Exception {
+ doTestPostWithTrailerHeaders(true);
+ }
+
+
+ @Test
+ public void testPostWithTrailerHeadersBlocked() throws Exception {
+ doTestPostWithTrailerHeaders(false);
+ }
+
+
+ private void doTestPostWithTrailerHeaders(boolean allowTrailerHeader) throws Exception{
http2Connect();
+ if (allowTrailerHeader) {
+ Http2Protocol http2Protocol =
+ (Http2Protocol) getTomcatInstance().getConnector().findUpgradeProtocols()[0];
+ http2Protocol.setAllowedTrailerHeaders(TRAILER_HEADER_NAME);
+ }
byte[] headersFrameHeader = new byte[9];
ByteBuffer headersPayload = ByteBuffer.allocate(128);
@@ -58,13 +74,22 @@ public class TestHttp2Section_8_1 extend
parser.readFrame(true);
parser.readFrame(true);
+ String len;
+ if (allowTrailerHeader) {
+ len = Integer.toString(256 + TRAILER_HEADER_VALUE.length());
+ } else {
+ len = "256";
+ }
+
Assert.assertEquals("0-WindowSize-[256]\n" +
"3-WindowSize-[256]\n" +
"3-HeadersStart\n" +
"3-Header-[:status]-[200]\n" +
"3-Header-[date]-["+ DEFAULT_DATE + "]\n" +
"3-HeadersEnd\n" +
- "3-Body-260\n" +
+ "3-Body-" +
+ len +
+ "\n" +
"3-EndOfStream\n",
output.getTrace());
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1765590&r1=1765589&r2=1765590&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Oct 19 13:31:36 2016
@@ -115,6 +115,9 @@
Add addition checks around the handling of HTTP/2 pseudo headers.
(markt)
</add>
+ <add>
+ Add support for trailer headers to the HTTP/2 implementation. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Jasper">
Modified: tomcat/trunk/webapps/docs/config/http2.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http2.xml?rev=1765590&r1=1765589&r2=1765590&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/http2.xml (original)
+++ tomcat/trunk/webapps/docs/config/http2.xml Wed Oct 19 13:31:36 2016
@@ -71,6 +71,12 @@
<attributes>
+ <attribute name="allowedTrailerHeaders" required="false">
+ <p>By default Tomcat will ignore all trailer headers when processing
+ HTTP/2 connections. For a header to be processed, it must be added to this
+ comma-separated list of header names.</p>
+ </attribute>
+
<attribute name="initialWindowSize" required="false">
<p>Controls the initial size of the flow control window for streams that
Tomcat advertises to clients. If not specified, the default value of
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org