You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by kk...@apache.org on 2011/11/10 09:44:04 UTC

svn commit: r1200218 - in /tomcat/tc7.0.x/trunk: ./ conf/ java/org/apache/catalina/ java/org/apache/catalina/connector/ java/org/apache/catalina/filters/ java/org/apache/tomcat/util/http/ webapps/docs/ webapps/docs/config/

Author: kkolinko
Date: Thu Nov 10 08:44:03 2011
New Revision: 1200218

URL: http://svn.apache.org/viewvc?rev=1200218&view=rev
Log:
Merged revisions r1198696 r1198707 r1200056 r1200107 from tomcat/trunk:
- Introduce new request attribute to be used to mark request if there was a failure during parameter parsing,
- Implement FailedRequestFilter - a filter that triggers parameter parsing and rejects requests marked with that attribute.
- Add sample configuration for FailedRequestFilter to conf/web.xml.

Added:
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java
      - copied, changed from r1198696, tomcat/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java
Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/conf/web.xml
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java
    tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java
    tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/Parameters.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
    tomcat/tc7.0.x/trunk/webapps/docs/config/filter.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Nov 10 08:44:03 2011
@@ -1 +1 @@
-/tomcat/trunk:1156115,1156171,1156276,1156304,1156519,1156530,1156602,1157015,1157018,1157151,1157198,1157204,1157810,1157832,1157834,1157847,1157908,1157939,1158155,1158160,1158176,1158195,1158198-1158199,1158227,1158331,1158334-1158335,1158426,1160347,1160592,1160611,1160619,1160626,1160639,1160652,1160720-1160721,1160772,1160774,1160776,1161303,1161310,1161322,1161339,1161486,1161540,1161549,1161584,1162082,1162149,1162169,1162721,1162769,1162836,1162932,1163630,1164419,1164438,1164469,1164480,1164567,1165234,1165247-1165248,1165253,1165273,1165282,1165309,1165331,1165338,1165347,1165360-1165361,1165367-1165368,1165602,1165608,1165677,1165693,1165721,1165723,1165728,1165730,1165738,1165746,1165765,1165777,1165918,1165921,1166077,1166150-1166151,1166290,1166366,1166620,1166686,1166693,1166752,1166757,1167368,1167394,1169447,1170647,1171692,1172233-1172234,1172236,1172269,1172278,1172282,1172556,1172610,1172664,1172689,1172711,1173020-1173021,1173082,1173088,1173090,1173096
 ,1173241,1173256,1173288,1173333,1173342,1173461,1173614,1173630,1173659,1173722,1174061,1174239,1174322,1174325,1174329-1174330,1174337-1174339,1174343,1174353,1174799,1174882,1174884,1174983,1175155,1175158,1175167,1175182,1175190,1175201,1175272,1175275,1175283,1175582,1175589-1175590,1175594,1175602,1175613,1175633,1175690,1175713,1175798,1175889,1175896,1175907,1176584,1176590,1176799,1177050,1177060,1177125,1177152,1177160,1177245,1177850,1177862,1177978,1178209,1178228,1178233,1178449,1178542,1178681,1178684,1178721,1179268,1179274,1180261,1180865,1180891,1180894,1180907,1181028,1181123,1181125,1181136,1181291,1181743,1182796,1183078,1183105,1183142,1183328,1183339-1183340,1183492-1183494,1183605,1184917,1184919,1185018,1185020,1185200,1185588,1185626,1185756,1185758,1186011,1186042-1186045,1186104,1186123,1186137,1186153,1186254,1186257,1186377-1186379,1186479-1186480,1186712,1186743,1186750,1186763,1186890-1186892,1186894,1186949,1187018,1187027-1187028,1187381,1187
 753,1187755,1187775,1187801,1187806,1187809,1187827,1188301,1188303-1188305,1188399,1188822,1188930-1188931,1189116,1189129,1189183,1189240,1189256,1189386,1189413-1189414,1189477,1189685,1189805,1189857,1189864,1189882,1190034,1190185,1190279,1190339,1190371,1190388-1190389,1190474,1190481,1194915,1195222-1195223,1195531,1195899,1195905,1195943,1195949,1195953,1195955,1195965,1195968,1196175,1196212,1196223,1196304-1196305,1196735,1196825,1196827,1197158,1197261,1197263,1197299-1197300,1197305,1197339-1197340,1197343,1197382,1197386-1197387,1197480,1197578,1198497,1198528,1198552,1198602,1198604,1198607,1198622,1198640,1199418,1199432,1199436,1199513,1199529,1199980,1199996,1200106
