Author: markt Date: Sat Oct 31 14:09:02 2009 New Revision: 831544 URL: http://svn.apache.org/viewvc?rev=831544&view=rev Log: Add a new new cookie option to allow the use of equals signs in cookies. Includes test cases and docs.
Added: tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java Modified: tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java tomcat/trunk/webapps/docs/config/systemprops.xml 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=831544&r1=831543&r2=831544&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/Cookies.java Sat Oct 31 14:09:02 2009 @@ -53,6 +53,12 @@ public static final boolean STRICT_SERVLET_COMPLIANCE; /** + * If true, cookie values are allowed to contain an equals character without + * being quoted. + */ + public static final boolean ALLOW_EQUALS_IN_VALUE; + + /** * If set to true, the <code>/</code> character will be treated as a * separator. Default is usually false. If STRICT_SERVLET_COMPLIANCE==true * then default is true. Explicitly setting always takes priority. @@ -70,6 +76,10 @@ "org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "false")).booleanValue(); + ALLOW_EQUALS_IN_VALUE = Boolean.valueOf(System.getProperty( + "org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE", + "false")).booleanValue(); + String fwdSlashIsSeparator = System.getProperty( "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR"); if (fwdSlashIsSeparator == null) { @@ -588,7 +598,11 @@ */ public static final int getTokenEndPosition(byte bytes[], int off, int end){ int pos = off; - while (pos < end && !isSeparator(bytes[pos])) {pos++; } + while (pos < end && + (!isSeparator(bytes[pos]) || + bytes[pos]=='=' && ALLOW_EQUALS_IN_VALUE)) { + pos++; + } if (pos > end) return end; Added: tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java?rev=831544&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java (added) +++ tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java Sat Oct 31 14:09:02 2009 @@ -0,0 +1,99 @@ +/* + * 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; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.SimpleHttpClient; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.catalina.startup.Tomcat; + +public class TestCookiesAllowEquals extends TomcatBaseTest{ + + private static final String COOKIE_WITH_EQUALS = "name=value=withequals"; + + public void testWithEquals() throws Exception { + System.setProperty( + "org.apache.tomcat.util.http.ServerCookie.ALLOW_EQUALS_IN_VALUE", + "true"); + + TestCookieEqualsClient client = new TestCookieEqualsClient(); + client.doRequest(); + } + + private class TestCookieEqualsClient extends SimpleHttpClient { + + + private void doRequest() throws Exception { + Tomcat tomcat = getTomcatInstance(); + StandardContext root = tomcat.addContext("", TEMP_DIR); + Tomcat.addServlet(root, "Simple", new SimpleServlet()); + root.addServletMapping("/test", "Simple"); + + tomcat.start(); + // Open connection + setPort(tomcat.getConnector().getPort()); + connect(); + + String[] request = new String[1]; + request[0] = + "GET /test HTTP/1.0" + CRLF + + "Cookie: " + COOKIE_WITH_EQUALS + CRLF + CRLF; + setRequest(request); + processRequest(true); // blocks until response has been read + String response = getResponseBody(); + + // Close the connection + disconnect(); + reset(); + tomcat.stop(); + assertTrue(response.contains(COOKIE_WITH_EQUALS)); + } + + @Override + public boolean isResponseBodyOK() { + return true; + } + + } + + + private static class SimpleServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + Cookie cookies[] = req.getCookies(); + for (Cookie cookie : cookies) { + resp.getWriter().write(cookie.getName() + "=" + + cookie.getValue() + "\n"); + } + resp.flushBuffer(); + } + + } + +} Added: tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java?rev=831544&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java (added) +++ tomcat/trunk/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java Sat Oct 31 14:09:02 2009 @@ -0,0 +1,96 @@ +/* + * 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; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.startup.SimpleHttpClient; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.catalina.startup.Tomcat; + +public class TestCookiesDisallowEquals extends TomcatBaseTest{ + + private static final String COOKIE_WITH_EQUALS = "name=value=withequals"; + private static final String COOKIE_TRUNCATED = "name=value"; + + public void testWithEquals() throws Exception { + TestCookieEqualsClient client = new TestCookieEqualsClient(); + client.doRequest(); + } + + private class TestCookieEqualsClient extends SimpleHttpClient { + + + private void doRequest() throws Exception { + Tomcat tomcat = getTomcatInstance(); + StandardContext root = tomcat.addContext("", TEMP_DIR); + Tomcat.addServlet(root, "Simple", new SimpleServlet()); + root.addServletMapping("/test", "Simple"); + + tomcat.start(); + // Open connection + setPort(tomcat.getConnector().getPort()); + connect(); + + String[] request = new String[1]; + request[0] = + "GET /test HTTP/1.0" + CRLF + + "Cookie: " + COOKIE_WITH_EQUALS + CRLF + CRLF; + setRequest(request); + processRequest(true); // blocks until response has been read + String response = getResponseBody(); + + // Close the connection + disconnect(); + reset(); + tomcat.stop(); + assertTrue(response.contains(COOKIE_TRUNCATED)); + } + + @Override + public boolean isResponseBodyOK() { + return true; + } + + } + + + private static class SimpleServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + Cookie cookies[] = req.getCookies(); + for (Cookie cookie : cookies) { + resp.getWriter().write(cookie.getName() + "=" + + cookie.getValue() + "\n"); + } + resp.flushBuffer(); + } + + } + +} Modified: tomcat/trunk/webapps/docs/config/systemprops.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/systemprops.xml?rev=831544&r1=831543&r2=831544&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/systemprops.xml (original) +++ tomcat/trunk/webapps/docs/config/systemprops.xml Sat Oct 31 14:09:02 2009 @@ -236,16 +236,12 @@ the request explicitly accesses the session. (SRV.7.6) </li> <li> - cookies will be parsed strictly, by default v0 cookies will not work with any invalid characters. - <br/>If set to false, any v0 cookie with invalid character will be switched to a v1 cookie and - the value will be quoted. - </li> - <li> <code>ServletContext.getResource/getResourceAsStream</code> must start with "/"<br/> if set to false, code like <code>getResource("myfolder/myresource.txt")</code> will work </li> <li> The default value will be changed for + <code>org.apache.tomcat.util.http.ServerCookie.ALLOW_VERSION_SWITCH</code>. <code>org.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES</code>. <code>org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR</code>. <code>org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING</code>. @@ -272,6 +268,16 @@ </property> <property + name="org.apache.tomcat.util.http. ServerCookie.ALLOW_EQUALS_IN_VALUE"> + <p>If this is <code>true</code> Tomcat will allow <code>=</code> + characters when parsing unquoted cookie values. If <code>false</code>, + cookie values containing <code>=</code> will be terminated when the + <code>=</code> is encountered and the remainder of the cookie value will + be dropped. If not specified, the default value specification compliant + value of <code>false</code> will be used.</p> + </property> + + <property name="org.apache.tomcat.util.http. ServerCookie.ALLOW_VERSION_SWITCH"> <p>If this is <code>true</code> Tomcat will convert a v0 cookie that contains invalid characters (i.e. separators) to a v1 cookie and add --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org