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 2012/11/03 21:46:03 UTC
svn commit: r1405415 - in /tomcat/trunk: ./
java/org/apache/catalina/authenticator/ java/org/apache/catalina/connector/
java/org/apache/coyote/ java/org/apache/tomcat/util/http/parser/
test/org/apache/tomcat/util/http/parser/
Author: markt
Date: Sat Nov 3 20:46:02 2012
New Revision: 1405415
URL: http://svn.apache.org/viewvc?rev=1405415&view=rev
Log:
Move media-type parsing to the new parser and drop the JJTree based parser.
Added:
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
- copied, changed from r1405399, tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java
Removed:
tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstAttribute.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstSubType.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstType.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstValue.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParserConstants.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParserTokenManager.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParserTreeConstants.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/JJTHttpParserState.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/Node.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/ParseException.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/SimpleCharStream.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/SimpleNode.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/Token.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/TokenMgrError.java
Modified:
tomcat/trunk/build.xml
tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
tomcat/trunk/java/org/apache/catalina/connector/Response.java
tomcat/trunk/java/org/apache/coyote/Response.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaType.java
tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java
tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java
tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java
Modified: tomcat/trunk/build.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/build.xml?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/build.xml (original)
+++ tomcat/trunk/build.xml Sat Nov 3 20:46:02 2012
@@ -481,7 +481,6 @@
<!-- Exclude auto-generated files -->
<exclude name="java/org/apache/el/parser/ELParser*.java" />
<exclude name="java/org/apache/el/parser/Node.java" />
- <exclude name="java/org/apache/tomcat/util/http/parser/HttpParser*.java" />
<exclude name="java/org/apache/**/parser/JJT*ParserState.java" />
<exclude name="java/org/apache/**/parser/ParseException.java" />
<exclude name="java/org/apache/**/parser/SimpleCharStream.java" />
Modified: tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java Sat Nov 3 20:46:02 2012
@@ -35,7 +35,7 @@ import org.apache.catalina.util.MD5Encod
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.B2CConverter;
-import org.apache.tomcat.util.http.parser.HttpParser2;
+import org.apache.tomcat.util.http.parser.HttpParser;
/**
@@ -479,7 +479,7 @@ public class DigestAuthenticator extends
Map<String,String> directives;
try {
- directives = HttpParser2.parseAuthorizationDigest(
+ directives = HttpParser.parseAuthorizationDigest(
new StringReader(authorization));
} catch (IOException e) {
return false;
Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Sat Nov 3 20:46:02 2012
@@ -51,7 +51,6 @@ import org.apache.tomcat.util.http.FastH
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.ServerCookie;
import org.apache.tomcat.util.http.parser.MediaTypeCache;
-import org.apache.tomcat.util.http.parser.ParseException;
import org.apache.tomcat.util.net.URL;
import org.apache.tomcat.util.res.StringManager;
@@ -709,10 +708,8 @@ public class Response
return;
}
- String[] m = null;
- try {
- m = MEDIA_TYPE_CACHE.parse(type);
- } catch (ParseException e) {
+ String[] m = MEDIA_TYPE_CACHE.parse(type);
+ if (m == null) {
// Invalid - Assume no charset and just pass through whatever
// the user provided.
coyoteResponse.setContentTypeNoCharset(type);
Modified: tomcat/trunk/java/org/apache/coyote/Response.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/Response.java?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/Response.java (original)
+++ tomcat/trunk/java/org/apache/coyote/Response.java Sat Nov 3 20:46:02 2012
@@ -25,9 +25,8 @@ import javax.servlet.WriteListener;
import org.apache.coyote.http11.AbstractOutputBuffer;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.http.parser.AstMediaType;
import org.apache.tomcat.util.http.parser.HttpParser;
-import org.apache.tomcat.util.http.parser.ParseException;
+import org.apache.tomcat.util.http.parser.MediaType;
/**
* Response object.
@@ -434,11 +433,13 @@ public final class Response {
return;
}
- AstMediaType m = null;
- HttpParser hp = new HttpParser(new StringReader(type));
+ MediaType m = null;
try {
- m = hp.MediaType();
- } catch (ParseException e) {
+ m = HttpParser.parseMediaType(new StringReader(type));
+ } catch (IOException e) {
+ // Ignore - null test below handles this
+ }
+ if (m == null) {
// Invalid - Assume no charset and just pass through whatever
// the user provided.
this.contentType = type;
Copied: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java (from r1405399, tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java)
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java?p2=tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java&p1=tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java&r1=1405399&r2=1405415&rev=1405415&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java Sat Nov 3 20:46:02 2012
@@ -19,6 +19,7 @@ package org.apache.tomcat.util.http.pars
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
@@ -39,10 +40,8 @@ import java.util.Map;
* - MediaType (used for Content-Type header)
*
* Support for additional headers will be provided as required.
- *
- * TODO: Replace HttpParser
*/
-public class HttpParser2 {
+public class HttpParser {
private static final Integer FIELD_TYPE_TOKEN = Integer.valueOf(0);
private static final Integer FIELD_TYPE_QUOTED_STRING = Integer.valueOf(1);
@@ -113,18 +112,15 @@ public class HttpParser2 {
if (skipConstant(input, "Digest") != SkipConstantResult.FOUND) {
return null;
}
- skipLws(input);
// All field names are valid tokens
String field = readToken(input);
if (field == null) {
return null;
}
while (!field.equals("")) {
- skipLws(input);
if (skipConstant(input, "=") != SkipConstantResult.FOUND) {
return null;
}
- skipLws(input);
String value = null;
Integer type = fieldTypes.get(field.toLowerCase(Locale.US));
if (type == null) {
@@ -163,11 +159,9 @@ public class HttpParser2 {
}
result.put(field, value);
- skipLws(input);
if (skipConstant(input, ",") == SkipConstantResult.NOT_FOUND) {
return null;
}
- skipLws(input);
field = readToken(input);
if (field == null) {
return null;
@@ -186,11 +180,9 @@ public class HttpParser2 {
return null;
}
- skipLws(input);
if (skipConstant(input, "/") == SkipConstantResult.NOT_FOUND) {
return null;
}
- skipLws(input);
// Subtype (required)
String subtype = readToken(input);
@@ -198,60 +190,59 @@ public class HttpParser2 {
return null;
}
- skipLws(input);
-
- Map<String,String> parameters = new HashMap<>();
+ LinkedHashMap<String,String> parameters = new LinkedHashMap<>();
SkipConstantResult lookForSemiColon = skipConstant(input, ";");
if (lookForSemiColon == SkipConstantResult.NOT_FOUND) {
return null;
}
while (lookForSemiColon == SkipConstantResult.FOUND) {
- skipLws(input);
String attribute = readToken(input);
- skipLws(input);
- if (skipConstant(input, "=") != SkipConstantResult.FOUND) {
- return null;
+ if (skipConstant(input, "=") == SkipConstantResult.FOUND) {
+ String value = readTokenOrQuotedString(input, true);
+ parameters.put(attribute, value);
+ } else {
+ parameters.put(attribute, "");
}
- skipLws(input);
- String value = readTokenOrQuotedString(input, true);
- skipLws(input);
-
- parameters.put(attribute.toLowerCase(), value);
-
lookForSemiColon = skipConstant(input, ";");
if (lookForSemiColon == SkipConstantResult.NOT_FOUND) {
return null;
}
}
- String charset = parameters.remove("charset");
- StringBuilder noCharSet = new StringBuilder();
- noCharSet.append(type);
- noCharSet.append('/');
- noCharSet.append(subtype);
- for (Map.Entry<String, String> entry : parameters.entrySet()) {
- noCharSet.append(';');
- // Workaround for Adobe Read 9 plug-in on IE bug
- // Can be removed after 26 June 2013 (EOL of Reader 9)
- // See BZ 53814
- noCharSet.append(' ');
- noCharSet.append(entry.getKey());
- noCharSet.append('=');
- noCharSet.append(entry.getValue());
+ return new MediaType(type, subtype, parameters);
+ }
+
+ public static String unquote(String input) {
+ if (input == null || input.length() < 2 || input.charAt(0) != '"') {
+ return input;
}
- return new MediaType(noCharSet.toString(), charset);
+ StringBuilder result = new StringBuilder();
+ for (int i = 1 ; i < (input.length() - 1); i++) {
+ char c = input.charAt(i);
+ if (input.charAt(i) == '\\') {
+ i++;
+ result.append(input.charAt(i));
+ } else {
+ result.append(c);
+ }
+ }
+ return result.toString();
}
private static SkipConstantResult skipConstant(StringReader input,
String constant) throws IOException {
int len = constant.length();
+ int c = input.read();
+ while (c == 32 || c == 9) {
+ c = input.read();
+ }
+
for (int i = 0; i < len; i++) {
- int c = input.read();
if (i == 0 && c == -1) {
return SkipConstantResult.EOF;
}
@@ -259,20 +250,13 @@ public class HttpParser2 {
input.skip(-(i + 1));
return SkipConstantResult.NOT_FOUND;
}
+ if (i != (len - 1)) {
+ c = input.read();
+ }
}
return SkipConstantResult.FOUND;
}
- private static void skipLws(StringReader input) throws IOException {
- int c = input.read();
- while (c == 32 || c == 9) {
- c = input.read();
- }
-
- // Skip back so non-LWS character is available for next read
- input.skip(-1);
- }
-
/**
* @return the token if one was found, the empty string if no data was
* available to read or <code>null</code> if data other than a
@@ -282,6 +266,12 @@ public class HttpParser2 {
StringBuilder result = new StringBuilder();
int c = input.read();
+
+ // Skip lws
+ while (c == 32 || c == 9) {
+ c = input.read();
+ }
+
while (c != -1 && isToken[c]) {
result.append((char) c);
c = input.read();
@@ -305,6 +295,12 @@ public class HttpParser2 {
boolean returnQuoted) throws IOException {
int c = input.read();
+
+ // Skip lws
+ while (c == 32 || c == 9) {
+ c = input.read();
+ }
+
if (c != '"') {
return null;
}
@@ -314,6 +310,7 @@ public class HttpParser2 {
result.append('\"');
}
c = input.read();
+
while (c != '"') {
if (c == -1) {
return null;
@@ -337,8 +334,9 @@ public class HttpParser2 {
private static String readTokenOrQuotedString(StringReader input,
boolean returnQuoted) throws IOException {
+ input.mark(1);
int c = input.read();
- input.skip(-1);
+ input.reset();
if (c == '"') {
return readQuotedString(input, returnQuoted);
@@ -358,6 +356,12 @@ public class HttpParser2 {
StringBuilder result = new StringBuilder();
int c = input.read();
+
+ // Skip lws
+ while (c == 32 || c == 9) {
+ c = input.read();
+ }
+
while (c != -1 && isHex[c]) {
result.append((char) c);
c = input.read();
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaType.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaType.java?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaType.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaType.java Sat Nov 3 20:46:02 2012
@@ -16,21 +16,109 @@
*/
package org.apache.tomcat.util.http.parser;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
public class MediaType {
- private final String noCharset;
+ private final String type;
+ private final String subtype;
+ private final LinkedHashMap<String,String> parameters;
private final String charset;
+ private volatile String noCharset;
+ private volatile String withCharset;
+
+ protected MediaType(String type, String subtype,
+ LinkedHashMap<String,String> parameters) {
+ this.type = type;
+ this.subtype = subtype;
+ this.parameters = parameters;
- protected MediaType(String noCharset, String charset) {
- this.noCharset = noCharset;
- this.charset = charset;
+ String cs = parameters.get("charset");
+ if (cs != null && cs.length() > 0 &&
+ cs.charAt(0) == '"') {
+ cs = HttpParser.unquote(cs);
+ }
+ this.charset = cs;
}
- public String toStringNoCharset() {
- return noCharset;
+ public String getType() {
+ return type;
}
- public String getCharSet() {
+ public String getSubtype() {
+ return subtype;
+ }
+
+ public String getCharset() {
return charset;
}
+
+ public int getParameterCount() {
+ return parameters.size();
+ }
+
+ public String getParameterValue(String parameter) {
+ return parameters.get(parameter);
+ }
+
+ @Override
+ public String toString() {
+ if (withCharset == null) {
+ synchronized (this) {
+ if (withCharset == null) {
+ StringBuilder result = new StringBuilder();
+ result.append(type);
+ result.append('/');
+ result.append(subtype);
+ for (Map.Entry<String, String> entry : parameters.entrySet()) {
+ String value = entry.getValue();
+ if (value == null || value.length() == 0) {
+ continue;
+ }
+ result.append(';');
+ // Workaround for Adobe Read 9 plug-in on IE bug
+ // Can be removed after 26 June 2013 (EOL of Reader 9)
+ // See BZ 53814
+ result.append(' ');
+ result.append(entry.getKey());
+ result.append('=');
+ result.append(value);
+ }
+
+ withCharset = result.toString();
+ }
+ }
+ }
+ return withCharset;
+ }
+
+ public String toStringNoCharset() {
+ if (noCharset == null) {
+ synchronized (this) {
+ if (noCharset == null) {
+ StringBuilder result = new StringBuilder();
+ result.append(type);
+ result.append('/');
+ result.append(subtype);
+ for (Map.Entry<String, String> entry : parameters.entrySet()) {
+ if (entry.getKey().equalsIgnoreCase("charset")) {
+ continue;
+ }
+ result.append(';');
+ // Workaround for Adobe Read 9 plug-in on IE bug
+ // Can be removed after 26 June 2013 (EOL of Reader 9)
+ // See BZ 53814
+ result.append(' ');
+ result.append(entry.getKey());
+ result.append('=');
+ result.append(entry.getValue());
+ }
+
+ noCharset = result.toString();
+ }
+ }
+ }
+ return noCharset;
+ }
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java Sat Nov 3 20:46:02 2012
@@ -16,6 +16,7 @@
*/
package org.apache.tomcat.util.http.parser;
+import java.io.IOException;
import java.io.StringReader;
import org.apache.tomcat.util.collections.ConcurrentCache;
@@ -40,21 +41,24 @@ public class MediaTypeCache {
* @return The results are provided as a two element String array. The
* first element is the media type less the charset and
* the second element is the charset
- *
- * @throws ParseException if the input cannot be parsed
*/
- public String[] parse(String input) throws ParseException {
+ public String[] parse(String input) {
String[] result = cache.get(input);
if (result != null) {
return result;
}
- HttpParser hp = new HttpParser(new StringReader(input));
- AstMediaType m = hp.MediaType();
-
- result = new String[] {m.toStringNoCharset(), m.getCharset()};
- cache.put(input, result);
+ MediaType m = null;
+ try {
+ m = HttpParser.parseMediaType(new StringReader(input));
+ } catch (IOException e) {
+ // Ignore - return null
+ }
+ if (m != null) {
+ result = new String[] {m.toStringNoCharset(), m.getCharset()};
+ cache.put(input, result);
+ }
return result;
}
Modified: tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java Sat Nov 3 20:46:02 2012
@@ -38,7 +38,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertEquals("mthornton", result.get("username"));
Assert.assertEquals("optrak.com", result.get("realm"));
@@ -69,7 +69,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertEquals("mthornton", result.get("username"));
Assert.assertEquals("optrak.com", result.get("realm"));
@@ -93,7 +93,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertEquals("mthornton", result.get("username"));
Assert.assertEquals("auth", result.get("qop"));
@@ -107,7 +107,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertEquals("mthornton", result.get("username"));
Assert.assertEquals("auth", result.get("qop"));
@@ -120,7 +120,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertEquals("00000001", result.get("nc"));
}
@@ -131,7 +131,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertNull(result);
}
@@ -141,7 +141,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertNull(result);
}
@@ -151,7 +151,7 @@ public class TestAuthorizationDigest {
StringReader input = new StringReader(header);
- Map<String,String> result = HttpParser2.parseAuthorizationDigest(input);
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
Assert.assertNull(result);
}
Modified: tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java?rev=1405415&r1=1405414&r2=1405415&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java Sat Nov 3 20:46:02 2012
@@ -16,6 +16,7 @@
*/
package org.apache.tomcat.util.http.parser;
+import java.io.IOException;
import java.io.StringReader;
import static org.junit.Assert.assertEquals;
@@ -60,93 +61,90 @@ public class TestMediaType {
@Test
- public void testSimple() throws ParseException {
+ public void testSimple() throws IOException {
doTest();
}
@Test
- public void testSimpleWithToken() throws ParseException {
+ public void testSimpleWithToken() throws IOException {
doTest(PARAM_TOKEN);
}
@Test
- public void testSimpleWithQuotedString() throws ParseException {
+ public void testSimpleWithQuotedString() throws IOException {
doTest(PARAM_QUOTED);
}
@Test
- public void testSimpleWithEmptyQuotedString() throws ParseException {
+ public void testSimpleWithEmptyQuotedString() throws IOException {
doTest(PARAM_EMPTY_QUOTED);
}
@Test
- public void testSimpleWithComplesQuotedString() throws ParseException {
+ public void testSimpleWithComplesQuotedString() throws IOException {
doTest(PARAM_COMPLEX_QUOTED);
}
@Test
- public void testSimpleWithCharset() throws ParseException {
+ public void testSimpleWithCharset() throws IOException {
doTest(PARAM_CHARSET);
}
@Test
- public void testSimpleWithCharsetWhitespaceBefore() throws ParseException {
+ public void testSimpleWithCharsetWhitespaceBefore() throws IOException {
doTest(PARAM_WS_CHARSET);
}
@Test
- public void testSimpleWithCharsetWhitespaceAfter() throws ParseException {
+ public void testSimpleWithCharsetWhitespaceAfter() throws IOException {
doTest(PARAM_CHARSET_WS);
}
@Test
- public void testSimpleWithCharsetQuoted() throws ParseException {
+ public void testSimpleWithCharsetQuoted() throws IOException {
doTest(PARAM_CHARSET_QUOTED);
}
@Test
- public void testSimpleWithAll() throws ParseException {
+ public void testSimpleWithAll() throws IOException {
doTest(PARAM_COMPLEX_QUOTED, PARAM_EMPTY_QUOTED, PARAM_QUOTED,
PARAM_TOKEN, PARAM_CHARSET);
}
@Test
- public void testCharset() throws ParseException {
+ public void testCharset() throws IOException {
StringBuilder sb = new StringBuilder();
sb.append(TYPES);
sb.append(PARAM_CHARSET);
sb.append(PARAM_TOKEN);
StringReader sr = new StringReader(sb.toString());
- HttpParser hp = new HttpParser(sr);
- AstMediaType m = hp.MediaType();
+ MediaType m = HttpParser.parseMediaType(sr);
- assertEquals(sb.toString().replaceAll(" ", ""), m.toString());
+ assertEquals("foo/bar; charset=UTF-8; a=b", m.toString());
assertEquals(CHARSET, m.getCharset());
- assertEquals(TYPES.replaceAll(" ", "") + PARAM_TOKEN,
- m.toStringNoCharset());
+ assertEquals("foo/bar; a=b", m.toStringNoCharset());
}
@Test
- public void testCharsetQuoted() throws ParseException {
+ public void testCharsetQuoted() throws IOException {
StringBuilder sb = new StringBuilder();
sb.append(TYPES);
sb.append(PARAM_CHARSET_QUOTED);
StringReader sr = new StringReader(sb.toString());
- HttpParser hp = new HttpParser(sr);
- AstMediaType m = hp.MediaType();
+ MediaType m = HttpParser.parseMediaType(sr);
assertEquals(CHARSET_WS, m.getCharset());
assertEquals(TYPES.replaceAll(" ", ""),
@@ -155,88 +153,59 @@ public class TestMediaType {
@Test
- public void testBug52811() throws ParseException {
+ public void testBug52811() throws IOException {
String input = "multipart/related;boundary=1_4F50BD36_CDF8C28;" +
"Start=\"<31671603.smil>\";" +
"Type=\"application/smil;charset=UTF-8\"";
StringReader sr = new StringReader(input);
- HttpParser hp = new HttpParser(sr);
- AstMediaType m = hp.MediaType();
-
- assertTrue(m.children.length == 5);
+ MediaType m = HttpParser.parseMediaType(sr);
// Check the types
- assertTrue(m.children[0] instanceof AstType);
- assertTrue(m.children[1] instanceof AstSubType);
- assertEquals("multipart", m.children[0].toString());
- assertEquals("related", m.children[1].toString());
+ assertEquals("multipart", m.getType());
+ assertEquals("related", m.getSubtype());
// Check the parameters
- AstParameter p = (AstParameter) m.children[2];
- assertTrue(p.children.length == 2);
- assertTrue(p.children[0] instanceof AstAttribute);
- assertTrue(p.children[1] instanceof AstValue);
- assertEquals("boundary", p.children[0].toString());
- assertEquals("1_4F50BD36_CDF8C28", p.children[1].toString());
-
- p = (AstParameter) m.children[3];
- assertTrue(p.children.length == 2);
- assertTrue(p.children[0] instanceof AstAttribute);
- assertTrue(p.children[1] instanceof AstValue);
- assertEquals("Start", p.children[0].toString());
- assertEquals("\"<31671603.smil>\"", p.children[1].toString());
-
- p = (AstParameter) m.children[4];
- assertTrue(p.children.length == 2);
- assertTrue(p.children[0] instanceof AstAttribute);
- assertTrue(p.children[1] instanceof AstValue);
- assertEquals("Type", p.children[0].toString());
+ assertTrue(m.getParameterCount() == 3);
+
+ assertEquals("1_4F50BD36_CDF8C28", m.getParameterValue("boundary"));
+ assertEquals("\"<31671603.smil>\"", m.getParameterValue("Start"));
assertEquals("\"application/smil;charset=UTF-8\"",
- p.children[1].toString());
+ m.getParameterValue("Type"));
- assertEquals(input, m.toString());
- assertEquals(input, m.toStringNoCharset());
+ String expected = "multipart/related; boundary=1_4F50BD36_CDF8C28; " +
+ "Start=\"<31671603.smil>\"; " +
+ "Type=\"application/smil;charset=UTF-8\"";
+ assertEquals(expected, m.toString());
+ assertEquals(expected, m.toStringNoCharset());
assertNull(m.getCharset());
}
@Test
- public void testBug53353() throws ParseException {
+ public void testBug53353() throws IOException {
String input = "text/html; UTF-8;charset=UTF-8";
StringReader sr = new StringReader(input);
- HttpParser hp = new HttpParser(sr);
- AstMediaType m = hp.MediaType();
-
- assertTrue(m.children.length == 4);
+ MediaType m = HttpParser.parseMediaType(sr);
// Check the types
- assertTrue(m.children[0] instanceof AstType);
- assertTrue(m.children[1] instanceof AstSubType);
- assertEquals("text", m.children[0].toString());
- assertEquals("html", m.children[1].toString());
+ assertEquals("text", m.getType());
+ assertEquals("html", m.getSubtype());
// Check the parameters
- AstParameter p = (AstParameter) m.children[2];
- assertTrue(p.children.length == 1);
- assertTrue(p.children[0] instanceof AstAttribute);
- assertEquals("UTF-8", p.children[0].toString());
-
- p = (AstParameter) m.children[3];
- assertTrue(p.children.length == 2);
- assertTrue(p.children[0] instanceof AstAttribute);
- assertTrue(p.children[1] instanceof AstValue);
- assertEquals("charset", p.children[0].toString());
- assertEquals("UTF-8", p.children[1].toString());
+ assertTrue(m.getParameterCount() == 2);
+
+ assertEquals("", m.getParameterValue("UTF-8"));
+ assertEquals("UTF-8", m.getCharset());
// Note: Invalid input is filtered out
- assertEquals("text/html;charset=UTF-8", m.toString());
+ assertEquals("text/html; charset=UTF-8", m.toString());
assertEquals("UTF-8", m.getCharset());
}
- private void doTest(Parameter... parameters) throws ParseException {
+ private void doTest(Parameter... parameters) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append(TYPES);
for (Parameter p : parameters) {
@@ -244,27 +213,19 @@ public class TestMediaType {
}
StringReader sr = new StringReader(sb.toString());
- HttpParser hp = new HttpParser(sr);
- AstMediaType m = hp.MediaType();
+ MediaType m = HttpParser.parseMediaType(sr);
- // Check all expected children are present
- assertTrue(m.children.length == 2 + parameters.length);
+ // Check all expected parameters are present
+ assertTrue(m.getParameterCount() == parameters.length);
// Check the types
- assertTrue(m.children[0] instanceof AstType);
- assertTrue(m.children[1] instanceof AstSubType);
- assertEquals(TYPE.trim(), m.children[0].toString());
- assertEquals(SUBTYPE.trim(), m.children[1].toString());
+ assertEquals(TYPE.trim(), m.getType());
+ assertEquals(SUBTYPE.trim(), m.getSubtype());
// Check the parameters
for (int i = 0; i < parameters.length; i++) {
- assertTrue(m.children[i + 2] instanceof AstParameter);
- AstParameter p = (AstParameter) m.children[i + 2];
- assertTrue(p.children.length == 2);
- assertTrue(p.children[0] instanceof AstAttribute);
- assertTrue(p.children[1] instanceof AstValue);
- assertEquals(parameters[i].getName().trim(), p.children[0].toString());
- assertEquals(parameters[i].getValue().trim(), p.children[1].toString());
+ assertEquals(parameters[i].getValue().trim(),
+ m.getParameterValue(parameters[i].getName().trim()));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r1405415 - in /tomcat/trunk: ./ java/org/apache/catalina/authenticator/
java/org/apache/catalina/connector/ java/org/apache/coyote/
java/org/apache/tomcat/util/http/parser/ test/org/apache/tomcat/util/http/parser/
Posted by Konstantin Kolinko <kn...@gmail.com>.
2012/11/4 <ma...@apache.org>:
> Author: markt
> Date: Sat Nov 3 20:46:02 2012
> New Revision: 1405415
>
> URL: http://svn.apache.org/viewvc?rev=1405415&view=rev
> Log:
> Move media-type parsing to the new parser and drop the JJTree based parser.
>
> Added:
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
> - copied, changed from r1405399, tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java
> Removed:
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstAttribute.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstMediaType.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstParameter.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstSubType.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstType.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/AstValue.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.jjt
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParserConstants.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParserTokenManager.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParserTreeConstants.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/JJTHttpParserState.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/Node.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/ParseException.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/SimpleCharStream.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/SimpleNode.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/Token.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/TokenMgrError.java
> Modified:
> tomcat/trunk/build.xml
> tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
> tomcat/trunk/java/org/apache/catalina/connector/Response.java
> tomcat/trunk/java/org/apache/coyote/Response.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaType.java
> tomcat/trunk/java/org/apache/tomcat/util/http/parser/MediaTypeCache.java
> tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java
> tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java
> Copied: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java (from r1405399, tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser2.java)
> @@ -198,60 +190,59 @@ public class HttpParser2 {
> return null;
> }
>
> - skipLws(input);
> -
> - Map<String,String> parameters = new HashMap<>();
> + LinkedHashMap<String,String> parameters = new LinkedHashMap<>();
>
> SkipConstantResult lookForSemiColon = skipConstant(input, ";");
> if (lookForSemiColon == SkipConstantResult.NOT_FOUND) {
> return null;
> }
> while (lookForSemiColon == SkipConstantResult.FOUND) {
> - skipLws(input);
> String attribute = readToken(input);
> - skipLws(input);
>
> - if (skipConstant(input, "=") != SkipConstantResult.FOUND) {
> - return null;
> + if (skipConstant(input, "=") == SkipConstantResult.FOUND) {
> + String value = readTokenOrQuotedString(input, true);
> + parameters.put(attribute, value);
> + } else {
> + parameters.put(attribute, "");
> }
>
> - skipLws(input);
> - String value = readTokenOrQuotedString(input, true);
> - skipLws(input);
> -
> - parameters.put(attribute.toLowerCase(), value);
The above old code does attribute.toLowerCase(). The new code does not.
Looking into MediaType#MediaType(type,subtype,parameters) constructor, it calls
String cs = parameters.get("charset");
So it works with lowercase.
According to RFC2616 ch. 3.7 Media Types,
"The type, subtype, and parameter attribute names are case-insensitive."
> -
> lookForSemiColon = skipConstant(input, ";");
> if (lookForSemiColon == SkipConstantResult.NOT_FOUND) {
> return null;
> }
> }
>
> - String charset = parameters.remove("charset");
> - StringBuilder noCharSet = new StringBuilder();
> - noCharSet.append(type);
> - noCharSet.append('/');
> - noCharSet.append(subtype);
> - for (Map.Entry<String, String> entry : parameters.entrySet()) {
> - noCharSet.append(';');
> - // Workaround for Adobe Read 9 plug-in on IE bug
> - // Can be removed after 26 June 2013 (EOL of Reader 9)
> - // See BZ 53814
> - noCharSet.append(' ');
> - noCharSet.append(entry.getKey());
> - noCharSet.append('=');
> - noCharSet.append(entry.getValue());
> + return new MediaType(type, subtype, parameters);
> + }
> +
(...)
Best regards,
Konstantin Kolinko
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org