+/tomcat/trunk:1156115,1156171,1156276,1156304,1156519,1156530,1156602,1157015,1157018,1157151,1157198,1157204,1157810,1157832,1157834,1157847,1157908,1157939,1158155,1158160,1158176,1158195,1158198-1158199,1158227,1158331,1158334-1158335,1158426,1160347,1160592,1160611,1160619,1160626,1160639,1160652,1160720-1160721,1160772,1160774,1160776,1161303,1161310,1161322,1161339,1161486,1161540,1161549,1161584,1162082,1162149,1162169,1162721,1162769,1162836,1162932,1163630,1164419,1164438,1164469,1164480,1164567,1165234,1165247-1165248,1165253,1165273,1165282,1165309,1165331,1165338,1165347,1165360-1165361,1165367-1165368,1165602,1165608,1165677,1165693,1165721,1165723,1165728,1165730,1165738,1165746,1165765,1165777,1165918,1165921,1166077,1166150-1166151,1166290,1166366,1166620,1166686,1166693,1166752,1166757,1167368,1167394,1169447,1170647,1171692,1172233-1172234,1172236,1172269,1172278,1172282,1172556,1172610,1172664,1172689,1172711,1173020-1173021,1173082,1173088,1173090,1173096
 ,1173241,1173256,1173288,1173333,1173342,1173461,1173614,1173630,1173659,1173722,1174061,1174239,1174322,1174325,1174329-1174330,1174337-1174339,1174343,1174353,1174799,1174882,1174884,1174983,1175155,1175158,1175167,1175182,1175190,1175201,1175272,1175275,1175283,1175582,1175589-1175590,1175594,1175602,1175613,1175633,1175690,1175713,1175798,1175889,1175896,1175907,1176584,1176590,1176799,1177050,1177060,1177125,1177152,1177160,1177245,1177850,1177862,1177978,1178209,1178228,1178233,1178449,1178542,1178681,1178684,1178721,1179268,1179274,1180261,1180865,1180891,1180894,1180907,1181028,1181123,1181125,1181136,1181291,1181743,1182796,1183078,1183105,1183142,1183328,1183339-1183340,1183492-1183494,1183605,1184917,1184919,1185018,1185020,1185200,1185588,1185626,1185756,1185758,1186011,1186042-1186045,1186104,1186123,1186137,1186153,1186254,1186257,1186377-1186379,1186479-1186480,1186712,1186743,1186750,1186763,1186890-1186892,1186894,1186949,1187018,1187027-1187028,1187381,1187
 753,1187755,1187775,1187801,1187806,1187809,1187827,1188301,1188303-1188305,1188399,1188822,1188930-1188931,1189116,1189129,1189183,1189240,1189256,1189386,1189413-1189414,1189477,1189685,1189805,1189857,1189864,1189882,1190034,1190185,1190279,1190339,1190371,1190388-1190389,1190474,1190481,1194915,1195222-1195223,1195531,1195899,1195905,1195943,1195949,1195953,1195955,1195965,1195968,1196175,1196212,1196223,1196304-1196305,1196735,1196825,1196827,1197158,1197261,1197263,1197299-1197300,1197305,1197339-1197340,1197343,1197382,1197386-1197387,1197480,1197578,1198497,1198528,1198552,1198602,1198604,1198607,1198622,1198640,1198696,1198707,1199418,1199432,1199436,1199513,1199529,1199980,1199996,1200056,1200106-1200107

Modified: tomcat/tc7.0.x/trunk/conf/web.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/conf/web.xml?rev=1200218&r1=1200217&r2=1200218&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/conf/web.xml (original)
+++ tomcat/tc7.0.x/trunk/conf/web.xml Thu Nov 10 08:44:03 2011
@@ -388,6 +388,20 @@
 
   <!-- ================== Built In Filter Definitions ===================== -->
 
