From: markt Date: Sat, 31 Oct 2009 14:09:02 +0000 (+0000) Subject: Add a new new cookie option to allow the use of equals signs in cookies. Includes... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=6b6dafaf78c3059a848e76e0f2e5734e42c2d369;p=tomcat7.0 Add a new new cookie option to allow the use of equals signs in cookies. Includes test cases and docs. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@831544 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/tomcat/util/http/Cookies.java b/java/org/apache/tomcat/util/http/Cookies.java index e45b60d21..12ef857bb 100644 --- a/java/org/apache/tomcat/util/http/Cookies.java +++ b/java/org/apache/tomcat/util/http/Cookies.java @@ -53,6 +53,12 @@ public final class Cookies { // extends MultiMap { 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 / 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 @@ public final class Cookies { // extends MultiMap { "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 final class Cookies { // extends MultiMap { */ 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; diff --git a/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java b/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java new file mode 100644 index 000000000..225946aeb --- /dev/null +++ b/test/org/apache/tomcat/util/http/TestCookiesAllowEquals.java @@ -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(); + } + + } + +} diff --git a/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java b/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java new file mode 100644 index 000000000..4efbb2c47 --- /dev/null +++ b/test/org/apache/tomcat/util/http/TestCookiesDisallowEquals.java @@ -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(); + } + + } + +} diff --git a/webapps/docs/config/systemprops.xml b/webapps/docs/config/systemprops.xml index d50bfad47..75a2c98e2 100644 --- a/webapps/docs/config/systemprops.xml +++ b/webapps/docs/config/systemprops.xml @@ -236,16 +236,12 @@ the request explicitly accesses the session. (SRV.7.6)
  • - cookies will be parsed strictly, by default v0 cookies will not work with any invalid characters. -
    If set to false, any v0 cookie with invalid character will be switched to a v1 cookie and - the value will be quoted. -
  • -
  • ServletContext.getResource/getResourceAsStream must start with "/"
    if set to false, code like getResource("myfolder/myresource.txt") will work
  • The default value will be changed for + org.apache.tomcat.util.http.ServerCookie.ALLOW_VERSION_SWITCH. org.apache.tomcat.util.http.ServerCookie.ALWAYS_ADD_EXPIRES. org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR. org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING. @@ -272,6 +268,16 @@ +

    If this is true Tomcat will allow = + characters when parsing unquoted cookie values. If false, + cookie values containing = will be terminated when the + = is encountered and the remainder of the cookie value will + be dropped. If not specified, the default value specification compliant + value of false will be used.

    +
    + +

    If this is true Tomcat will convert a v0 cookie that contains invalid characters (i.e. separators) to a v1 cookie and add