Author: markt Date: Wed Jun 18 20:55:20 2014 New Revision: 1603628 URL: http://svn.apache.org/r1603628 Log: Improvements to ChunkedInputFilter - Clean-up - i18n for ChunkedInputFilter error message - Add error flag to allow subsequent attempts at reading after an error to fail fast
Added: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/LocalStrings.properties - copied unchanged from r1601333, tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/filters/LocalStrings.properties Modified: tomcat/tc6.0.x/trunk/ (props changed) tomcat/tc6.0.x/trunk/STATUS.txt tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Propchange: tomcat/tc6.0.x/trunk/ ------------------------------------------------------------------------------ Merged /tomcat/trunk:r1600963,1600978,1600984,1601329-1601330,1601332 Merged /tomcat/tc7.0.x/trunk:r1601333 Modified: tomcat/tc6.0.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1603628&r1=1603627&r2=1603628&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/STATUS.txt (original) +++ tomcat/tc6.0.x/trunk/STATUS.txt Wed Jun 18 20:55:20 2014 @@ -28,15 +28,6 @@ None PATCHES PROPOSED TO BACKPORT: [ New proposals should be added at the end of the list ] -* Improvements to ChunkedInputFilter - - Clean-up - - i18n for ChunkedInputFilter error message - - Add error flag to allow subsequent attempts at reading after an error to - fail fast - http://people.apache.org/~markt/patches/2014-06-09-chunked-input-filter-tc6-v1.patch - +1: markt, kkolinko, schultz - -1: - * Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56606 User new attribute name for username http://people.apache.org/~markt/patches/2014-06-10-user-username-tc6-v1.patch Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java?rev=1603628&r1=1603627&r2=1603628&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java Wed Jun 18 20:55:20 2014 @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.coyote.http11.filters; import java.io.EOFException; @@ -29,6 +28,7 @@ import org.apache.coyote.http11.Constant import org.apache.coyote.http11.InputFilter; import org.apache.tomcat.util.buf.MessageBytes; import org.apache.tomcat.util.http.MimeHeaders; +import org.apache.tomcat.util.res.StringManager; /** * Chunked input filter. Parses chunked data according to @@ -39,9 +39,11 @@ import org.apache.tomcat.util.http.MimeH */ public class ChunkedInputFilter implements InputFilter { + private static final StringManager sm = StringManager.getManager( + ChunkedInputFilter.class.getPackage().getName()); - // -------------------------------------------------------------- Constants + // -------------------------------------------------------------- Constants protected static final String ENCODING_NAME = "chunked"; protected static final ByteChunk ENCODING = new ByteChunk(); @@ -49,7 +51,6 @@ public class ChunkedInputFilter implemen // ----------------------------------------------------- Static Initializer - static { ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length()); } @@ -57,7 +58,6 @@ public class ChunkedInputFilter implemen // ----------------------------------------------------- Instance Variables - /** * Next buffer in the pipeline. */ @@ -120,6 +120,11 @@ public class ChunkedInputFilter implemen /** + * Flag that indicates if an error has occurred. + */ + private boolean error; + + /** * Flag set to true if the next call to doRead() must parse a CRLF pair * before doing anything else. */ @@ -130,13 +135,10 @@ public class ChunkedInputFilter implemen * Request being parsed. */ private Request request; - - // ------------------------------------------------------------- Properties // ---------------------------------------------------- InputBuffer Methods - /** * Read bytes. * @@ -146,11 +148,12 @@ public class ChunkedInputFilter implemen * whichever is greater. If the filter does not do request body length * control, the returned value should be -1. */ - public int doRead(ByteChunk chunk, Request req) - throws IOException { - - if (endChunk) + public int doRead(ByteChunk chunk, Request req) throws IOException { + if (endChunk) { return -1; + } + + checkError(); if(needCRLFParse) { needCRLFParse = false; @@ -159,7 +162,7 @@ public class ChunkedInputFilter implemen if (remaining <= 0) { if (!parseChunkHeader()) { - throw new IOException("Invalid chunk header"); + throwIOException(sm.getString("chunkedInputFilter.invalidHeader")); } if (endChunk) { parseEndChunk(); @@ -171,8 +174,7 @@ public class ChunkedInputFilter implemen if (pos >= lastValid) { if (readBytes() < 0) { - throw new IOException( - "Unexpected end of stream whilst reading request body"); + throwIOException(sm.getString("chunkedInputFilter.eos")); } } @@ -197,13 +199,11 @@ public class ChunkedInputFilter implemen } return result; - } // ---------------------------------------------------- InputFilter Methods - /** * Read the content length from the request. */ @@ -215,16 +215,13 @@ public class ChunkedInputFilter implemen /** * End the current request. */ - public long end() - throws IOException { - + public long end() throws IOException { // Consume extra bytes : parse the stream until the end chunk is found while (doRead(readChunk, null) >= 0) { } // Return the number of extra bytes which were consumed - return (lastValid - pos); - + return lastValid - pos; } @@ -232,7 +229,7 @@ public class ChunkedInputFilter implemen * Amount of bytes still available in a buffer. */ public int available() { - return (lastValid - pos); + return lastValid - pos; } @@ -258,6 +255,7 @@ public class ChunkedInputFilter implemen trailingHeaders.setLimit(org.apache.coyote.Constants.MAX_TRAILER_SIZE); } extensionSize = 0; + error = false; } @@ -272,12 +270,10 @@ public class ChunkedInputFilter implemen // ------------------------------------------------------ Protected Methods - /** * Read bytes from the previous buffer. */ - protected int readBytes() - throws IOException { + protected int readBytes() throws IOException { int nRead = buffer.doRead(readChunk, null); pos = readChunk.getStart(); @@ -285,7 +281,6 @@ public class ChunkedInputFilter implemen buf = readChunk.getBytes(); return nRead; - } @@ -298,8 +293,7 @@ public class ChunkedInputFilter implemen * we should not parse F23IAMGONNAMESSTHISUP34CRLF as a valid header * according to spec */ - protected boolean parseChunkHeader() - throws IOException { + protected boolean parseChunkHeader() throws IOException { int result = 0; boolean eol = false; @@ -340,7 +334,7 @@ public class ChunkedInputFilter implemen extensionSize++; if (org.apache.coyote.Constants.MAX_EXTENSION_SIZE > -1 && extensionSize > org.apache.coyote.Constants.MAX_EXTENSION_SIZE) { - throw new IOException("maxExtensionSize exceeded"); + throwIOException(sm.getString("chunkedInputFilter.maxExtension")); } } @@ -348,21 +342,22 @@ public class ChunkedInputFilter implemen if (!eol) { pos++; } - } - if (readDigit == 0 || result < 0) + if (readDigit == 0 || result < 0) { return false; + } - if (result == 0) + if (result == 0) { endChunk = true; + } remaining = result; - if (remaining < 0) + if (remaining < 0) { return false; + } return true; - } @@ -389,26 +384,27 @@ public class ChunkedInputFilter implemen boolean crfound = false; while (!eol) { - if (pos >= lastValid) { - if (readBytes() <= 0) - throw new IOException("Invalid CRLF"); + if (readBytes() <= 0) { + throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoData")); + } } if (buf[pos] == Constants.CR) { - if (crfound) throw new IOException("Invalid CRLF, two CR characters encountered."); + if (crfound) { + throwIOException(sm.getString("chunkedInputFilter.invalidCrlfCRCR")); + } crfound = true; } else if (buf[pos] == Constants.LF) { if (!tolerant && !crfound) { - throw new IOException("Invalid CRLF, no CR character encountered."); + throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoCR")); } eol = true; } else { - throw new IOException("Invalid CRLF"); + throwIOException(sm.getString("chunkedInputFilter.invalidCrlf")); } pos++; - } } @@ -417,7 +413,6 @@ public class ChunkedInputFilter implemen * Parse end chunk data. */ protected boolean parseEndChunk() throws IOException { - // Handle optional trailer headers while (parseHeader()) { // Loop until we run out of headers @@ -434,8 +429,9 @@ public class ChunkedInputFilter implemen // Read new bytes if needed if (pos >= lastValid) { - if (readBytes() <0) - throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); + if (readBytes() <0) { + throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } } chr = buf[pos]; @@ -459,8 +455,9 @@ public class ChunkedInputFilter implemen // Read new bytes if needed if (pos >= lastValid) { - if (readBytes() <0) - throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); + if (readBytes() <0) { + throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } } chr = buf[pos]; @@ -500,8 +497,9 @@ public class ChunkedInputFilter implemen // Read new bytes if needed if (pos >= lastValid) { - if (readBytes() <0) - throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); + if (readBytes() <0) { + throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } } chr = buf[pos]; @@ -512,7 +510,7 @@ public class ChunkedInputFilter implemen if (trailingHeaders.getLimit() != -1) { int newlimit = trailingHeaders.getLimit() -1; if (trailingHeaders.getEnd() > newlimit) { - throw new IOException("Exceeded maxTrailerSize"); + throwIOException(sm.getString("chunkedInputFilter.maxTrailer")); } trailingHeaders.setLimit(newlimit); } @@ -527,8 +525,9 @@ public class ChunkedInputFilter implemen // Read new bytes if needed if (pos >= lastValid) { - if (readBytes() <0) - throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); + if (readBytes() <0) { + throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } } chr = buf[pos]; @@ -552,8 +551,9 @@ public class ChunkedInputFilter implemen // Read new bytes if needed if (pos >= lastValid) { - if (readBytes() <0) - throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); + if (readBytes() <0) { + throwEOFException(sm.getString("chunkedInputFilter.eosTrailer")); + } } chr = buf[pos]; @@ -574,4 +574,23 @@ public class ChunkedInputFilter implemen return true; } + + + private void throwIOException(String msg) throws IOException { + error = true; + throw new IOException(msg); + } + + + private void throwEOFException(String msg) throws IOException { + error = true; + throw new EOFException(msg); + } + + + private void checkError() throws IOException { + if (error) { + throw new IOException(sm.getString("chunkedInputFilter.error")); + } + } } Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1603628&r1=1603627&r2=1603628&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Wed Jun 18 20:55:20 2014 @@ -52,6 +52,15 @@ </fix> </changelog> </subsection> + <subsection name="Coyote"> + <changelog> + <fix> + Various improvements to ChunkedInputFilter including clean-up, i18n for + error messages and adding an error flag to allow subsequent attempts at + reading after an error to fail fast. (markt) + </fix> + </changelog> + </subsection> <subsection name="Jasper"> <changelog> <fix> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org