(tomcat) 03/04: Refactor chunked input filter to use common HTTP header/trailer parser
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git commit 92e3c7a7adc574a859ab70333bf930561dcf1e9d Author: Mark Thomas AuthorDate: Fri Apr 26 15:58:37 2024 +0100 Refactor chunked input filter to use common HTTP header/trailer parser This adds non-blocking read support for chunked request bodies --- java/org/apache/coyote/http11/Http11Processor.java | 2 +- .../coyote/http11/filters/ChunkedInputFilter.java | 576 - webapps/docs/changelog.xml | 3 + 3 files changed, 233 insertions(+), 348 deletions(-) diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java index 0692b8da4e..c75243e369 100644 --- a/java/org/apache/coyote/http11/Http11Processor.java +++ b/java/org/apache/coyote/http11/Http11Processor.java @@ -169,7 +169,7 @@ public class Http11Processor extends AbstractProcessor { // Create and add the chunked filters. inputBuffer.addFilter( -new ChunkedInputFilter(protocol.getMaxTrailerSize(), protocol.getAllowedTrailerHeadersInternal(), +new ChunkedInputFilter(request, protocol.getMaxTrailerSize(), protocol.getAllowedTrailerHeadersInternal(), protocol.getMaxExtensionSize(), protocol.getMaxSwallowSize())); outputBuffer.addFilter(new ChunkedOutputFilter()); diff --git a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java index 741cd1078b..f350487771 100644 --- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java +++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java @@ -16,11 +16,9 @@ */ package org.apache.coyote.http11.filters; -import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.Locale; import java.util.Set; import org.apache.coyote.ActionCode; @@ -31,8 +29,9 @@ import org.apache.coyote.http11.Constants; 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.http.MimeHeaders; -import org.apache.tomcat.util.http.parser.HttpParser; +import org.apache.tomcat.util.http.parser.HttpHeaderParser; +import org.apache.tomcat.util.http.parser.HttpHeaderParser.HeaderDataSource; +import org.apache.tomcat.util.http.parser.HttpHeaderParser.HeaderParseStatus; import org.apache.tomcat.util.net.ApplicationBufferHandler; import org.apache.tomcat.util.res.StringManager; @@ -42,7 +41,7 @@ import org.apache.tomcat.util.res.StringManager; * * @author Remy Maucherat */ -public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler { +public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler, HeaderDataSource { private static final StringManager sm = StringManager.getManager(ChunkedInputFilter.class); @@ -82,28 +81,15 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler /** - * Flag set to true when the end chunk has been read. + * Buffer used to store trailing headers. Is normally in read mode. */ -protected boolean endChunk = false; - - -/** - * Byte chunk used to store trailing headers. - */ -protected final ByteChunk trailingHeaders = new ByteChunk(); - - -/** - * Flag set to true if the next call to doRead() must parse a CRLF pair - * before doing anything else. - */ -protected boolean needCRLFParse = false; +protected final ByteBuffer trailingHeaders; /** * Request being parsed. */ -private Request request; +private final Request request; /** @@ -112,38 +98,31 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler private final long maxExtensionSize; -/** - * Limit for trailer size. - */ -private final int maxTrailerSize; - - -/** - * Size of extensions processed for this request. - */ -private long extensionSize; - - private final int maxSwallowSize; +private final Set allowedTrailerHeaders; -/** - * Flag that indicates if an error has occurred. +/* + * Parsing state. */ -private boolean error; - - -private final Set allowedTrailerHeaders; +private volatile ParseState parseState = ParseState.CHUNK_HEADER; +private volatile boolean crFound = false; +private volatile int chunkSizeDigitsRead = 0; +private volatile boolean parsingExtension = false; +private volatile long extensionSize; +private final HttpHeaderParser httpHeaderParser; // --- Constructors -public ChunkedInputFilter(int ma
(tomcat) 03/04: Refactor chunked input filter to use common HTTP header/trailer parser
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git commit cbed8e1836962d43120b81ae99d8d1b349265749 Author: Mark Thomas AuthorDate: Fri Apr 26 15:58:37 2024 +0100 Refactor chunked input filter to use common HTTP header/trailer parser This adds non-blocking read support for chunked request bodies --- java/org/apache/coyote/http11/Http11Processor.java | 2 +- .../coyote/http11/filters/ChunkedInputFilter.java | 576 - 2 files changed, 230 insertions(+), 348 deletions(-) diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java index 3a1897a84b..b2fac4af8c 100644 --- a/java/org/apache/coyote/http11/Http11Processor.java +++ b/java/org/apache/coyote/http11/Http11Processor.java @@ -167,7 +167,7 @@ public class Http11Processor extends AbstractProcessor { // Create and add the chunked filters. inputBuffer.addFilter( -new ChunkedInputFilter(protocol.getMaxTrailerSize(), protocol.getAllowedTrailerHeadersInternal(), +new ChunkedInputFilter(request, protocol.getMaxTrailerSize(), protocol.getAllowedTrailerHeadersInternal(), protocol.getMaxExtensionSize(), protocol.getMaxSwallowSize())); outputBuffer.addFilter(new ChunkedOutputFilter()); diff --git a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java index 741cd1078b..f350487771 100644 --- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java +++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java @@ -16,11 +16,9 @@ */ package org.apache.coyote.http11.filters; -import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.Locale; import java.util.Set; import org.apache.coyote.ActionCode; @@ -31,8 +29,9 @@ import org.apache.coyote.http11.Constants; 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.http.MimeHeaders; -import org.apache.tomcat.util.http.parser.HttpParser; +import org.apache.tomcat.util.http.parser.HttpHeaderParser; +import org.apache.tomcat.util.http.parser.HttpHeaderParser.HeaderDataSource; +import org.apache.tomcat.util.http.parser.HttpHeaderParser.HeaderParseStatus; import org.apache.tomcat.util.net.ApplicationBufferHandler; import org.apache.tomcat.util.res.StringManager; @@ -42,7 +41,7 @@ import org.apache.tomcat.util.res.StringManager; * * @author Remy Maucherat */ -public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler { +public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler, HeaderDataSource { private static final StringManager sm = StringManager.getManager(ChunkedInputFilter.class); @@ -82,28 +81,15 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler /** - * Flag set to true when the end chunk has been read. + * Buffer used to store trailing headers. Is normally in read mode. */ -protected boolean endChunk = false; - - -/** - * Byte chunk used to store trailing headers. - */ -protected final ByteChunk trailingHeaders = new ByteChunk(); - - -/** - * Flag set to true if the next call to doRead() must parse a CRLF pair - * before doing anything else. - */ -protected boolean needCRLFParse = false; +protected final ByteBuffer trailingHeaders; /** * Request being parsed. */ -private Request request; +private final Request request; /** @@ -112,38 +98,31 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler private final long maxExtensionSize; -/** - * Limit for trailer size. - */ -private final int maxTrailerSize; - - -/** - * Size of extensions processed for this request. - */ -private long extensionSize; - - private final int maxSwallowSize; +private final Set allowedTrailerHeaders; -/** - * Flag that indicates if an error has occurred. +/* + * Parsing state. */ -private boolean error; - - -private final Set allowedTrailerHeaders; +private volatile ParseState parseState = ParseState.CHUNK_HEADER; +private volatile boolean crFound = false; +private volatile int chunkSizeDigitsRead = 0; +private volatile boolean parsingExtension = false; +private volatile long extensionSize; +private final HttpHeaderParser httpHeaderParser; // --- Constructors -public ChunkedInputFilter(int maxTrailerSize, Set allowedTrailerHeaders, +public ChunkedI