Author: markt
Date: Tue Sep  2 13:40:53 2014
New Revision: 1621983

URL: http://svn.apache.org/r1621983
Log:
Add a per context option to select the cookie parser to use and add the
necessary plumbing to pass that choice to the cookie parser.

Modified:
    tomcat/trunk/java/org/apache/catalina/Context.java
    tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
    tomcat/trunk/java/org/apache/catalina/connector/Request.java
    tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
    tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml
    tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java
    tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java
    tomcat/trunk/test/org/apache/catalina/core/TesterContext.java
    tomcat/trunk/webapps/docs/config/context.xml

Modified: tomcat/trunk/java/org/apache/catalina/Context.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Context.java?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Context.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Context.java Tue Sep  2 13:40:53 2014
@@ -17,6 +17,7 @@
 package org.apache.catalina;
 
 import java.net.URL;
+import java.nio.charset.Charset;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -1637,4 +1638,40 @@ public interface Context extends Contain
      * context.
      */
     public Object getNamingToken();
+
+    /**
+     * Should this context use the new RFC6265 based cookie parser for
+     * processing HTTP cookies? The default value is currently false but that
+     * may change in a future point release.
+     */
+    public void setUseRfc6265(boolean useRfc6265);
+
+    /**
+     * Does this context use the new RFC6265 based cookie parser for
+     * processing HTTP cookies? The default value is currently false but that
+     * may change in a future point release.
+     */
+    public boolean getUseRfc6265();
+
+    /**
+     * Specifies the name of the character encoding to use to convert bytes 
into
+     * characters when processing cookies using the RFC6265 based cookie 
parser.
+     * It has no effect if the RFC6265 parser is not used.
+     * If an unrecognised character encoding is specified, a warning will be
+     * logged and the default value of UTF-8 will be used.
+     */
+    public void setCookieEncoding(String encoding);
+
+    /**
+     * Returns the name of the character encoding used to convert bytes into
+     * characters when processing cookies using the RFC6265 based cookie 
parser.
+     * The default value is UTF-8.
+     */
+    public String getCookieEncoding();
+
+    /**
+     * Returns the character set used to convert bytes into characters when
+     * processing cookies using the RFC6265 based cookie parser.
+     */
+    public Charset getCookieEncodingCharset();
 }

Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Tue Sep  
2 13:40:53 2014
@@ -900,6 +900,13 @@ public class CoyoteAdapter implements Ad
                 }
             }
 
+            if (request.getContext().getUseRfc6265()) {
+                req.getCookies().setUseRfc6265(true);
+            } else {
+                req.getCookies().setUseRfc6265(false);
+            }
+
+
             // Look for session ID in cookies and SSL session
             parseSessionCookiesId(req, request);
             parseSessionSslId(request);
@@ -931,6 +938,9 @@ public class CoyoteAdapter implements Ad
                                 // Reset mapping
                                 request.getMappingData().recycle();
                                 mapRequired = true;
+                                // Recycle cookies in case correct context is
+                                // configured with different settings
+                                req.getCookies().recycle();
                             }
                             break;
                         }

Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Tue Sep  2 
13:40:53 2014
@@ -2865,6 +2865,10 @@ public class Request
                 Cookie cookie = new Cookie(scookie.getName().toString(),null);
                 int version = scookie.getVersion();
                 cookie.setVersion(version);
+                if (getContext().getUseRfc6265()) {
+                    scookie.getValue().getByteChunk().setCharset(
+                            getContext().getCookieEncodingCharset());
+                }
                 cookie.setValue(unescape(scookie.getValue().toString()));
                 cookie.setPath(unescape(scookie.getPath().toString()));
                 String domain = scookie.getDomain().toString();

