Return-Path: X-Original-To: apmail-tomcat-dev-archive@www.apache.org Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B14D2D80E for ; Sat, 3 Nov 2012 20:46:27 +0000 (UTC) Received: (qmail 81587 invoked by uid 500); 3 Nov 2012 20:46:26 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 81521 invoked by uid 500); 3 Nov 2012 20:46:26 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 81511 invoked by uid 99); 3 Nov 2012 20:46:26 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 03 Nov 2012 20:46:26 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 03 Nov 2012 20:46:24 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DF5C123888CD for ; Sat, 3 Nov 2012 20:46:03 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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/ Date: Sat, 03 Nov 2012 20:46:03 -0000 To: dev@tomcat.apache.org From: markt@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121103204603.DF5C123888CD@eris.apache.org> X-Virus-Checked: Checked by ClamAV on 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 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 @@ - 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 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 parameters = new HashMap<>(); + LinkedHashMap 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 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 null 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 parameters; private final String charset; + private volatile String noCharset; + private volatile String withCharset; + + protected MediaType(String type, String subtype, + LinkedHashMap 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 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 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 result = HttpParser2.parseAuthorizationDigest(input); + Map 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 result = HttpParser2.parseAuthorizationDigest(input); + Map 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 result = HttpParser2.parseAuthorizationDigest(input); + Map 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 result = HttpParser2.parseAuthorizationDigest(input); + Map 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 result = HttpParser2.parseAuthorizationDigest(input); + Map result = HttpParser.parseAuthorizationDigest(input); Assert.assertEquals("00000001", result.get("nc")); } @@ -131,7 +131,7 @@ public class TestAuthorizationDigest { StringReader input = new StringReader(header); - Map result = HttpParser2.parseAuthorizationDigest(input); + Map result = HttpParser.parseAuthorizationDigest(input); Assert.assertNull(result); } @@ -141,7 +141,7 @@ public class TestAuthorizationDigest { StringReader input = new StringReader(header); - Map result = HttpParser2.parseAuthorizationDigest(input); + Map result = HttpParser.parseAuthorizationDigest(input); Assert.assertNull(result); } @@ -151,7 +151,7 @@ public class TestAuthorizationDigest { StringReader input = new StringReader(header); - Map result = HttpParser2.parseAuthorizationDigest(input); + Map 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