/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * Licensed 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 com.alibaba.citrus.service.requestcontext.util; import static com.alibaba.citrus.test.TestUtil.*; import static org.junit.Assert.*; import java.text.DateFormat; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Locale; import com.alibaba.citrus.service.requestcontext.AbstractRequestContextsTests; import com.alibaba.citrus.service.requestcontext.RequestContext; import com.alibaba.citrus.util.internal.Servlet3Util; import org.junit.Before; import org.junit.Test; /** * 测试<code>CookieSupport</code>。 * * @author Michael Zhou */ public class CookieSupportTests extends AbstractRequestContextsTests<RequestContext> { private DateFormat fmt; private CookieSupport cookie; @Before public void init() throws Exception { cookie = new CookieSupport("myname", "myvalue"); assertCookie("myname=myvalue", cookie); fmt = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.US); } @Test public void copyConstructors() { CookieSupport newCookie; assertCookie("myname=myvalue", newCookie = new CookieSupport(cookie)); assertCookie("myname=myvalue", newCookie = new CookieSupport(cookie, " ")); assertCookie("newName=myvalue", newCookie = new CookieSupport(cookie, " newName ")); assertEquals("newName", newCookie.getName()); assertEquals("myvalue", newCookie.getValue()); assertNull(newCookie.getDomain()); assertNull(newCookie.getPath()); } public void getHeaderName() { assertEquals("Set-Cookie", cookie.getCookieHeaderName()); } @Test public void getHeaderValue_invalid() { // 包含控制字符 String name = Servlet3Util.isServlet3() ? "myname" : "my\"name\""; // servlet3 cookie name不能有控制字符 cookie = new CookieSupport(name, "my\nvalu\te"); try { cookie.getCookieHeaderValue(); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("Control character in cookie value, consider BASE64 encoding your value")); } // escape错误 cookie = new CookieSupport("myname", "\"my value\\"); try { cookie.getCookieHeaderValue(); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("Invalid escape character in cookie value")); } cookie = new CookieSupport("myname", "\"my value\\\""); try { cookie.getCookieHeaderValue(); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("Invalid escape character in cookie value")); } } @Test public void toString_invalid() { // 包含控制字符 String name = Servlet3Util.isServlet3() ? "myname" : "my\"name\""; // servlet3 cookie name不能有控制字符 cookie = new CookieSupport(name, "my\nvalu\te"); assertEquals("Set-Cookie: Control character in cookie value, consider BASE64 encoding your value", cookie.toString()); // escape错误 cookie = new CookieSupport("myname", "\"my value\\"); assertEquals("Set-Cookie: Invalid escape character in cookie value.", cookie.toString()); } @Test public void cookie_empty_value() { cookie = new CookieSupport("myname", " "); assertCookie("myname=\" \"; Version=1; Discard", cookie); cookie = new CookieSupport("myname", ""); assertCookie("myname=; Expires=Thu, 01-Jan-1970 00:00:10 GMT", cookie); cookie = new CookieSupport("myname", null); assertCookie("myname=; Expires=Thu, 01-Jan-1970 00:00:10 GMT", cookie); } @Test public void cookie_value_quote() { cookie = new CookieSupport("myname", "\\r\\n"); assertCookie("myname=\"\\r\\n\"; Version=1; Discard", cookie); // already quoted cookie = new CookieSupport("myname", "\"abc\\\"\""); assertCookie("myname=\"abc\\\"\"", cookie); // not quoted yet cookie = new CookieSupport("myname", "\\rabc\""); assertCookie("myname=\"\\rabc\\\"\"; Version=1; Discard", cookie); cookie = new CookieSupport("myname", "\\\\rabc\""); assertCookie("myname=\"\\\\rabc\\\"\"; Version=1; Discard", cookie); } @Test public void cookie_value() { cookie = new CookieSupport("myname", "abc"); assertCookie("myname=abc", cookie); cookie = new CookieSupport("myname", "a b"); assertCookie("myname=\"a b\"; Version=1; Discard", cookie); } @Test public void cookies_maxage_v0() throws ParseException { // maxAge=-1, temp cookie cookie.setMaxAge(-1); assertCookie("myname=myvalue", cookie); // maxAge=0, remove cookie cookie.setMaxAge(0); assertCookie("myname=myvalue; Expires=Thu, 01-Jan-1970 00:00:10 GMT", cookie); // maxAge is 1 second or 1000 milliseconds cookie.setMaxAge(1); long currentTime = System.currentTimeMillis(); String result = cookie.getCookieHeaderValue(); String expectedPrefix = "myname=myvalue; Expires="; assertTrue(result.startsWith(expectedPrefix)); long resultTime = fmt.parse(result, new ParsePosition(expectedPrefix.length())).getTime(); long diff = resultTime - currentTime; assertTrue(diff < 1000); } @Test public void cookies_maxage_v1() throws ParseException { cookie.setVersion(1); // maxAge=-1, temp cookie cookie.setMaxAge(-1); assertCookie("myname=myvalue; Version=1; Discard", cookie); // maxAge=0, remove cookie, ALWAYS_ADD_EXPIRES cookie.setMaxAge(0); assertCookie("myname=myvalue; Version=1; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT", cookie); // maxAge is 1 second or 1000 milliseconds, ALWAYS_ADD_EXPIRES cookie.setMaxAge(1); long currentTime = System.currentTimeMillis(); String result = cookie.getCookieHeaderValue(); String expectedPrefix = "myname=myvalue; Version=1; Max-Age=1; Expires="; assertTrue(result.startsWith(expectedPrefix)); long resultTime = fmt.parse(result, new ParsePosition(expectedPrefix.length())).getTime(); long diff = resultTime - currentTime; assertTrue(diff < 1000); } @Test public void cookie_comment_v0() { cookie.setComment("simple"); assertCookie("myname=myvalue", cookie); cookie.setComment("\"quoted\" comment!"); assertCookie("myname=myvalue", cookie); } @Test public void cookie_comment_v1() { cookie.setVersion(1); cookie.setComment("simple"); assertCookie("myname=myvalue; Version=1; Comment=simple; Discard", cookie); cookie.setComment("\"quoted\" comment!"); assertCookie("myname=myvalue; Version=1; Comment=\"\\\"quoted\\\" comment!\"; Discard", cookie); } @Test public void cookie_domain() { cookie.setDomain(".SINA.COM.CN"); assertEquals(".sina.com.cn", cookie.getDomain()); assertCookie("myname=myvalue; Domain=.sina.com.cn", cookie); cookie.setDomain("SINA.COM.CN"); assertEquals(".sina.com.cn", cookie.getDomain()); assertCookie("myname=myvalue; Domain=.sina.com.cn", cookie); cookie.setDomain(" "); assertEquals("", cookie.getDomain()); assertCookie("myname=myvalue", cookie); cookie.setDomain(null); assertEquals("", cookie.getDomain()); assertCookie("myname=myvalue", cookie); } @Test public void cookie_path() { cookie.setPath("/aabb"); assertCookie("myname=myvalue; Path=/aabb", cookie); cookie.setPath("/aa bb"); assertCookie("myname=myvalue; Path=\"/aa bb\"", cookie); cookie.setPath("/aa bb"); cookie.setVersion(1); assertCookie("myname=myvalue; Version=1; Discard; Path=\"/aa bb\"", cookie); } @Test public void cookie_secure() { cookie.setSecure(true); assertCookie("myname=myvalue; Secure", cookie); } @Test public void cookie_httpOnly() { cookie.setHttpOnly(true); assertCookie("myname=myvalue; HttpOnly", cookie); } @Test public void cookie_all_params_v0() { cookie = new CookieSupport("myname", "myvalue"); cookie.setMaxAge(0); cookie.setComment("hello! comment!"); cookie.setVersion(0); cookie.setDomain("WWW.SINA.COM.CN"); cookie.setSecure(true); cookie.setPath("/aa/bb"); cookie.setHttpOnly(true); assertEquals("myname=myvalue; Domain=.www.sina.com.cn; Expires=Thu, 01-Jan-1970 00:00:10 GMT; " + "Path=/aa/bb; Secure; HttpOnly", cookie.getCookieHeaderValue()); // test copy constructor assertEquals("myname=myvalue; Domain=.www.sina.com.cn; Expires=Thu, 01-Jan-1970 00:00:10 GMT; " + "Path=/aa/bb; Secure; HttpOnly", new CookieSupport(cookie).getCookieHeaderValue()); } @Test public void cookie_all_params_v1() { cookie = new CookieSupport("myname", "myvalue"); cookie.setMaxAge(0); cookie.setComment("hello! comment!"); cookie.setVersion(1); cookie.setDomain("WWW.SINA.COM.CN"); cookie.setSecure(true); cookie.setPath("/aa/bb"); cookie.setHttpOnly(true); assertEquals("myname=myvalue; Version=1; Comment=\"hello! comment!\"; " + "Domain=.www.sina.com.cn; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; " + "Path=/aa/bb; Secure; HttpOnly", cookie.getCookieHeaderValue()); // test copy constructor assertEquals("myname=myvalue; Version=1; Comment=\"hello! comment!\"; " + "Domain=.www.sina.com.cn; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; " + "Path=/aa/bb; Secure; HttpOnly", new CookieSupport(cookie).getCookieHeaderValue()); } @Test public void addCookie() throws Exception { // request 1: add myname invokeNoopServlet("/servlet"); cookie.addCookie(response); commitToClient(); assertArrayEquals(new String[] { "myname=myvalue" }, clientResponse.getHeaderFields("set-cookie")); // request 2: check myname invokeNoopServlet("/servlet"); assertEquals(1, request.getCookies().length); cookie = new CookieSupport(request.getCookies()[0]); assertCookie("myname=myvalue", cookie); commitToClient(); assertArrayEquals(new String[] { }, clientResponse.getHeaderFields("set-cookie")); } private void assertCookie(String value, CookieSupport cookie) { assertEquals("Set-Cookie", cookie.getCookieHeaderName()); assertEquals(value, cookie.getCookieHeaderValue()); assertEquals("Set-Cookie: " + value, cookie.toString()); } }