View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.impl.cookie;
29  
30  import java.util.ArrayList;
31  import java.util.List;
32  
33  import org.apache.http.Header;
34  import org.apache.http.cookie.ClientCookie;
35  import org.apache.http.cookie.Cookie;
36  import org.apache.http.cookie.CookieOrigin;
37  import org.apache.http.cookie.CookieSpec;
38  import org.apache.http.cookie.MalformedCookieException;
39  import org.apache.http.cookie.SetCookie2;
40  import org.apache.http.message.BasicHeader;
41  import org.junit.Assert;
42  import org.junit.Test;
43  
44  /**
45   * Test cases for 'best match' cookie policy
46   */
47  public class TestDefaultCookieSpec {
48  
49      @Test
50      public void testCookieBrowserCompatParsing() throws Exception {
51          final CookieSpec cookiespec = new DefaultCookieSpec();
52          final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false);
53  
54          // Make sure the lenient (browser compatible) cookie parsing
55          // and validation is used for Netscape style cookies
56          final Header header = new BasicHeader("Set-Cookie", "name=value;path=/;domain=domain.com");
57  
58          final List<Cookie> cookies = cookiespec.parse(header, origin);
59          for (int i = 0; i < cookies.size(); i++) {
60              cookiespec.validate(cookies.get(i), origin);
61          }
62      }
63  
64      @Test
65      public void testNetscapeCookieParsing() throws Exception {
66          final CookieSpec cookiespec = new DefaultCookieSpec();
67          final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false);
68  
69          Header header = new BasicHeader("Set-Cookie",
70              "name=value; path=/; domain=.mydomain.com; expires=Thu, 01-Jan-2070 00:00:10 GMT; comment=no_comment");
71          List<Cookie> cookies = cookiespec.parse(header, origin);
72          cookiespec.validate(cookies.get(0), origin);
73          Assert.assertEquals(1, cookies.size());
74          header = new BasicHeader("Set-Cookie",
75              "name=value; path=/; domain=.mydomain.com; expires=Thu, 01-Jan-2070 00:00:10 GMT; version=1");
76          cookies = cookiespec.parse(header, origin);
77          cookiespec.validate(cookies.get(0), origin);
78          Assert.assertEquals(1, cookies.size());
79      }
80  
81      @Test
82      public void testCookieStandardCompliantParsing() throws Exception {
83          final CookieSpec cookiespec = new DefaultCookieSpec();
84          final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false);
85  
86          // Make sure the strict (RFC2965) cookie parsing
87          // and validation is used for version 1 Set-Cookie2 headers
88          Header header = new BasicHeader("Set-Cookie2", "name=value;path=/;domain=b.domain.com; version=1");
89  
90          List<Cookie> cookies = cookiespec.parse(header, origin);
91          for (int i = 0; i < cookies.size(); i++) {
92              cookiespec.validate(cookies.get(i), origin);
93          }
94  
95          // Make sure the strict (RFC2109) cookie parsing
96          // and validation is used for version 1 Set-Cookie headers
97          header = new BasicHeader("Set-Cookie", "name=value;path=/;domain=.b.domain.com; version=1");
98  
99          cookies = cookiespec.parse(header, origin);
100         for (int i = 0; i < cookies.size(); i++) {
101             cookiespec.validate(cookies.get(i), origin);
102         }
103 
104         header = new BasicHeader("Set-Cookie2", "name=value;path=/;domain=domain.com; version=1");
105         try {
106             cookies = cookiespec.parse(header, origin);
107             cookiespec.validate(cookies.get(0), origin);
108             Assert.fail("MalformedCookieException exception should have been thrown");
109         } catch (final MalformedCookieException e) {
110             // expected
111         }
112     }
113 
114     @Test
115     public void testCookieStandardCompliantParsingLocalHost() throws Exception {
116         final CookieSpec cookiespec = new DefaultCookieSpec();
117         final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false);
118 
119         final Header header = new BasicHeader("Set-Cookie", "special=\"abcdigh\"; Version=1");
120 
121         final List<Cookie> cookies = cookiespec.parse(header, origin);
122         for (int i = 0; i < cookies.size(); i++) {
123             final Cookie cookie = cookies.get(i);
124             cookiespec.validate(cookie, origin);
125             Assert.assertEquals("localhost", cookie.getDomain());
126             Assert.assertFalse(cookie instanceof SetCookie2);
127         }
128     }
129 
130     @Test
131     public void testCookieStandardCompliantParsingLocalHost2() throws Exception {
132         final CookieSpec cookiespec = new DefaultCookieSpec();
133         final CookieOrigin origin = new CookieOrigin("localhost", 80, "/", false);
134 
135         final Header header = new BasicHeader("Set-Cookie2", "special=\"abcdigh\"; Version=1");
136 
137         final List<Cookie> cookies = cookiespec.parse(header, origin);
138         for (int i = 0; i < cookies.size(); i++) {
139             final Cookie cookie = cookies.get(i);
140             cookiespec.validate(cookie, origin);
141             Assert.assertEquals("localhost.local", cookie.getDomain());
142             Assert.assertTrue(cookie instanceof SetCookie2);
143         }
144     }
145 
146     @Test
147     public void testCookieBrowserCompatMatch() throws Exception {
148         final CookieSpec cookiespec = new DefaultCookieSpec();
149         final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false);
150 
151         // Make sure the lenient (browser compatible) cookie matching
152         // is used for Netscape style cookies
153         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
154         cookie.setDomain(".domain.com");
155         cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain());
156         cookie.setPath("/");
157         cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath());
158 
159         Assert.assertTrue(cookiespec.match(cookie, origin));
160     }
161 
162     @Test
163     public void testCookieStandardCompliantMatch() throws Exception {
164         final CookieSpec cookiespec = new DefaultCookieSpec();
165         final CookieOrigin origin = new CookieOrigin("a.b.domain.com", 80, "/", false);
166 
167         // Make sure the strict (RFC2965) cookie matching
168         // is used for version 1 cookies
169         final BasicClientCookie2 cookie = new BasicClientCookie2("name", "value");
170         cookie.setVersion(1);
171         cookie.setDomain(".domain.com");
172         cookie.setAttribute(ClientCookie.DOMAIN_ATTR, cookie.getDomain());
173         cookie.setPath("/");
174         cookie.setAttribute(ClientCookie.PATH_ATTR, cookie.getPath());
175 
176         Assert.assertFalse(cookiespec.match(cookie, origin));
177 
178         cookie.setDomain(".b.domain.com");
179 
180         Assert.assertTrue(cookiespec.match(cookie, origin));
181     }
182 
183     @Test
184     public void testCookieBrowserCompatFormatting() throws Exception {
185         final CookieSpec cookiespec = new DefaultCookieSpec();
186 
187         // Make sure the lenient (browser compatible) cookie formatting
188         // is used for Netscape style cookies
189         final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value1");
190         cookie1.setDomain(".domain.com");
191         cookie1.setAttribute(ClientCookie.DOMAIN_ATTR, cookie1.getDomain());
192         cookie1.setPath("/");
193         cookie1.setAttribute(ClientCookie.PATH_ATTR, cookie1.getPath());
194 
195         final BasicClientCookie cookie2 = new BasicClientCookie("name2", "value2");
196         cookie2.setVersion(1);
197         cookie2.setDomain(".domain.com");
198         cookie2.setAttribute(ClientCookie.DOMAIN_ATTR, cookie2.getDomain());
199         cookie2.setPath("/");
200         cookie2.setAttribute(ClientCookie.PATH_ATTR, cookie2.getPath());
201 
202         final List<Cookie> cookies = new ArrayList<Cookie>();
203         cookies.add(cookie1);
204         cookies.add(cookie2);
205 
206         final List<Header> headers = cookiespec.formatCookies(cookies);
207         Assert.assertNotNull(headers);
208         Assert.assertEquals(1, headers.size());
209 
210         final Header header = headers.get(0);
211         Assert.assertEquals("name1=value1; name2=value2", header.getValue());
212 
213     }
214 
215     @Test
216     public void testCookieStandardCompliantFormatting() throws Exception {
217         final CookieSpec cookiespec = new DefaultCookieSpec(null, true);
218 
219         // Make sure the strict (RFC2965) cookie formatting
220         // is used for Netscape style cookies
221         final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value1");
222         cookie1.setVersion(1);
223         cookie1.setDomain(".domain.com");
224         cookie1.setAttribute(ClientCookie.DOMAIN_ATTR, cookie1.getDomain());
225         cookie1.setPath("/");
226         cookie1.setAttribute(ClientCookie.PATH_ATTR, cookie1.getPath());
227 
228         final BasicClientCookie cookie2 = new BasicClientCookie("name2", "value2");
229         cookie2.setVersion(1);
230         cookie2.setDomain(".domain.com");
231         cookie2.setAttribute(ClientCookie.DOMAIN_ATTR, cookie2.getDomain());
232         cookie2.setPath("/");
233         cookie2.setAttribute(ClientCookie.PATH_ATTR, cookie2.getPath());
234 
235         final List<Cookie> cookies = new ArrayList<Cookie>();
236         cookies.add(cookie1);
237         cookies.add(cookie2);
238 
239         final List<Header> headers = cookiespec.formatCookies(cookies);
240         Assert.assertNotNull(headers);
241         Assert.assertEquals(1, headers.size());
242 
243         final Header header = headers.get(0);
244         Assert.assertEquals("$Version=1; name1=\"value1\"; $Path=\"/\"; $Domain=\".domain.com\"; " +
245                 "name2=\"value2\"; $Path=\"/\"; $Domain=\".domain.com\"",
246                 header.getValue());
247 
248     }
249 
250     @Test
251     public void testInvalidInput() throws Exception {
252         final CookieSpec cookiespec = new DefaultCookieSpec();
253         try {
254             cookiespec.parse(null, null);
255             Assert.fail("IllegalArgumentException must have been thrown");
256         } catch (final IllegalArgumentException ex) {
257             // expected
258         }
259         try {
260             cookiespec.parse(new BasicHeader("Set-Cookie", "name=value"), null);
261             Assert.fail("IllegalArgumentException must have been thrown");
262         } catch (final IllegalArgumentException ex) {
263             // expected
264         }
265         try {
266             cookiespec.formatCookies(null);
267             Assert.fail("IllegalArgumentException must have been thrown");
268         } catch (final IllegalArgumentException ex) {
269             // expected
270         }
271         try {
272             final List<Cookie> cookies = new ArrayList<Cookie>();
273             cookiespec.formatCookies(cookies);
274             Assert.fail("IllegalArgumentException must have been thrown");
275         } catch (final IllegalArgumentException ex) {
276             // expected
277         }
278     }
279 
280     @Test
281     public void testVersion1CookieWithInvalidExpires() throws Exception {
282         final CookieSpec cookiespec = new DefaultCookieSpec();
283         final CookieOrigin origin = new CookieOrigin("myhost.mydomain.com", 80, "/", false);
284 
285         final Header origHeader = new BasicHeader("Set-Cookie",
286                 "test=\"test\"; Version=1; Expires=Mon, 11-Feb-2013 10:39:19 GMT; Path=/");
287         final List<Cookie> cookies = cookiespec.parse(origHeader, origin);
288         Assert.assertNotNull(cookies);
289         Assert.assertEquals(1, cookies.size());
290 
291         final List<Header> headers = cookiespec.formatCookies(cookies);
292         Assert.assertNotNull(headers);
293         Assert.assertEquals(1, headers.size());
294         final Header header1 = headers.get(0);
295         Assert.assertEquals("test=\"test\"", header1.getValue());
296     }
297 
298 }
299