Author: markt
Date: Tue May 2 18:48:20 2017
New Revision: 1793573
URL: http://svn.apache.org/viewvc?rev=1793573&view=rev
Log:
Update the Servlet 4.0 implementation to add support for obtaining trailer
fields from chunked HTTP requests.
Modified:
tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java
tomcat/trunk/java/javax/servlet/http/HttpServletRequestWrapper.java
tomcat/trunk/java/org/apache/catalina/connector/Request.java
tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java
tomcat/trunk/java/org/apache/coyote/Request.java
tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
tomcat/trunk/java/org/apache/coyote/http2/Stream.java
tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java
tomcat/trunk/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java (original)
+++ tomcat/trunk/java/javax/servlet/http/HttpServletRequest.java Tue May 2
18:48:20 2017
@@ -20,6 +20,7 @@ package javax.servlet.http;
import java.io.IOException;
import java.util.Collection;
import java.util.Enumeration;
+import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
@@ -575,4 +576,13 @@ public interface HttpServletRequest exte
*/
public <T extends HttpUpgradeHandler> T upgrade(
Class<T> httpUpgradeHandlerClass) throws java.io.IOException,
ServletException;
+
+ /**
+ * Obtain a Map of the trailer fields that is not backed by the request
+ * object.
+ *
+ * @return A Map of the received trailer fields with all keys lower case
+ * or an empty Map if no trailers are present
+ */
+ public Map<String,String> getTrailerFields();
}
Modified: tomcat/trunk/java/javax/servlet/http/HttpServletRequestWrapper.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/http/HttpServletRequestWrapper.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/java/javax/servlet/http/HttpServletRequestWrapper.java
(original)
+++ tomcat/trunk/java/javax/servlet/http/HttpServletRequestWrapper.java Tue May
2 18:48:20 2017
@@ -19,6 +19,7 @@ package javax.servlet.http;
import java.io.IOException;
import java.util.Collection;
import java.util.Enumeration;
+import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletRequestWrapper;
@@ -396,4 +397,17 @@ public class HttpServletRequestWrapper e
public PushBuilder newPushBuilder() {
return this._getHttpServletRequest().newPushBuilder();
}
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * The default behavior of this method is to return
+ * {@link HttpServletRequest#newPushBuilder()} on the wrapped request
object.
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public Map<String,String> getTrailerFields() {
+ return this._getHttpServletRequest().getTrailerFields();
+ }
}
Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Tue May 2
18:48:20 2017
@@ -1930,6 +1930,14 @@ public class Request implements HttpServ
// --------------------------------------------- HttpServletRequest Methods
+ @Override
+ public Map<String, String> getTrailerFields() {
+ Map<String,String> result = new HashMap<>();
+ result.putAll(coyoteRequest.getTrailerFields());
+ return result;
+ }
+
+
/**
* {@inheritDoc}
*
Modified: tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/connector/RequestFacade.java Tue May
2 18:48:20 2017
@@ -1137,4 +1137,15 @@ public class RequestFacade implements Ht
public PushBuilder newPushBuilder() {
return request.newPushBuilder();
}
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since Servlet 4.0
+ */
+ @Override
+ public Map<String, String> getTrailerFields() {
+ return request.getTrailerFields();
+ }
}
Modified: tomcat/trunk/java/org/apache/coyote/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Request.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/Request.java (original)
+++ tomcat/trunk/java/org/apache/coyote/Request.java Tue May 2 18:48:20 2017
@@ -96,6 +96,7 @@ public final class Request {
private final MessageBytes localAddrMB = MessageBytes.newInstance();
private final MimeHeaders headers = new MimeHeaders();
+ private final Map<String,String> trailerFields = new HashMap<>();
/**
@@ -193,12 +194,17 @@ public final class Request {
}
+ public Map<String,String> getTrailerFields() {
+ return trailerFields;
+ }
+
+
public UDecoder getURLDecoder() {
return urlDecoder;
}
- // -------------------- Request data --------------------
+ // -------------------- Request data --------------------
public MessageBytes scheme() {
return schemeMB;
Modified:
tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
Tue May 2 18:48:20 2017
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import org.apache.coyote.InputBuffer;
@@ -29,8 +30,6 @@ import org.apache.coyote.http11.Constant
import org.apache.coyote.http11.InputFilter;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.HexUtils;
-import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.net.ApplicationBufferHandler;
import org.apache.tomcat.util.res.StringManager;
@@ -435,7 +434,7 @@ public class ChunkedInputFilter implemen
private boolean parseHeader() throws IOException {
- MimeHeaders headers = request.getMimeHeaders();
+ Map<String,String> headers = request.getTrailerFields();
byte chr = 0;
@@ -579,12 +578,14 @@ public class ChunkedInputFilter implemen
String headerName = new String(trailingHeaders.getBytes(), startPos,
colonPos - startPos, StandardCharsets.ISO_8859_1);
- if
(allowedTrailerHeaders.contains(headerName.toLowerCase(Locale.ENGLISH))) {
- MessageBytes headerValue = headers.addValue(headerName);
+ headerName = headerName.toLowerCase(Locale.ENGLISH);
- // Set the header value
- headerValue.setBytes(trailingHeaders.getBytes(), colonPos,
- lastSignificantChar - colonPos);
+ if (allowedTrailerHeaders.contains(headerName)) {
+
+ String value = new String(trailingHeaders.getBytes(), colonPos,
+ lastSignificantChar - colonPos,
StandardCharsets.ISO_8859_1);
+
+ headers.put(headerName, value);
}
return true;
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=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Tue May 2 18:48:20
2017
@@ -345,8 +345,13 @@ class Stream extends AbstractStream impl
headerStateErrorMsg =
sm.getString("stream.header.unknownPseudoHeader",
getConnectionId(), getIdentifier(), name);
}
- // Assume other HTTP header
- coyoteRequest.getMimeHeaders().addValue(name).setString(value);
+
+ if (headerState == HEADER_STATE_TRAILER) {
+ // HTTP/2 headers are already always lower case
+ coyoteRequest.getTrailerFields().put(name, value);
+ } else {
+ coyoteRequest.getMimeHeaders().addValue(name).setString(value);
+ }
}
}
}
Modified:
tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java
(original)
+++ tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java
Tue May 2 18:48:20 2017
@@ -446,4 +446,9 @@ public class TesterHttpServletRequest im
public PushBuilder newPushBuilder() {
throw new RuntimeException("Not implemented");
}
+
+ @Override
+ public Map<String, String> getTrailerFields() {
+ throw new RuntimeException("Not implemented");
+ }
}
Modified:
tomcat/trunk/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
---
tomcat/trunk/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
(original)
+++
tomcat/trunk/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
Tue May 2 18:48:20 2017
@@ -105,7 +105,7 @@ public class TestChunkedInputFilter exte
Context ctx = tomcat.addContext("", null);
// Configure allowed trailer headers
- tomcat.getConnector().setProperty("allowedTrailerHeaders",
"X-Trailer1,X-Trailer2");
+ tomcat.getConnector().setProperty("allowedTrailerHeaders",
"x-trailer1,x-trailer2");
EchoHeaderServlet servlet = new EchoHeaderServlet(expectPass);
Tomcat.addServlet(ctx, "servlet", servlet);
@@ -478,7 +478,7 @@ public class TestChunkedInputFilter exte
private void dumpHeader(String headerName, HttpServletRequest req,
PrintWriter pw) {
- String value = req.getHeader(headerName);
+ String value = req.getTrailerFields().get(headerName);
if (value == null) {
value = "null";
}
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=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java (original)
+++ tomcat/trunk/test/org/apache/coyote/http2/Http2TestBase.java Tue May 2
18:48:20 2017
@@ -72,7 +72,7 @@ public abstract class Http2TestBase exte
EMPTY_HTTP2_SETTINGS_HEADER = "HTTP2-Settings: " +
Base64.encodeBase64String(empty) + "\r\n";
}
- protected 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;
@@ -1091,7 +1091,7 @@ public abstract class Http2TestBase exte
IOTools.flow(bais, resp.getOutputStream());
// Check for trailer headers
- String trailerValue = req.getHeader(TRAILER_HEADER_NAME);
+ String trailerValue =
req.getTrailerFields().get(TRAILER_HEADER_NAME);
if (trailerValue != null) {
resp.getOutputStream().write(trailerValue.getBytes(StandardCharsets.UTF_8));
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1793573&r1=1793572&r2=1793573&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue May 2 18:48:20 2017
@@ -104,6 +104,10 @@
custom error page located below <code>WEB-INF</code>, ensure that the
target error page is displayed rather than a 404 response. (markt)
</fix>
+ <update>
+ Update the Servlet 4.0 implementation to add support for obtaining
+ trailer fields from chunked HTTP requests. (markt)
+ </update>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]