138 lines
4.8 KiB
Diff
138 lines
4.8 KiB
Diff
From 74888576a60ec58ee99454e4202a0eb1a7720d98 Mon Sep 17 00:00:00 2001
|
|
From: Mark Thomas <markt@apache.org>
|
|
Date: Mon, 10 May 2021 22:14:18 +0100
|
|
Subject: [PATCH] Ensure chunked, if present, is the last encoding in the list
|
|
|
|
---
|
|
.../apache/coyote/http11/Http11Processor.java | 13 ++++++++-
|
|
.../coyote/http11/TestHttp11Processor.java | 28 +++++++++++++------
|
|
webapps/docs/changelog.xml | 5 ++++
|
|
3 files changed, 36 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java
|
|
index 4021355..17932b9 100644
|
|
--- a/java/org/apache/coyote/http11/Http11Processor.java
|
|
+++ b/java/org/apache/coyote/http11/Http11Processor.java
|
|
@@ -238,11 +238,22 @@ public class Http11Processor extends AbstractProcessor {
|
|
* supported, a 501 response will be returned to the client.
|
|
*/
|
|
private void addInputFilter(InputFilter[] inputFilters, String encodingName) {
|
|
+ if (contentDelimitation) {
|
|
+ // Chunked has already been specified and it must be the final
|
|
+ // encoding.
|
|
+ // 400 - Bad request
|
|
+ response.setStatus(400);
|
|
+ setErrorState(ErrorState.CLOSE_CLEAN, null);
|
|
+ if (log.isDebugEnabled()) {
|
|
+ log.debug(sm.getString("http11processor.request.prepare") +
|
|
+ " Tranfer encoding lists chunked before [" + encodingName + "]");
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
|
|
// Trim provided encoding name and convert to lower case since transfer
|
|
// encoding names are case insensitive. (RFC2616, section 3.6)
|
|
encodingName = encodingName.trim().toLowerCase(Locale.ENGLISH);
|
|
-
|
|
if (encodingName.equals("chunked")) {
|
|
inputBuffer.addActiveFilter(inputFilters[Constants.CHUNKED_FILTER]);
|
|
contentDelimitation = true;
|
|
diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java b/test/org/apache/coyote/http11/TestHttp11Processor.java
|
|
index 84fdd42..ceb2601 100644
|
|
--- a/test/org/apache/coyote/http11/TestHttp11Processor.java
|
|
+++ b/test/org/apache/coyote/http11/TestHttp11Processor.java
|
|
@@ -1287,47 +1287,53 @@ public class TestHttp11Processor extends TomcatBaseTest {
|
|
|
|
@Test
|
|
public void testTEHeaderUnknown01() throws Exception {
|
|
- doTestTEHeaderUnknown("identity");
|
|
+ doTestTEHeaderInvalid("identity", false);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testTEHeaderUnknown02() throws Exception {
|
|
- doTestTEHeaderUnknown("identity, chunked");
|
|
+ doTestTEHeaderInvalid("identity, chunked", false);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testTEHeaderUnknown03() throws Exception {
|
|
- doTestTEHeaderUnknown("unknown, chunked");
|
|
+ doTestTEHeaderInvalid("unknown, chunked", false);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testTEHeaderUnknown04() throws Exception {
|
|
- doTestTEHeaderUnknown("void");
|
|
+ doTestTEHeaderInvalid("void", false);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testTEHeaderUnknown05() throws Exception {
|
|
- doTestTEHeaderUnknown("void, chunked");
|
|
+ doTestTEHeaderInvalid("void, chunked", false);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testTEHeaderUnknown06() throws Exception {
|
|
- doTestTEHeaderUnknown("void, identity");
|
|
+ doTestTEHeaderInvalid("void, identity", false);
|
|
}
|
|
|
|
|
|
@Test
|
|
public void testTEHeaderUnknown07() throws Exception {
|
|
- doTestTEHeaderUnknown("identity, void");
|
|
+ doTestTEHeaderInvalid("identity, void", false);
|
|
}
|
|
|
|
|
|
- private void doTestTEHeaderUnknown(String headerValue) throws Exception {
|
|
+ @Test
|
|
+ public void testTEHeaderChunkedNotLast01() throws Exception {
|
|
+ doTestTEHeaderInvalid("chunked, void", true);
|
|
+ }
|
|
+
|
|
+
|
|
+ private void doTestTEHeaderInvalid(String headerValue, boolean badRequest) throws Exception {
|
|
Tomcat tomcat = getTomcatInstance();
|
|
|
|
// No file system docBase required
|
|
@@ -1351,7 +1357,11 @@ public class TestHttp11Processor extends TomcatBaseTest {
|
|
client.connect();
|
|
client.processRequest(false);
|
|
|
|
- Assert.assertTrue(client.isResponse501());
|
|
+ if (badRequest) {
|
|
+ Assert.assertTrue(client.isResponse400());
|
|
+ } else {
|
|
+ Assert.assertTrue(client.isResponse501());
|
|
+ }
|
|
}
|
|
|
|
|
|
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
|
|
index e47f3d6..35b8eab 100644
|
|
--- a/webapps/docs/changelog.xml
|
|
+++ b/webapps/docs/changelog.xml
|
|
@@ -319,6 +319,11 @@
|
|
Process transfer encoding headers from both HTTP 1.0 and HTTP 1.1
|
|
clients. (markt)
|
|
</fix>
|
|
+ <fix>
|
|
+ Ensure that if the transfer encoding header contains the
|
|
+ <code>chunked</code>, that the <code>chunked</code> encoding is the
|
|
+ final encoding listed. (markt)
|
|
+ </fix>
|
|
</changelog>
|
|
</subsection>
|
|
<subsection name="Web applications">
|
|
--
|
|
2.23.0
|
|
|