init
This commit is contained in:
344
test/org/apache/tomcat/util/http/TestCookieParsing.java
Normal file
344
test/org/apache/tomcat/util/http/TestCookieParsing.java
Normal file
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* 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 java.util.Enumeration;
|
||||
|
||||
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.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.startup.SimpleHttpClient;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.catalina.startup.TomcatBaseTest;
|
||||
|
||||
|
||||
public class TestCookieParsing extends TomcatBaseTest {
|
||||
|
||||
private static final String[] COOKIES_WITH_EQUALS = new String[] {
|
||||
"name=equals=middle", "name==equalsstart", "name=equalsend=" };
|
||||
private static final String COOKIES_WITH_EQUALS_TRUNC = "name=equalsname=name=equalsend";
|
||||
|
||||
private static final String[] COOKIES_WITH_NAME_ONLY = new String[] {
|
||||
"bob", "bob=" };
|
||||
private static final String COOKIES_WITH_NAME_ONLY_CONCAT = "bob=bob=";
|
||||
|
||||
private static final String[] COOKIES_WITH_SEPS = new String[] {
|
||||
"name=val/ue" };
|
||||
private static final String COOKIES_WITH_SEPS_TRUNC = "name=val";
|
||||
|
||||
private static final String[] COOKIES_WITH_QUOTES = new String[] {
|
||||
"name=\"val\\\"ue\"", "name=\"value\"" };
|
||||
|
||||
private static final String[] COOKIES_V0 = new String[] {
|
||||
"$Version=0;name=\"val ue\"", "$Version=0;name=\"val\tue\""};
|
||||
|
||||
private static final String COOKIES_V0_CONCAT = "name=\"val ue\"name=\"val\tue\"";
|
||||
|
||||
private static final String[] COOKIES_V1 = new String[] {
|
||||
"$Version=1;name=\"val ue\"", "$Version=1;name=\"val\tue\""};
|
||||
|
||||
private static final String COOKIES_V1_CONCAT = "name=\"val ue\"name=\"val\tue\"";
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithEquals() throws Exception {
|
||||
doTestLegacyEquals(true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithoutEquals() throws Exception {
|
||||
doTestLegacyEquals(false);
|
||||
}
|
||||
|
||||
|
||||
private void doTestLegacyEquals(boolean allowEquals) throws Exception {
|
||||
LegacyCookieProcessor legacyCookieProcessor = new LegacyCookieProcessor();
|
||||
legacyCookieProcessor.setAllowEqualsInValue(allowEquals);
|
||||
// Need to allow name only cookies to handle equals at the start of
|
||||
// the value
|
||||
legacyCookieProcessor.setAllowNameOnly(true);
|
||||
|
||||
String expected;
|
||||
if (allowEquals) {
|
||||
expected = concat(COOKIES_WITH_EQUALS);
|
||||
} else {
|
||||
expected = COOKIES_WITH_EQUALS_TRUNC;
|
||||
}
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
legacyCookieProcessor, COOKIES_WITH_EQUALS, expected);
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRfc6265Equals() throws Exception {
|
||||
// Always allows equals
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
new Rfc6265CookieProcessor(), COOKIES_WITH_EQUALS, concat(COOKIES_WITH_EQUALS));
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithNameOnly() throws Exception {
|
||||
doTestLegacyNameOnly(true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithoutNameOnly() throws Exception {
|
||||
doTestLegacyNameOnly(false);
|
||||
}
|
||||
|
||||
|
||||
private void doTestLegacyNameOnly(boolean nameOnly) throws Exception {
|
||||
LegacyCookieProcessor legacyCookieProcessor = new LegacyCookieProcessor();
|
||||
legacyCookieProcessor.setAllowNameOnly(nameOnly);
|
||||
|
||||
String expected;
|
||||
if (nameOnly) {
|
||||
expected = COOKIES_WITH_NAME_ONLY_CONCAT;
|
||||
} else {
|
||||
expected = "";
|
||||
}
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
legacyCookieProcessor, COOKIES_WITH_NAME_ONLY, expected);
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRfc6265NameOnly() throws Exception {
|
||||
// Always allows equals
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
new Rfc6265CookieProcessor(), COOKIES_WITH_NAME_ONLY,
|
||||
COOKIES_WITH_NAME_ONLY_CONCAT);
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRfc6265V0() throws Exception {
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
new Rfc6265CookieProcessor(), COOKIES_V0, COOKIES_V0_CONCAT);
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRfc6265V1() throws Exception {
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
new Rfc6265CookieProcessor(), COOKIES_V1, COOKIES_V1_CONCAT);
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithSeps() throws Exception {
|
||||
doTestLegacySeps(true, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithoutSeps() throws Exception {
|
||||
doTestLegacySeps(false, true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithFwdSlash() throws Exception {
|
||||
doTestLegacySeps(true, false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyWithoutFwdSlash() throws Exception {
|
||||
doTestLegacySeps(false, false);
|
||||
}
|
||||
|
||||
|
||||
private void doTestLegacySeps(boolean seps, boolean fwdSlash) throws Exception {
|
||||
LegacyCookieProcessor legacyCookieProcessor = new LegacyCookieProcessor();
|
||||
legacyCookieProcessor.setAllowHttpSepsInV0(seps);
|
||||
legacyCookieProcessor.setForwardSlashIsSeparator(fwdSlash);
|
||||
|
||||
String expected;
|
||||
if (!seps && fwdSlash) {
|
||||
expected = COOKIES_WITH_SEPS_TRUNC;
|
||||
} else {
|
||||
expected = concat(COOKIES_WITH_SEPS);
|
||||
}
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
legacyCookieProcessor, COOKIES_WITH_SEPS, expected);
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRfc6265Seps() throws Exception {
|
||||
// Always allows equals
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
new Rfc6265CookieProcessor(), COOKIES_WITH_SEPS, concat(COOKIES_WITH_SEPS));
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLegacyPreserveHeader() throws Exception {
|
||||
LegacyCookieProcessor legacyCookieProcessor = new LegacyCookieProcessor();
|
||||
|
||||
String expected;
|
||||
expected = concat(COOKIES_WITH_QUOTES);
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(
|
||||
legacyCookieProcessor, true, COOKIES_WITH_QUOTES, expected);
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRfc6265PreserveHeader() throws Exception {
|
||||
// Always allows equals
|
||||
TestCookieParsingClient client = new TestCookieParsingClient(new Rfc6265CookieProcessor(),
|
||||
true, COOKIES_WITH_QUOTES, concat(COOKIES_WITH_QUOTES));
|
||||
client.doRequest();
|
||||
}
|
||||
|
||||
|
||||
private static String concat(String[] input) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (String s : input) {
|
||||
result.append(s);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
private class TestCookieParsingClient extends SimpleHttpClient {
|
||||
|
||||
private final CookieProcessor cookieProcessor;
|
||||
private final String[] cookies;
|
||||
private final String expected;
|
||||
private final boolean echoHeader;
|
||||
|
||||
|
||||
public TestCookieParsingClient(CookieProcessor cookieProcessor,
|
||||
String[] cookies, String expected) {
|
||||
this(cookieProcessor, false, cookies, expected);
|
||||
}
|
||||
|
||||
public TestCookieParsingClient(CookieProcessor cookieProcessor,
|
||||
boolean echoHeader, String[] cookies, String expected) {
|
||||
this.cookieProcessor = cookieProcessor;
|
||||
this.echoHeader = echoHeader;
|
||||
this.cookies = cookies;
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
|
||||
private void doRequest() throws Exception {
|
||||
Tomcat tomcat = getTomcatInstance();
|
||||
Context root = tomcat.addContext("", TEMP_DIR);
|
||||
root.setCookieProcessor(cookieProcessor);
|
||||
|
||||
if (echoHeader) {
|
||||
Tomcat.addServlet(root, "Cookies", new EchoCookieHeader());
|
||||
} else {
|
||||
Tomcat.addServlet(root, "Cookies", new EchoCookies());
|
||||
}
|
||||
root.addServletMappingDecoded("/test", "Cookies");
|
||||
|
||||
tomcat.start();
|
||||
// Open connection
|
||||
setPort(tomcat.getConnector().getLocalPort());
|
||||
connect();
|
||||
|
||||
StringBuilder request = new StringBuilder();
|
||||
request.append("GET /test HTTP/1.0");
|
||||
request.append(CRLF);
|
||||
for (String cookie : cookies) {
|
||||
request.append("Cookie: ");
|
||||
request.append(cookie);
|
||||
request.append(CRLF);
|
||||
}
|
||||
request.append(CRLF);
|
||||
setRequest(new String[] {request.toString()});
|
||||
processRequest(true); // blocks until response has been read
|
||||
String response = getResponseBody();
|
||||
|
||||
// Close the connection
|
||||
disconnect();
|
||||
reset();
|
||||
tomcat.stop();
|
||||
|
||||
Assert.assertEquals(expected, response);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isResponseBodyOK() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class EchoCookies extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
Cookie cookies[] = req.getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
resp.getWriter().write(cookie.getName() + "=" +
|
||||
cookie.getValue());
|
||||
}
|
||||
}
|
||||
resp.flushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class EchoCookieHeader extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
req.getCookies();
|
||||
// Never do this in production code. It triggers an XSS.
|
||||
Enumeration<String> cookieHeaders = req.getHeaders("Cookie");
|
||||
while (cookieHeaders.hasMoreElements()) {
|
||||
String cookieHeader = cookieHeaders.nextElement();
|
||||
resp.getWriter().write(cookieHeader);
|
||||
}
|
||||
resp.flushBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user