Modified: tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/LocalStrings.properties Tue Sep  
2 13:40:53 2014
@@ -148,6 +148,7 @@ standardContext.startFailed=Context [{0}
 standardContext.startingContext=Exception starting Context with name [{0}]
 standardContext.stoppingContext=Exception stopping Context with name [{0}]
 standardContext.threadBindingListenerError=An error occurred in the thread 
binding listener configured for Context [{0}]
+standardContext.unknownCookieEncoding=The unknown encoding [{0}] was specified 
for setCookieEncoding(String) so the default of UTF-8 will be used instead
 standardContext.urlPattern.patternWarning=WARNING: URL pattern {0} must start 
with a ''/'' in Servlet 2.4
 standardContext.webappClassLoader.missingProperty=Unable to set the web 
application class loader property [{0}] to [{1}] as the property does not exist.
 standardContext.workPath=Exception obtaining work path for context [{0}]

Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Tue Sep  2 
13:40:53 2014
@@ -21,8 +21,11 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -115,6 +118,7 @@ import org.apache.tomcat.InstanceManager
 import org.apache.tomcat.JarScanner;
 import org.apache.tomcat.util.ExceptionUtils;
 import org.apache.tomcat.util.IntrospectionUtils;
+import org.apache.tomcat.util.buf.B2CConverter;
 import org.apache.tomcat.util.buf.UDecoder;
 import org.apache.tomcat.util.descriptor.XmlIdentifiers;
 import org.apache.tomcat.util.descriptor.web.ApplicationParameter;
@@ -821,9 +825,49 @@ public class StandardContext extends Con
 
     private final Object namingToken = new Object();
 
+    private boolean useRfc6265 = false;
+    private Charset cookieEncoding = StandardCharsets.UTF_8;
+
 
     // ----------------------------------------------------- Context Properties
 
+
+    @Override
+    public void setUseRfc6265(boolean useRfc6265) {
+        this.useRfc6265 = useRfc6265;
+    }
+
+
+    @Override
+    public boolean getUseRfc6265() {
+        return useRfc6265;
+    }
+
+
+    @Override
+    public void setCookieEncoding(String encoding) {
+        try {
+            Charset charset = B2CConverter.getCharset(encoding);
+            cookieEncoding = charset;
+        } catch (UnsupportedEncodingException uee) {
+            cookieEncoding = StandardCharsets.UTF_8;
+            log.warn(sm.getString("standardContext.unknownCookieEncoding"), 
uee);
+        }
+    }
+
+
+    @Override
+    public String getCookieEncoding() {
+        return cookieEncoding.name();
+    }
+
+
+    @Override
+    public Charset getCookieEncodingCharset() {
+        return cookieEncoding;
+    }
+
+
     @Override
     public Object getNamingToken() {
         return namingToken;

Modified: tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml (original)
+++ tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml Tue Sep  
2 13:40:53 2014
@@ -103,6 +103,10 @@
                type="boolean"
                writeable="false" />
 
+    <attribute name="cookieEncoding"
+               description="If the new cookie parser is used, which encoding 
should be used to decode the cookie values?"
+               type="java.lang.String"/>
+
     <attribute name="cookies"
                description="Should we attempt to use cookies for session id 
communication?"
                type="boolean"/>
@@ -331,6 +335,11 @@
                is="true"
                type="boolean"/>
 
+    <attribute name="useNewCookieParser"
+               description="Use the new RFC6265 based cookie parser"
+               is="false"
+               type="boolean"/>
+
     <attribute name="webappVersion"
                description="The version of this web application - used in 
parallel deployment to differentiate different versions of the same web 
application"
                type="java.lang.String"

Modified: tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/FailedContext.java Tue Sep  2 
13:40:53 2014
@@ -19,6 +19,8 @@ package org.apache.catalina.startup;
 import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -753,7 +755,20 @@ public class FailedContext extends Lifec
     }
 
     @Override
-    public Object getNamingToken() {
-        return null;
-    }
+    public Object getNamingToken() { return null; }
+
+    @Override
+    public void setUseRfc6265(boolean useRfc6265) { /* NO-OP */ }
+
+    @Override
+    public boolean getUseRfc6265() {return false; }
+
+    @Override
+    public void setCookieEncoding(String encoding) { /* NO-OP */ }
+
+    @Override
+    public String getCookieEncoding() { return "UTF-8"; }
+
+    @Override
+    public Charset getCookieEncodingCharset() { return StandardCharsets.UTF_8; 
}
 }
