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/03/13 15:39:25 UTC

svn commit: r1300154 [2/2] - in /tomcat/trunk: ./ java/org/apache/coyote/ java/org/apache/tomcat/util/http/parser/ test/org/apache/tomcat/util/http/parser/

Added: tomcat/trunk/java/org/apache/tomcat/util/http/parser/Token.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/Token.java?rev=1300154&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/Token.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/Token.java Tue Mar 13 14:39:24 2012
@@ -0,0 +1,131 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
+/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package org.apache.tomcat.util.http.parser;
+
+/**
+ * Describes the input token stream.
+ */
+@SuppressWarnings("all") // Ignore warnings in generated code
+public class Token implements java.io.Serializable {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /** The line number of the first character of this Token. */
+  public int beginLine;
+  /** The column number of the first character of this Token. */
+  public int beginColumn;
+  /** The line number of the last character of this Token. */
+  public int endLine;
+  /** The column number of the last character of this Token. */
+  public int endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * An optional attribute value of the Token.
+   * Tokens which are not used as syntactic sugar will often contain
+   * meaningful values that will be used later on by the compiler or
+   * interpreter. This attribute value is often different from the image.
+   * Any subclass of Token that actually wants to return a non-null value can
+   * override this method as appropriate.
+   */
+  public Object getValue() {
+    return null;
+  }
+
+  /**
+   * No-argument constructor
+   */
+  public Token() {}
+
+  /**
+   * Constructs a new token for the specified Image.
+   */
+  public Token(int kind)
+  {
+    this(kind, null);
+  }
+
+  /**
+   * Constructs a new token for the specified Image and Kind.
+   */
+  public Token(int kind, String image)
+  {
+    this.kind = kind;
+    this.image = image;
+  }
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+    return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simply add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken(ofKind, image);
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use sit in your lexical actions.
+   */
+  public static Token newToken(int ofKind, String image)
+  {
+    switch(ofKind)
+    {
+      default : return new Token(ofKind, image);
+    }
+  }
+
+  public static Token newToken(int ofKind)
+  {
+    return newToken(ofKind, null);
+  }
+
+}
+/* JavaCC - OriginalChecksum=2104130aa3f9189e35a4571dc4c8f0c9 (do not edit this line) */