+  <!-- A filter that triggers request parameters parsing and rejects the    -->
+  <!-- request if some parameters were skipped because of parsing errors or -->
+  <!-- request size limitations.                                            -->
+<!--
+    <filter>
+        <filter-name>failedRequestFilter</filter-name>
+        <filter-class>
+          org.apache.catalina.filters.FailedRequestFilter
+        </filter-class>
+        <async-supported>true</async-supported>
+    </filter>
+-->
+
+
   <!-- NOTE: An SSI Servlet is also available as an alternative SSI         -->
   <!-- implementation. Use either the Servlet or the Filter but NOT both.   -->
   <!--                                                                      -->
@@ -448,6 +462,14 @@
 
   <!-- ==================== Built In Filter Mappings ====================== -->
 
+  <!-- The mapping for the Failed Request Filter -->
+<!--
+    <filter-mapping>
+        <filter-name>failedRequestFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+-->
+
   <!-- The mapping for the SSI Filter -->
 <!--
     <filter-mapping>

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java?rev=1200218&r1=1200217&r2=1200218&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/Globals.java Thu Nov 10 08:44:03 2011
@@ -162,6 +162,17 @@ public final class Globals {
 
 
     /**
+     * The request attribute that is set to {@code Boolean.TRUE} if some request
+     * parameters have been ignored during request parameters parsing. It can
+     * happen, for example, if there is a limit on the total count of parseable
+     * parameters, or if parameter cannot be decoded, or any other error
+     * happened during parameter parsing.
+     */
+    public static final String PARAMETER_PARSE_FAILED_ATTR =
+        "org.apache.catalina.parameter_parse_failed";
+
+
+    /**
      * The master flag which controls strict servlet specification
      * compliance.
      */

Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java?rev=1200218&r1=1200217&r2=1200218&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java Thu Nov 10 08:44:03 2011
@@ -947,6 +947,13 @@ public class Request
             return null;
         }
 