\ No newline at end of file

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java Tue Sep  2 
13:40:53 2014
@@ -23,12 +23,13 @@ import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.parser.Cookie;
 import org.apache.tomcat.util.log.UserDataHelper;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
  * A collection of cookies - reusable and tuned for server side performance.
- * Based on RFC2965 (and 2109).
+ * Based on RFC6265 and RFC2109.
  *
  * This class is not thread-safe.
  *
@@ -48,6 +49,7 @@ public final class Cookies {
     public static final int INITIAL_SIZE = 4;
     private ServerCookies scookies = new ServerCookies(INITIAL_SIZE);
     private boolean unprocessed = true;
+    private boolean useRfc6265 = false;
 
     private final MimeHeaders headers;
 
@@ -67,6 +69,7 @@ public final class Cookies {
     public void recycle() {
         scookies.recycle();
         unprocessed = true;
+        useRfc6265 = false;
     }
 
 
@@ -145,6 +148,11 @@ public final class Cookies {
     }
 
 
+    public void setUseRfc6265(boolean useRfc6265) {
+        this.useRfc6265 = useRfc6265;
+    }
+
+
     // XXX will be refactored soon!
     private static boolean equals(String s, byte b[], int start, int end) {
         int blen = end-start;
@@ -218,13 +226,22 @@ public final class Cookies {
     }
 
 
+    final void processCookieHeader(byte bytes[], int off, int len) {
+        if (useRfc6265) {
+            Cookie.parseCookie(bytes, off, len, scookies);
+        } else {
+            doProcessCookieHeaderOriginal(bytes, off, len);
+        }
+    }
+
+
     /**
      * Parses a cookie header after the initial "Cookie:"
      * [WS][$]token[WS]=[WS](token|QV)[;|,]
-     * RFC 2965
+     * RFC 2965 / RFC 2109
      * JVK
      */
-    final void processCookieHeader(byte bytes[], int off, int len){
+    private void doProcessCookieHeaderOriginal(byte bytes[], int off, int len){
         if (len <= 0 || bytes == null) {
             return;
         }

Modified: tomcat/trunk/test/org/apache/catalina/core/TesterContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TesterContext.java?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TesterContext.java (original)
+++ tomcat/trunk/test/org/apache/catalina/core/TesterContext.java Tue Sep  2 
13:40:53 2014
@@ -19,6 +19,8 @@ package org.apache.catalina.core;
 import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -1221,4 +1223,19 @@ public class TesterContext implements Co
     public Object getNamingToken() {
         return null;
     }
+
+    @Override
+    public void setUseRfc6265(boolean useRfc6265) { /* NO-OP */ }
+
+    @Override
+    public boolean getUseRfc6265() {return false; }
+
+    @Override
+    public void setCookieEncoding(String encoding) { /* NO-OP */ }
+
+    @Override
+    public String getCookieEncoding() { return "UTF-8"; }
+
+    @Override
+    public Charset getCookieEncodingCharset() { return StandardCharsets.UTF_8; 
}
 }

Modified: tomcat/trunk/webapps/docs/config/context.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=1621983&r1=1621982&r2=1621983&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Tue Sep  2 13:40:53 2014
@@ -300,6 +300,13 @@
         no filtering will be applied.</p>
       </attribute>
 
+      <attribute name="cookieEncoding" required="false">
+        <p>If the RFC6265 based cookie parser is used this attribute determines
+        the encoding to be used to convert the byte values in the HTTP header 
to
+        strings. If not specified, the default of <code>UTF-8</code> will be
+        used.</p>
+      </attribute>
+
       <attribute name="cookies" required="false">
         <p>Set to <code>true</code> if you want cookies to be used for
         session identifier communication if supported by the client (this
@@ -529,6 +536,12 @@
         penalty.</p>
       </attribute>
 
+      <attribute name="useRfc6265" required="false">
+        <p>Determines if the RFC6265 based cookie parser is used. The default
+        value is <code>false</code> in which case the original parser based on
+        RFC2109 and the Netscape cookie specification will be used.</p>
+      </attribute>
+
       <attribute name="useHttpOnly" required="false">
        <p>Should the HttpOnly flag be set on session cookies to prevent client
           side script from accessing the session ID? Defaults to



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

Reply via email to