Propchange: tomcat/trunk/java/org/apache/tomcat/util/http/parser/Token.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/java/org/apache/tomcat/util/http/parser/TokenMgrError.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/TokenMgrError.java?rev=1300154&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/TokenMgrError.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/TokenMgrError.java Tue Mar 13 14:39:24 2012
@@ -0,0 +1,148 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
+/* JavaCCOptions: */
+package org.apache.tomcat.util.http.parser;
+
+/** Token Manager Error. */
+@SuppressWarnings("all") // Ignore warnings in generated code
+public class TokenMgrError extends Error
+{
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /*
+   * Ordinals for various reasons why an Error of this type can be thrown.
+   */
+
+  /**
+   * Lexical error occurred.
+   */
+  static final int LEXICAL_ERROR = 0;
+
+  /**
+   * An attempt was made to create a second instance of a static token manager.
+   */
+  static final int STATIC_LEXER_ERROR = 1;
+
+  /**
+   * Tried to change to an invalid lexical state.
+   */
+  static final int INVALID_LEXICAL_STATE = 2;
+
+  /**
+   * Detected (and bailed out of) an infinite loop in the token manager.
+   */
+  static final int LOOP_DETECTED = 3;
+
+  /**
+   * Indicates the reason why the exception is thrown. It will have
+   * one of the above 4 values.
+   */
+  int errorCode;
+
+  /**
+   * Replaces unprintable characters by their escaped (or unicode escaped)
+   * equivalents in the given string
+   */
+  protected static final String addEscapes(String str) {
+    StringBuffer retval = new StringBuffer();
+    char ch;
+    for (int i = 0; i < str.length(); i++) {
+      switch (str.charAt(i))
+      {
+        case 0 :
+          continue;
+        case '\b':
+          retval.append("\\b");
+          continue;
+        case '\t':
+          retval.append("\\t");
+          continue;
+        case '\n':
+          retval.append("\\n");
+          continue;
+        case '\f':
+          retval.append("\\f");
+          continue;
+        case '\r':
+          retval.append("\\r");
+          continue;
+        case '\"':
+          retval.append("\\\"");
+          continue;
+        case '\'':
+          retval.append("\\\'");
+          continue;
+        case '\\':
+          retval.append("\\\\");
+          continue;
+        default:
+          if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+            String s = "0000" + Integer.toString(ch, 16);
+            retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+          } else {
+            retval.append(ch);
+          }
+          continue;
+      }
+    }
+    return retval.toString();
+  }
+
+  /**
+   * Returns a detailed message for the Error when it is thrown by the
+   * token manager to indicate a lexical error.
+   * Parameters :
+   *    EOFSeen     : indicates if EOF caused the lexical error
+   *    curLexState : lexical state in which this error occurred
+   *    errorLine   : line number when the error occurred
+   *    errorColumn : column number when the error occurred
+   *    errorAfter  : prefix that was seen before this error occurred
+   *    curchar     : the offending character
+   * Note: You can customize the lexical error message by modifying this method.
+   */
+  protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+    return("Lexical error at line " +
+          errorLine + ", column " +
+          errorColumn + ".  Encountered: " +
+          (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+          "after : \"" + addEscapes(errorAfter) + "\"");
+  }
+
+  /**
+   * You can also modify the body of this method to customize your error messages.
+   * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+   * of end-users concern, so you can return something like :
+   *
+   *     "Internal Error : Please file a bug report .... "
+   *
+   * from this method for such cases in the release version of your parser.
+   */
+  public String getMessage() {
+    return super.getMessage();
+  }
+
+  /*
+   * Constructors of various flavors follow.
+   */
+
+  /** No arg constructor. */
+  public TokenMgrError() {
+  }
+
+  /** Constructor with message and reason. */
+  public TokenMgrError(String message, int reason) {
+    super(message);
+    errorCode = reason;
+  }
+
+  /** Full Constructor. */
+  public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+    this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+  }
+}
+/* JavaCC - OriginalChecksum=c0e71cb84849413e4aa36c7471643b93 (do not edit this line) */

