import org.apache.coyote.http11.InputFilter;\r
\r
/**\r
- * Chunked input filter.\r
+ * Chunked input filter. Parses chunked data according to\r
+ * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1">http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1</a><br>\r
* \r
* @author Remy Maucherat\r
+ * @author Filip Hanik\r
*/\r
public class ChunkedInputFilter implements InputFilter {\r
\r
\r
if (remaining <= 0) {\r
if (!parseChunkHeader()) {\r
- throw new IOException("Invalid chunk");\r
+ throw new IOException("Invalid chunk header");\r
}\r
if (endChunk) {\r
parseEndChunk();\r
\r
/**\r
* Parse the header of a chunk.\r
+ * A chunk header can look like \r
+ * A10CRLF\r
+ * F23;chunk-extension to be ignoredCRLF\r
+ * The letters before CRLF but after the trailer mark, must be valid hex digits, \r
+ * we should not parse F23IAMGONNAMESSTHISUP34CRLF as a valid header\r
+ * according to spec\r
*/\r
protected boolean parseChunkHeader()\r
throws IOException {\r
int result = 0;\r
boolean eol = false;\r
boolean readDigit = false;\r
+ boolean trailer = false;\r
\r
while (!eol) {\r
\r
if (buf[pos] == Constants.CR) {\r
} else if (buf[pos] == Constants.LF) {\r
eol = true;\r
- } else {\r
+ } else if (buf[pos] == Constants.SEMI_COLON) {\r
+ trailer = true;\r
+ } else if (!trailer) { \r
+ //don't read data after the trailer\r
if (HexUtils.DEC[buf[pos]] != -1) {\r
readDigit = true;\r
result *= 16;\r
result += HexUtils.DEC[buf[pos]];\r
+ } else {\r
+ //we shouldn't allow invalid, non hex characters\r
+ //in the chunked header\r
+ return false;\r
}\r
}\r
\r