Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=37794
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 16 Jun 2009 20:30:43 +0000 (20:30 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Tue, 16 Jun 2009 20:30:43 +0000 (20:30 +0000)
Handle chunked POSTs. If maxPostSize is exceeded, a 500 results.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@785381 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/connector/LocalStrings.properties
java/org/apache/catalina/connector/Request.java

index 039d030..f9b7996 100644 (file)
@@ -59,6 +59,7 @@ coyoteRequest.listenerStop=Exception sending context destroyed event to listener
 coyoteRequest.attributeEvent=Exception thrown by attributes event listener
 coyoteRequest.parseParameters=Exception thrown whilst processing POSTed parameters
 coyoteRequest.postTooLarge=Parameters were not parsed because the size of the posted data was too big. Use the maxPostSize attribute of the connector to resolve this if the application should accept large POSTs.
+coyoteRequest.chunkedPostTooLarge=Parameters were not parsed because the size of the posted data was too big. Because this request was a chunked request, it could not be processed further. Use the maxPostSize attribute of the connector to resolve this if the application should accept large POSTs.
 
 requestFacade.nullRequest=The request object has been recycled and is no longer associated with this facade
 
index f8dba58..d6bc695 100644 (file)
@@ -56,6 +56,7 @@ import javax.servlet.http.HttpSession;
 import javax.servlet.http.Part;
 
 import org.apache.tomcat.util.buf.B2CConverter;
+import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.buf.StringCache;
 import org.apache.tomcat.util.http.Cookies;
@@ -2497,7 +2498,8 @@ public class Request
             int maxPostSize = connector.getMaxPostSize();
             if ((maxPostSize > 0) && (len > maxPostSize)) {
                 if (context.getLogger().isDebugEnabled()) {
-                    context.getLogger().debug("Post too large");
+                    context.getLogger().debug(
+                            sm.getString("coyoteRequest.postTooLarge"));
                 }
                 return;
             }
@@ -2522,6 +2524,20 @@ public class Request
                 return;
             }
             parameters.processParameters(formData, 0, len);
+        } else if ("chunked".equals(
+                coyoteRequest.getHeader("transfer-encoding"))) {
+            byte[] formData = null;
+            try {
+                formData = readChunkedPostBody();
+            } catch (IOException e) {
+                // Client disconnect
+                if (context.getLogger().isDebugEnabled()) {
+                    context.getLogger().debug(
+                            sm.getString("coyoteRequest.parseParameters"), e);
+                }
+                return;
+            }
+            parameters.processParameters(formData, 0, formData.length);
         }
 
     }
@@ -2547,6 +2563,38 @@ public class Request
 
 
     /**
+     * Read chunked post body.
+     */
+    protected byte[] readChunkedPostBody() throws IOException {
+        ByteChunk body = new ByteChunk();
+        
+        byte[] buffer = new byte[CACHED_POST_LEN];
+        
+        int len = 0;
+        while (len > -1) {
+            len = getStream().read(buffer, 0, CACHED_POST_LEN);
+            if (connector.getMaxPostSize() > 0 &&
+                    (body.getLength() + len) > connector.getMaxPostSize()) {
+                // Too much data
+                throw new IllegalArgumentException(
+                        sm.getString("coyoteRequest.chunkedPostTooLarge"));
+            }
+            if (len > 0) {
+                body.append(buffer, 0, len);
+            }
+        }
+        if (body.getLength() < body.getBuffer().length) {
+            int length = body.getLength();
+            byte[] result = new byte[length];
+            System.arraycopy(body.getBuffer(), 0, result, 0, length);
+            return result;
+        } else {
+            return body.getBuffer();
+        }
+    }
+    
+    
+    /**
      * Parse request locales.
      */
     protected void parseLocales() {