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 2014/06/18 22:55:20 UTC

svn commit: r1603628 - in /tomcat/tc6.0.x/trunk: ./ STATUS.txt java/org/apache/coyote/http11/filters/ChunkedInputFilter.java java/org/apache/coyote/http11/filters/LocalStrings.properties webapps/docs/changelog.xml

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org