Propchange: tomcat/trunk/java/org/apache/tomcat/util/http/parser/TokenMgrError.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 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=1300154&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java (added)
+++ tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java Tue Mar 13 14:39:24 2012
@@ -0,0 +1,264 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomcat.util.http.parser;
+
+import java.io.StringReader;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link HttpParser} focusing on media-type as defined in
+ * section 3.7 of RFC 2616.
+ */
+public class TestMediaType {
+
+    // Include whitespace to ensure Parser handles it correctly (it should be
+    // skipped).
+    private static final String TYPE = " foo ";
+    private static final String SUBTYPE = " bar ";
+    private static final String TYPES = TYPE + "/" + SUBTYPE;
+
+    private static final Parameter PARAM_TOKEN =
+            new Parameter("a", "b");
+    private static final Parameter PARAM_QUOTED =
+            new Parameter("x", "y");
+    private static final Parameter PARAM_EMPTY_QUOTED =
+            new Parameter("z", "\"\"");
+    private static final Parameter PARAM_COMPLEX_QUOTED =
+            new Parameter("w", "\"foo'bar,a=b;x=y\"");
+    private static final String CHARSET = "UTF-8";
+    private static final String WS_CHARSET = " \tUTF-8";
+    private static final String CHARSET_WS = "UTF-8 \t";
+    // Since this is quoted, it should retain the space at the end
+    private static final String CHARSET_QUOTED = "\"" + CHARSET_WS + "\"";
+    private static final Parameter PARAM_CHARSET =
+            new Parameter("charset", CHARSET);
+    private static final Parameter PARAM_WS_CHARSET =
+            new Parameter("charset", WS_CHARSET);
+    private static final Parameter PARAM_CHARSET_WS =
+            new Parameter("charset", CHARSET_WS);
+    private static final Parameter PARAM_CHARSET_QUOTED =
+            new Parameter("charset", CHARSET_QUOTED);
+
+
+    @Test
+    public void testSimple() throws ParseException {
+        doTest();
+    }
+
+
+    @Test
+    public void testSimpleWithToken() throws ParseException {
+        doTest(PARAM_TOKEN);
+    }
+
+
+    @Test
+    public void testSimpleWithQuotedString() throws ParseException {
+        doTest(PARAM_QUOTED);
+    }
+
+
+    @Test
+    public void testSimpleWithEmptyQuotedString() throws ParseException {
+        doTest(PARAM_EMPTY_QUOTED);
+    }
+
+
+    @Test
+    public void testSimpleWithComplesQuotedString() throws ParseException {
+        doTest(PARAM_COMPLEX_QUOTED);
+    }
+
+
+    @Test
+    public void testSimpleWithCharset() throws ParseException {
+        doTest(PARAM_CHARSET);
+    }
+
+
+    @Test
+    public void testSimpleWithCharsetWhitespaceBefore() throws ParseException {
+        doTest(PARAM_WS_CHARSET);
+    }
+
+
+    @Test
+    public void testSimpleWithCharsetWhitespaceAfter() throws ParseException {
+        doTest(PARAM_CHARSET_WS);
+    }
+
+
+    @Test
+    public void testSimpleWithCharsetQuoted() throws ParseException {
+        doTest(PARAM_CHARSET_QUOTED);
+    }
+
+
+    @Test
+    public void testSimpleWithAll() throws ParseException {
+        doTest(PARAM_COMPLEX_QUOTED, PARAM_EMPTY_QUOTED, PARAM_QUOTED,
+                PARAM_TOKEN, PARAM_CHARSET);
+    }
+
+
+    @Test
+    public void testCharset() throws ParseException {
+        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();
+
+        assertEquals(sb.toString().replaceAll(" ", ""), m.toString());
+        assertEquals(CHARSET, m.getCharset());
+        assertEquals(TYPES.replaceAll(" ", "") + PARAM_TOKEN,
+                m.toStringNoCharset());
+    }
+
+
+    @Test
+    public void testCharsetQuoted() throws ParseException {
+        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();
+
+        assertEquals(CHARSET_WS, m.getCharset());
+        assertEquals(TYPES.replaceAll(" ", ""),
+                m.toStringNoCharset());
+    }
+
+
+    @Test
+    public void testBug52811() throws ParseException {
+        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);
+
+        // 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());
+
+        // 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());
+        assertEquals("\"application/smil;charset=UTF-8\"",
+                p.children[1].toString());
+
+        assertEquals(input, m.toString());
+        assertEquals(input, m.toStringNoCharset());
+        assertNull(m.getCharset());
+    }
+
+
+    private void doTest(Parameter... parameters) throws ParseException {
+        StringBuilder sb = new StringBuilder();
+        sb.append(TYPES);
+        for (Parameter p : parameters) {
+            sb.append(p.toString());
+        }
+
+        StringReader sr = new StringReader(sb.toString());
+        HttpParser hp = new HttpParser(sr);
+        AstMediaType m = hp.MediaType();
+
+        // Check all expected children are present
+        assertTrue(m.children.length == 2 + 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());
+
+        // 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());
+        }
+    }
+
+
+    private static class Parameter {
+        private final String name;
+        private final String value;
+
+        public Parameter(String name,String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(";");
+            sb.append(name);
+            sb.append("=");
+            sb.append(value);
+            return sb.toString();
+        }
+    }
+}

Propchange: tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestMediaType.java
------------------------------------------------------------------------------
    svn:eol-style = native



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