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.hc.client5.http.impl.cookie;
29  
30  import java.time.Instant;
31  import java.util.Arrays;
32  
33  import org.apache.hc.client5.http.cookie.Cookie;
34  import org.apache.hc.client5.http.cookie.CookieAttributeHandler;
35  import org.apache.hc.client5.http.cookie.CookieOrigin;
36  import org.apache.hc.client5.http.cookie.MalformedCookieException;
37  import org.apache.hc.client5.http.psl.DomainType;
38  import org.apache.hc.client5.http.psl.PublicSuffixMatcher;
39  import org.apache.hc.client5.http.utils.DateUtils;
40  import org.junit.jupiter.api.Assertions;
41  import org.junit.jupiter.api.Test;
42  
43  public class TestBasicCookieAttribHandlers {
44  
45      @Test
46      public void testBasicDomainParse() throws Exception {
47          final BasicClientCookie cookie = new BasicClientCookie("name", "value");
48          final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
49          h.parse(cookie, "www.somedomain.com");
50          Assertions.assertEquals("www.somedomain.com", cookie.getDomain());
51      }
52  
53      @Test
54      public void testBasicDomainParseInvalid1() throws Exception {
55          final BasicClientCookie cookie = new BasicClientCookie("name", "value");
56          final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
57          Assertions.assertThrows(MalformedCookieException.class, () ->
58                  h.parse(cookie, ""));
59      }
60  
61      @Test
62      public void testBasicDomainParseInvalid2() throws Exception {
63          final BasicClientCookie cookie = new BasicClientCookie("name", "value");
64          final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
65          Assertions.assertThrows(MalformedCookieException.class, () ->
66                  h.parse(cookie, null));
67      }
68  
69      @Test
70      public void testBasicDomainValidate1() throws Exception {
71          final BasicClientCookie cookie = new BasicClientCookie("name", "value");
72          final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false);
73          final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
74  
75          cookie.setDomain(".somedomain.com");
76          h.validate(cookie, origin);
77  
78          cookie.setDomain(".otherdomain.com");
79          Assertions.assertThrows(MalformedCookieException.class, () -> h.validate(cookie, origin));
80          cookie.setDomain("www.otherdomain.com");
81          Assertions.assertThrows(MalformedCookieException.class, () -> h.validate(cookie, origin));
82      }
83  
84      @Test
85      public void testBasicDomainValidate2() throws Exception {
86          final BasicClientCookie cookie = new BasicClientCookie("name", "value");
87          final CookieOrigin origin = new CookieOrigin("somehost", 80, "/", false);
88          final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
89  
90          cookie.setDomain("somehost");
91          h.validate(cookie, origin);
92  
93          cookie.setDomain("otherhost");
94          Assertions.assertThrows(MalformedCookieException.class, () -> h.validate(cookie, origin));
95      }
96  
97      @Test
98      public void testBasicDomainValidate3() throws Exception {
99          final BasicClientCookie cookie = new BasicClientCookie("name", "value");
100         final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false);
101         final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
102 
103         cookie.setDomain(".somedomain.com");
104         h.validate(cookie, origin);
105     }
106 
107     @Test
108     public void testBasicDomainValidate4() throws Exception {
109         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
110         final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false);
111         final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
112 
113         cookie.setDomain(null);
114         Assertions.assertThrows(MalformedCookieException.class, () -> h.validate(cookie, origin));
115     }
116 
117     @Test
118     public void testBasicDomainMatch1() throws Exception {
119         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
120         final CookieOrigin origin = new CookieOrigin("somedomain.com", 80, "/", false);
121         final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
122 
123         cookie.setDomain("somedomain.com");
124         cookie.setAttribute(Cookie.DOMAIN_ATTR, "somedomain.com");
125         Assertions.assertTrue(h.match(cookie, origin));
126 
127         cookie.setDomain(".somedomain.com");
128         Assertions.assertTrue(h.match(cookie, origin));
129     }
130 
131     @Test
132     public void testBasicDomainMatch2() throws Exception {
133         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
134         final CookieOrigin origin = new CookieOrigin("www.somedomain.com", 80, "/", false);
135         final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
136 
137         cookie.setDomain("somedomain.com");
138         cookie.setAttribute(Cookie.DOMAIN_ATTR, "somedomain.com");
139         Assertions.assertTrue(h.match(cookie, origin));
140 
141         cookie.setDomain(".somedomain.com");
142         Assertions.assertTrue(h.match(cookie, origin));
143 
144         cookie.setDomain(null);
145         Assertions.assertFalse(h.match(cookie, origin));
146     }
147 
148     @Test
149     public void testBasicDomainMatchOneLetterPrefix() throws Exception {
150         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
151         final CookieOrigin origin = new CookieOrigin("a.somedomain.com", 80, "/", false);
152         final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
153 
154         cookie.setDomain("somedomain.com");
155         cookie.setAttribute(Cookie.DOMAIN_ATTR, "somedomain.com");
156         Assertions.assertTrue(h.match(cookie, origin));
157     }
158 
159     @Test
160     public void testBasicDomainMatchMixedCase() throws Exception {
161         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
162         final CookieOrigin origin = new CookieOrigin("a.SomeDomain.com", 80, "/", false);
163         final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
164 
165         cookie.setDomain("somedoMain.Com");
166         cookie.setAttribute(Cookie.DOMAIN_ATTR, "somedoMain.Com");
167         Assertions.assertTrue(h.match(cookie, origin));
168     }
169 
170     @Test
171     public void testBasicDomainInvalidInput() throws Exception {
172         final CookieAttributeHandler h = BasicDomainHandler.INSTANCE;
173         Assertions.assertThrows(NullPointerException.class, () -> h.parse(null, null));
174         Assertions.assertThrows(NullPointerException.class, () -> h.validate(null, null));
175         Assertions.assertThrows(NullPointerException.class, () ->
176                 h.validate(new BasicClientCookie("name", "value"), null));
177         Assertions.assertThrows(NullPointerException.class, () -> h.match(null, null));
178         Assertions.assertThrows(NullPointerException.class, () ->
179                 h.match(new BasicClientCookie("name", "value"), null));
180     }
181 
182     @Test
183     public void testBasicPathParse() throws Exception {
184         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
185         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
186         h.parse(cookie, "stuff");
187         Assertions.assertEquals("stuff", cookie.getPath());
188         h.parse(cookie, "");
189         Assertions.assertEquals("/", cookie.getPath());
190         h.parse(cookie, null);
191         Assertions.assertEquals("/", cookie.getPath());
192     }
193 
194     @Test
195     public void testBasicPathMatch1() throws Exception {
196         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
197         final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff", false);
198         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
199         cookie.setPath("/stuff");
200         Assertions.assertTrue(h.match(cookie, origin));
201     }
202 
203     @Test
204     public void testBasicPathMatch2() throws Exception {
205         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
206         final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff/", false);
207         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
208         cookie.setPath("/stuff");
209         Assertions.assertTrue(h.match(cookie, origin));
210     }
211 
212     @Test
213     public void testBasicPathMatch3() throws Exception {
214         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
215         final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff/more-stuff", false);
216         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
217         cookie.setPath("/stuff");
218         Assertions.assertTrue(h.match(cookie, origin));
219     }
220 
221     @Test
222     public void testBasicPathMatch4() throws Exception {
223         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
224         final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuffed", false);
225         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
226         cookie.setPath("/stuff");
227         Assertions.assertFalse(h.match(cookie, origin));
228     }
229 
230     @Test
231     public void testBasicPathMatch5() throws Exception {
232         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
233         final CookieOrigin origin = new CookieOrigin("somehost", 80, "/otherstuff", false);
234         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
235         cookie.setPath("/stuff");
236         Assertions.assertFalse(h.match(cookie, origin));
237     }
238 
239     @Test
240     public void testBasicPathMatch6() throws Exception {
241         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
242         final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff", false);
243         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
244         cookie.setPath("/stuff/");
245         Assertions.assertTrue(h.match(cookie, origin));
246     }
247 
248     @Test
249     public void testBasicPathMatch7() throws Exception {
250         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
251         final CookieOrigin origin = new CookieOrigin("somehost", 80, "/stuff", false);
252         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
253         Assertions.assertTrue(h.match(cookie, origin));
254     }
255 
256     @Test
257     public void testBasicPathInvalidInput() throws Exception {
258         final CookieAttributeHandler h = BasicPathHandler.INSTANCE;
259         Assertions.assertThrows(NullPointerException.class, () -> h.parse(null, null));
260         Assertions.assertThrows(NullPointerException.class, () -> h.match(null, null));
261         Assertions.assertThrows(NullPointerException.class, () ->
262                 h.match(new BasicClientCookie("name", "value"), null));
263     }
264 
265     @Test
266     public void testBasicMaxAgeParse() throws Exception {
267         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
268         final CookieAttributeHandler h = BasicMaxAgeHandler.INSTANCE;
269         h.parse(cookie, "2000");
270         Assertions.assertNotNull(cookie.getExpiryInstant());
271     }
272 
273     @Test
274     public void testBasicMaxAgeParseInvalid() throws Exception {
275         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
276         final CookieAttributeHandler h = BasicMaxAgeHandler.INSTANCE;
277         Assertions.assertThrows(MalformedCookieException.class, () -> h.parse(cookie, "garbage"));
278         Assertions.assertThrows(MalformedCookieException.class, () -> h.parse(cookie, null));
279     }
280 
281     @Test
282     public void testBasicMaxAgeInvalidInput() throws Exception {
283         final CookieAttributeHandler h = BasicMaxAgeHandler.INSTANCE;
284         Assertions.assertThrows(NullPointerException.class, () -> h.parse(null, null));
285     }
286 
287     @Test
288     public void testBasicSecureParse() throws Exception {
289         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
290         final CookieAttributeHandler h = BasicSecureHandler.INSTANCE;
291         h.parse(cookie, "whatever");
292         Assertions.assertTrue(cookie.isSecure());
293         h.parse(cookie, null);
294         Assertions.assertTrue(cookie.isSecure());
295     }
296 
297     @Test
298     public void testBasicSecureMatch() throws Exception {
299         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
300         final CookieAttributeHandler h = BasicSecureHandler.INSTANCE;
301 
302         final CookieOrigin origin1 = new CookieOrigin("somehost", 80, "/stuff", false);
303         cookie.setSecure(false);
304         Assertions.assertTrue(h.match(cookie, origin1));
305         cookie.setSecure(true);
306         Assertions.assertFalse(h.match(cookie, origin1));
307 
308         final CookieOrigin origin2 = new CookieOrigin("somehost", 80, "/stuff", true);
309         cookie.setSecure(false);
310         Assertions.assertTrue(h.match(cookie, origin2));
311         cookie.setSecure(true);
312         Assertions.assertTrue(h.match(cookie, origin2));
313     }
314 
315     @Test
316     public void testBasicSecureInvalidInput() throws Exception {
317         final CookieAttributeHandler h = new BasicSecureHandler();
318         Assertions.assertThrows(NullPointerException.class, () -> h.parse(null, null));
319         Assertions.assertThrows(NullPointerException.class, () -> h.match(null, null));
320         Assertions.assertThrows(NullPointerException.class, () ->
321                 h.match(new BasicClientCookie("name", "value"), null));
322     }
323 
324     @Test
325     public void testBasicExpiresParse() throws Exception {
326         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
327         final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123);
328 
329         h.parse(cookie, DateUtils.formatStandardDate(Instant.now()));
330         Assertions.assertNotNull(cookie.getExpiryInstant());
331     }
332 
333     @Test
334     public void testBasicExpiresParseInvalid() throws Exception {
335         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
336         final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123);
337         Assertions.assertThrows(MalformedCookieException.class, () ->
338                 h.parse(cookie, "garbage"));
339         Assertions.assertThrows(MalformedCookieException.class, () ->
340                 h.parse(cookie, null));
341     }
342 
343     @SuppressWarnings("unused")
344     @Test
345     public void testBasicExpiresInvalidInput() throws Exception {
346         final CookieAttributeHandler h = new BasicExpiresHandler(DateUtils.FORMATTER_RFC1123);
347         Assertions.assertThrows(NullPointerException.class, () -> h.parse(null, null));
348     }
349 
350     @Test
351     public void testPublicSuffixFilter() throws Exception {
352         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
353 
354         final PublicSuffixMatcher matcher = new PublicSuffixMatcher(DomainType.ICANN, Arrays.asList("co.uk", "com"), null);
355         final PublicSuffixDomainFilter h = new PublicSuffixDomainFilter(BasicDomainHandler.INSTANCE, matcher);
356 
357         cookie.setDomain(".co.uk");
358         cookie.setAttribute(Cookie.DOMAIN_ATTR, ".co.uk");
359         Assertions.assertFalse(h.match(cookie, new CookieOrigin("apache.co.uk", 80, "/stuff", false)));
360 
361         cookie.setDomain("co.uk");
362         cookie.setAttribute(Cookie.DOMAIN_ATTR, "co.uk");
363         Assertions.assertFalse(h.match(cookie, new CookieOrigin("apache.co.uk", 80, "/stuff", false)));
364 
365         cookie.setDomain(".co.com");
366         cookie.setAttribute(Cookie.DOMAIN_ATTR, ".co.com");
367         Assertions.assertTrue(h.match(cookie, new CookieOrigin("apache.co.com", 80, "/stuff", false)));
368 
369         cookie.setDomain("co.com");
370         cookie.setAttribute(Cookie.DOMAIN_ATTR, "co.com");
371         Assertions.assertTrue(h.match(cookie, new CookieOrigin("apache.co.com", 80, "/stuff", false)));
372 
373         cookie.setDomain(".com");
374         cookie.setAttribute(Cookie.DOMAIN_ATTR, ".com");
375         Assertions.assertFalse(h.match(cookie, new CookieOrigin("apache.com", 80, "/stuff", false)));
376 
377         cookie.setDomain("com");
378         cookie.setAttribute(Cookie.DOMAIN_ATTR, "com");
379         Assertions.assertFalse(h.match(cookie, new CookieOrigin("apache.com", 80, "/stuff", false)));
380 
381         cookie.setDomain("apache.com");
382         cookie.setAttribute(Cookie.DOMAIN_ATTR, "apache.com");
383         Assertions.assertTrue(h.match(cookie, new CookieOrigin("apache.com", 80, "/stuff", false)));
384 
385         cookie.setDomain(".apache.com");
386         cookie.setAttribute(Cookie.DOMAIN_ATTR, ".apache.com");
387         Assertions.assertTrue(h.match(cookie, new CookieOrigin("www.apache.com", 80, "/stuff", false)));
388 
389         cookie.setDomain("localhost");
390         cookie.setAttribute(Cookie.DOMAIN_ATTR, "localhost");
391         Assertions.assertTrue(h.match(cookie, new CookieOrigin("localhost", 80, "/stuff", false)));
392     }
393     @Test
394     public void testBasicHttpOnlyParse() throws Exception {
395         final BasicClientCookie cookie = new BasicClientCookie("name", "value");
396         final CookieAttributeHandler h = new BasicHttpOnlyHandler();
397         h.parse(cookie, "true");
398         Assertions.assertTrue(cookie.isHttpOnly());
399         h.parse(cookie, "anyone");
400         Assertions.assertTrue(cookie.isHttpOnly());
401     }
402 
403 }