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