+        if (name.equals(Globals.PARAMETER_PARSE_FAILED_ATTR)) {
+            if (coyoteRequest.getParameters().isParseFailed()) {
+                return Boolean.TRUE;
+            }
+            return null;
+        }
+
         Object attr=attributes.get(name);
 
         if(attr!=null) {
@@ -1018,6 +1025,7 @@ public class Request
      * <li>{@link Globals#SSL_SESSION_ID_TOMCAT_ATTR} (SSL connections only)
      * </li>
      * <li>{@link Globals#SSL_SESSION_MGR_ATTR} (SSL connections only)</li>
+     * <li>{@link Globals#PARAMETER_PARSE_FAILED_ATTR}</li>
      * </ul>
      * The underlying connector may also expose request attributes. These all
      * have names starting with "org.apache.tomcat" and include:
@@ -2684,109 +2692,116 @@ public class Request
 
         Parameters parameters = coyoteRequest.getParameters();
 
-        File location;
-        String locationStr = mce.getLocation();
-        if (locationStr == null || locationStr.length() == 0) {
-            location = ((File) context.getServletContext().getAttribute(
-                    ServletContext.TEMPDIR));
-        } else {
-            location = new File(locationStr);
-        }
-
-        if (!location.isAbsolute() || !location.isDirectory()) {
-            partsParseException = new IOException(
-                    sm.getString("coyoteRequest.uploadLocationInvalid",
-                            location));
-            return;
-        }
-
-        // Create a new file upload handler
-        DiskFileItemFactory factory = new DiskFileItemFactory();
+        boolean success = false;
         try {
-            factory.setRepository(location.getCanonicalFile());
-        } catch (IOException ioe) {
-            partsParseException = ioe;
-            return;
-        }
-        factory.setSizeThreshold(mce.getFileSizeThreshold());
+            File location;
+            String locationStr = mce.getLocation();
+            if (locationStr == null || locationStr.length() == 0) {
+                location = ((File) context.getServletContext().getAttribute(
+                        ServletContext.TEMPDIR));
+            } else {
+                location = new File(locationStr);
+            }
 
-        ServletFileUpload upload = new ServletFileUpload();
-        upload.setFileItemFactory(factory);
-        upload.setFileSizeMax(mce.getMaxFileSize());
-        upload.setSizeMax(mce.getMaxRequestSize());
+            if (!location.isAbsolute() || !location.isDirectory()) {
+                partsParseException = new IOException(
+                        sm.getString("coyoteRequest.uploadLocationInvalid",
+                                location));
+                return;
+            }
 
-        parts = new ArrayList<Part>();
-        try {
-            List<FileItem> items = upload.parseRequest(this);
-            int maxPostSize = getConnector().getMaxPostSize();
-            int postSize = 0;
-            String enc = getCharacterEncoding();
-            Charset charset = null;
-            if (enc != null) {
-                try {
-                    charset = B2CConverter.getCharset(enc);
-                } catch (UnsupportedEncodingException e) {
-                    // Ignore
-                }
+
+            // Create a new file upload handler
+            DiskFileItemFactory factory = new DiskFileItemFactory();
+            try {
+                factory.setRepository(location.getCanonicalFile());
+            } catch (IOException ioe) {
+                partsParseException = ioe;
+                return;
             }
-            for (FileItem item : items) {
-                ApplicationPart part = new ApplicationPart(item, mce);
-                parts.add(part);
-                if (part.getFilename() == null) {
-                    String name = part.getName();
-                    String value = null;
+            factory.setSizeThreshold(mce.getFileSizeThreshold());
+
+            ServletFileUpload upload = new ServletFileUpload();
+            upload.setFileItemFactory(factory);
+            upload.setFileSizeMax(mce.getMaxFileSize());
+            upload.setSizeMax(mce.getMaxRequestSize());
+
+            parts = new ArrayList<Part>();
+            try {
+                List<FileItem> items = upload.parseRequest(this);
+                int maxPostSize = getConnector().getMaxPostSize();
+                int postSize = 0;
+                String enc = getCharacterEncoding();
+                Charset charset = null;
+                if (enc != null) {
                     try {
-                        String encoding = parameters.getEncoding();
-                        if (encoding == null) {
-                            encoding = Parameters.DEFAULT_ENCODING;
-                        }
-                        value = part.getString(encoding);
-                    } catch (UnsupportedEncodingException uee) {
-                        try {
-                            value = part.getString(Parameters.DEFAULT_ENCODING);
-                        } catch (UnsupportedEncodingException e) {
-                            // Should not be possible
-                        }
+                        charset = B2CConverter.getCharset(enc);
+                    } catch (UnsupportedEncodingException e) {
+                        // Ignore
                     }
-                    if (maxPostSize > 0) {
-                        // Have to calculate equivalent size. Not completely
-                        // accurate but close enough.
-                        if (charset == null) {
-                            // Name length
-                            postSize += name.getBytes().length;
-                        } else {
-                            postSize += name.getBytes(charset).length;
+                }
+                for (FileItem item : items) {
+                    ApplicationPart part = new ApplicationPart(item, mce);
+                    parts.add(part);
+                    if (part.getFilename() == null) {
+                        String name = part.getName();
+                        String value = null;
+                        try {
+                            String encoding = parameters.getEncoding();
+                            if (encoding == null) {
+                                encoding = Parameters.DEFAULT_ENCODING;
+                            }
+                            value = part.getString(encoding);
+                        } catch (UnsupportedEncodingException uee) {
+                            try {
+                                value = part.getString(Parameters.DEFAULT_ENCODING);
+                            } catch (UnsupportedEncodingException e) {
+                                // Should not be possible
+                            }
                         }
-                        if (value != null) {
-                            // Equals sign
+                        if (maxPostSize > 0) {
+                            // Have to calculate equivalent size. Not completely
+                            // accurate but close enough.
+                            if (charset == null) {
+                                // Name length
+                                postSize += name.getBytes().length;
+                            } else {
+                                postSize += name.getBytes(charset).length;
+                            }
+                            if (value != null) {
+                                // Equals sign
+                                postSize++;
+                                // Value length
+                                postSize += part.getSize();
+                            }
+                            // Value separator
                             postSize++;
-                            // Value length
-                            postSize += part.getSize();
-                        }
-                        // Value separator
-                        postSize++;
-                        if (postSize > maxPostSize) {
-                            throw new IllegalStateException(sm.getString(
-                                    "coyoteRequest.maxPostSizeExceeded"));
+                            if (postSize > maxPostSize) {
+                                throw new IllegalStateException(sm.getString(
+                                        "coyoteRequest.maxPostSizeExceeded"));
+                            }
                         }
+                        parameters.addParameter(name, value);
                     }
-                    parameters.addParameter(name, value);
                 }
-            }
 
-        } catch (InvalidContentTypeException e) {
-            partsParseException = new ServletException(e);
-        } catch (FileUploadBase.SizeException e) {
-            checkSwallowInput();
-            partsParseException = new IllegalStateException(e);
-        } catch (FileUploadException e) {
-            partsParseException = new IOException(e);
-        } catch (IllegalStateException e) {
-            checkSwallowInput();
-            partsParseException = e;
+                success = true;
+            } catch (InvalidContentTypeException e) {
+                partsParseException = new ServletException(e);
+            } catch (FileUploadBase.SizeException e) {
+                checkSwallowInput();
+                partsParseException = new IllegalStateException(e);
+            } catch (FileUploadException e) {
+                partsParseException = new IOException(e);
+            } catch (IllegalStateException e) {
+                checkSwallowInput();
+                partsParseException = e;
+            }
+        } finally {
+            if (partsParseException != null || !success) {
+                parameters.setParseFailed(true);
+            }
         }
-
-        return;
     }
 
 
@@ -2971,107 +2986,119 @@ public class Request
         parametersParsed = true;
 
         Parameters parameters = coyoteRequest.getParameters();
-        // Set this every time in case limit has been changed via JMX
-        parameters.setLimit(getConnector().getMaxParameterCount());
+        boolean success = false;
+        try {
+            // Set this every time in case limit has been changed via JMX
+            parameters.setLimit(getConnector().getMaxParameterCount());
 
-        // getCharacterEncoding() may have been overridden to search for
-        // hidden form field containing request encoding
-        String enc = getCharacterEncoding();
-
-        boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
-        if (enc != null) {
-            parameters.setEncoding(enc);
-            if (useBodyEncodingForURI) {
-                parameters.setQueryStringEncoding(enc);
-            }
-        } else {
-            parameters.setEncoding
-                (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
-            if (useBodyEncodingForURI) {
-                parameters.setQueryStringEncoding
+            // getCharacterEncoding() may have been overridden to search for
+            // hidden form field containing request encoding
+            String enc = getCharacterEncoding();
+
+            boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI();
+            if (enc != null) {
+                parameters.setEncoding(enc);
+                if (useBodyEncodingForURI) {
+                    parameters.setQueryStringEncoding(enc);
+                }
+            } else {
+                parameters.setEncoding
                     (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
+                if (useBodyEncodingForURI) {
+                    parameters.setQueryStringEncoding
+                        (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING);
+                }
             }
-        }
 
-        parameters.handleQueryParameters();
+            parameters.handleQueryParameters();
 
-        if (usingInputStream || usingReader) {
-            return;
-        }
+            if (usingInputStream || usingReader) {
+                success = true;
+                return;
+            }
 
-        if( !getConnector().isParseBodyMethod(getMethod()) ) {
-            return;
-        }
+            if( !getConnector().isParseBodyMethod(getMethod()) ) {
+                success = true;
+                return;
+            }
 
-        String contentType = getContentType();
-        if (contentType == null) {
-            contentType = "";
-        }
-        int semicolon = contentType.indexOf(';');
-        if (semicolon >= 0) {
-            contentType = contentType.substring(0, semicolon).trim();
-        } else {
-            contentType = contentType.trim();
-        }
+            String contentType = getContentType();
+            if (contentType == null) {
+                contentType = "";
+            }
+            int semicolon = contentType.indexOf(';');
+            if (semicolon >= 0) {
+                contentType = contentType.substring(0, semicolon).trim();
+            } else {
+                contentType = contentType.trim();
+            }
 
-        if ("multipart/form-data".equals(contentType)) {
-            parseParts();
-            return;
-        }
+            if ("multipart/form-data".equals(contentType)) {
+                parseParts();
+                success = true;
+                return;
+            }
 
-        if (!("application/x-www-form-urlencoded".equals(contentType))) {
-            return;
-        }
+            if (!("application/x-www-form-urlencoded".equals(contentType))) {
+                success = true;
+                return;
+            }
 
-        int len = getContentLength();
+            int len = getContentLength();
 
-        if (len > 0) {
-            int maxPostSize = connector.getMaxPostSize();
-            if ((maxPostSize > 0) && (len > maxPostSize)) {
-                if (context.getLogger().isDebugEnabled()) {
-                    context.getLogger().debug(
-                            sm.getString("coyoteRequest.postTooLarge"));
+            if (len > 0) {
+                int maxPostSize = connector.getMaxPostSize();
+                if ((maxPostSize > 0) && (len > maxPostSize)) {
+                    if (context.getLogger().isDebugEnabled()) {
+                        context.getLogger().debug(
+                                sm.getString("coyoteRequest.postTooLarge"));
+                    }
+                    checkSwallowInput();
+                    return;
                 }
-                checkSwallowInput();
-                return;
-            }
-            byte[] formData = null;
-            if (len < CACHED_POST_LEN) {
-                if (postData == null) {
-                    postData = new byte[CACHED_POST_LEN];
+                byte[] formData = null;
+                if (len < CACHED_POST_LEN) {
+                    if (postData == null) {
+                        postData = new byte[CACHED_POST_LEN];
+                    }
+                    formData = postData;
+                } else {
+                    formData = new byte[len];
                 }
-                formData = postData;
-            } else {
-                formData = new byte[len];
-            }
-            try {
-                if (readPostBody(formData, len) != len) {
+                try {
+                    if (readPostBody(formData, len) != len) {
+                        return;
+                    }
+                } catch (IOException e) {
+                    // Client disconnect
+                    if (context.getLogger().isDebugEnabled()) {
+                        context.getLogger().debug(
+                                sm.getString("coyoteRequest.parseParameters"), e);
+                    }
                     return;
                 }
-            } catch (IOException e) {
-                // Client disconnect
-                if (context.getLogger().isDebugEnabled()) {
-                    context.getLogger().debug(
-                            sm.getString("coyoteRequest.parseParameters"), e);
+                parameters.processParameters(formData, 0, len);
+            } else if ("chunked".equalsIgnoreCase(
+                    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;
                 }
-                return;
-            }
-            parameters.processParameters(formData, 0, len);
-        } else if ("chunked".equalsIgnoreCase(
-                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);
+                if (formData != null) {
+                    parameters.processParameters(formData, 0, formData.length);
                 }
-                return;
             }
-            if (formData != null) {
-                parameters.processParameters(formData, 0, formData.length);
+            success = true;
+        } finally {
+            if (!success) {
+                parameters.setParseFailed(true);
             }
         }
 

Copied: tomcat/tc7.0.x/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java (from r1198696, tomcat/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java)
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java?p2=tomcat/tc7.0.x/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java&p1=tomcat/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java&r1=1198696&r2=1200218&rev=1200218&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/filters/FailedRequestFilter.java Thu Nov 10 08:44:03 2011
@@ -38,9 +38,10 @@ import org.apache.juli.logging.LogFactor
  *
  * <p>
  * Note that it has side effect that it triggers parameter parsing and thus
- * consumes the body for POST requests, so use it only with addresses that do not
- * use <code>request.getInputStream()</code> and
- * <code>request.getReader()</code>.
+ * consumes the body for POST requests. Parameter parsing does check content
+ * type of the request, so there should not be problems with addresses that use
+ * <code>request.getInputStream()</code> and <code>request.getReader()</code>,
+ * if requests parsed by them do not use standard value for content mime-type.
  */
 public class FailedRequestFilter extends FilterBase implements CometFilter {
 

Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/Parameters.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/Parameters.java?rev=1200218&r1=1200217&r2=1200218&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/Parameters.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/Parameters.java Thu Nov 10 08:44:03 2011
@@ -60,6 +60,12 @@ public final class Parameters {
     private int limit = -1;
     private int parameterCount = 0;
 
+    /**
+     * Is set to <code>true</code> if there were failures during parameter
+     * parsing.
+     */
+    private boolean parseFailed = false;
+
     public Parameters() {
         // NO-OP
     }
@@ -90,12 +96,21 @@ public final class Parameters {
         }
     }
 
+    public boolean isParseFailed() {
+        return parseFailed;
+    }
+
+    public void setParseFailed(boolean parseFailed) {
+        this.parseFailed = parseFailed;
+    }
+
     public void recycle() {
         parameterCount = 0;
         paramHashValues.clear();
         didQueryParameters=false;
         encoding=null;
         decodedQuery.recycle();
+        parseFailed = false;
     }
 
     // -------------------- Data access --------------------
@@ -186,6 +201,7 @@ public final class Parameters {
         if (limit > -1 && parameterCount > limit) {
             // Processing this parameter will push us over the limit. ISE is
             // what Request.parseParts() uses for requests that are too big
+            parseFailed = true;
             throw new IllegalStateException(sm.getString(
                     "parameters.maxCountFail", Integer.valueOf(limit)));
         }
@@ -314,6 +330,7 @@ public final class Parameters {
                                 null));
                     }
                 }
+                parseFailed = true;
                 continue;
                 // invalid chunk - it's better to ignore
             }
@@ -355,10 +372,12 @@ public final class Parameters {
                 } catch (IllegalStateException ise) {
                     // Hitting limit stops processing further params but does
                     // not cause request to fail.
+                    parseFailed = true;
                     log.warn(ise.getMessage());
                     break;
                 }
             } catch (IOException e) {
+                parseFailed = true;
                 decodeFailCount++;
                 if (decodeFailCount == 1 || log.isDebugEnabled()) {
                     if (log.isDebugEnabled()) {

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1200218&r1=1200217&r2=1200218&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Thu Nov 10 08:44:03 2011
@@ -163,7 +163,9 @@
       <add>
         Improve performance of parameter processing for GET and POST requests.
         Also add an option to limit the maximum number of parameters processed
-        per request. This defaults to 10000. (markt/kkolinko)
+        per request. This defaults to 10000. Excessive parameters are ignored.
+        Note that <code>FailedRequestFilter</code> can be used to reject the
+        request if some parameters were ignored. (markt/kkolinko)
       </add>
       <fix>
         <bug>52091</bug>: Address performance issues related to lock contention
@@ -189,6 +191,15 @@
         resource when path contains <code>/../</code> sequences or any other
         sequences that require normalization. (markt)
       </fix>
+      <add>
+        Report existence of HTTP request parameter parsing errors via new
+        special ServletRequest attribute,
+        <code>org.apache.catalina.parameter_parse_failed</code>. (kkolinko)
+      </add>
+      <add>
+        New filter <code>FailedRequestFilter</code> that will reject a request
+        if there were errors during HTTP parameter parsing. (kkolinko)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Coyote">

Modified: tomcat/tc7.0.x/trunk/webapps/docs/config/filter.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/config/filter.xml?rev=1200218&r1=1200217&r2=1200218&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/config/filter.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/config/filter.xml Thu Nov 10 08:44:03 2011
@@ -1207,6 +1207,44 @@ org.apache.catalina.filters.RequestDumpe
 </section>
 
 
+<section name="Failed Request Filter">
+
+  <subsection name="Introduction">
+
+    <p>This filter triggers parameters parsing in a request and rejects the
+    request if some parameters were skipped during parameter parsing because
+    of parsing errors or request size limitations (such as
+    <code>maxParameterCount</code> attribute in a
+    <a href="http.html">Connector</a>).
+    This filter can be used to ensure that none parameter values submitted by
+    client are lost.</p>
+
+    <p>Note that parameter parsing may consume the body of an HTTP request, so
+    caution is needed if the servlet protected by this filter uses
+    <code>request.getInputStream()</code> or <code>request.getReader()</code>
+    calls. In general the risk of breaking a web application by adding this
+    filter is not so high, because parameter parsing does check content type
+    of the request before consuming the request body.</p>
+
+  </subsection>
+
+  <subsection name="Filter Class Name">
+
+    <p>The filter class name for the Failed Request Filter is
+    <strong><code>org.apache.catalina.filters.FailedRequestFilter</code>
+    </strong>.</p>
+
+  </subsection>
+
+  <subsection name="Initialisation parameters">
+
+    <p>The Failed Request Filter does not support any initialization parameters.</p>
+
+  </subsection>
+
+</section>
+
+
 </body>
 
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org