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  package org.apache.http.client.protocol;
28  
29  import java.util.Date;
30  
31  import org.apache.http.Header;
32  import org.apache.http.HttpHost;
33  import org.apache.http.HttpRequest;
34  import org.apache.http.HttpRequestInterceptor;
35  import org.apache.http.client.CookieStore;
36  import org.apache.http.client.config.CookieSpecs;
37  import org.apache.http.client.config.RequestConfig;
38  import org.apache.http.config.Lookup;
39  import org.apache.http.config.RegistryBuilder;
40  import org.apache.http.conn.routing.HttpRoute;
41  import org.apache.http.conn.routing.RouteInfo.LayerType;
42  import org.apache.http.conn.routing.RouteInfo.TunnelType;
43  import org.apache.http.cookie.CookieOrigin;
44  import org.apache.http.cookie.CookieSpec;
45  import org.apache.http.cookie.CookieSpecProvider;
46  import org.apache.http.cookie.SM;
47  import org.apache.http.impl.client.BasicCookieStore;
48  import org.apache.http.impl.cookie.BasicClientCookie;
49  import org.apache.http.impl.cookie.BasicClientCookie2;
50  import org.apache.http.impl.cookie.DefaultCookieSpecProvider;
51  import org.apache.http.impl.cookie.IgnoreSpecProvider;
52  import org.apache.http.impl.cookie.NetscapeDraftSpec;
53  import org.apache.http.impl.cookie.NetscapeDraftSpecProvider;
54  import org.apache.http.impl.cookie.RFC2965SpecProvider;
55  import org.apache.http.message.BasicHttpRequest;
56  import org.apache.http.protocol.HttpCoreContext;
57  import org.junit.Assert;
58  import org.junit.Before;
59  import org.junit.Test;
60  import org.mockito.Matchers;
61  import org.mockito.Mockito;
62  
63  public class TestRequestAddCookies {
64  
65      private HttpHost target;
66      private CookieStore cookieStore;
67      private Lookup<CookieSpecProvider> cookieSpecRegistry;
68  
69      @Before
70      public void setUp() {
71          this.target = new HttpHost("localhost.local", 80);
72          this.cookieStore = new BasicCookieStore();
73          final BasicClientCookie2 cookie1 = new BasicClientCookie2("name1", "value1");
74          cookie1.setVersion(1);
75          cookie1.setDomain("localhost.local");
76          cookie1.setPath("/");
77          this.cookieStore.addCookie(cookie1);
78          final BasicClientCookie2 cookie2 = new BasicClientCookie2("name2", "value2");
79          cookie2.setVersion(1);
80          cookie2.setDomain("localhost.local");
81          cookie2.setPath("/");
82          this.cookieStore.addCookie(cookie2);
83  
84          this.cookieSpecRegistry = RegistryBuilder.<CookieSpecProvider>create()
85              .register(CookieSpecs.DEFAULT, new DefaultCookieSpecProvider())
86              .register(CookieSpecs.STANDARD, new RFC2965SpecProvider())
87              .register(CookieSpecs.NETSCAPE, new NetscapeDraftSpecProvider())
88              .register(CookieSpecs.IGNORE_COOKIES, new IgnoreSpecProvider())
89              .build();
90      }
91  
92      @Test(expected=IllegalArgumentException.class)
93      public void testRequestParameterCheck() throws Exception {
94          final HttpClientContext context = HttpClientContext.create();
95          final HttpRequestInterceptor interceptor = new RequestAddCookies();
96          interceptor.process(null, context);
97      }
98  
99      @Test(expected=IllegalArgumentException.class)
100     public void testContextParameterCheck() throws Exception {
101         final HttpRequest request = new BasicHttpRequest("GET", "/");
102         final HttpRequestInterceptor interceptor = new RequestAddCookies();
103         interceptor.process(request, null);
104     }
105 
106     @Test
107     public void testAddCookies() throws Exception {
108         final HttpRequest request = new BasicHttpRequest("GET", "/");
109 
110         final HttpRoute route = new HttpRoute(this.target, null, false);
111 
112         final HttpClientContext context = HttpClientContext.create();
113         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
114         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
115         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
116         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
117 
118         final HttpRequestInterceptor interceptor = new RequestAddCookies();
119         interceptor.process(request, context);
120 
121         final Header[] headers1 = request.getHeaders(SM.COOKIE);
122         Assert.assertNotNull(headers1);
123         Assert.assertEquals(2, headers1.length);
124         Assert.assertEquals("$Version=1; name1=\"value1\"", headers1[0].getValue());
125         Assert.assertEquals("$Version=1; name2=\"value2\"", headers1[1].getValue());
126         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
127         Assert.assertNotNull(headers2);
128         Assert.assertEquals(0, headers2.length);
129 
130         final CookieOrigin cookieOrigin = context.getCookieOrigin();
131         Assert.assertNotNull(cookieOrigin);
132         Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost());
133         Assert.assertEquals(this.target.getPort(), cookieOrigin.getPort());
134         Assert.assertEquals("/", cookieOrigin.getPath());
135         Assert.assertFalse(cookieOrigin.isSecure());
136     }
137 
138     @Test
139     public void testCookiesForConnectRequest() throws Exception {
140         final HttpRequest request = new BasicHttpRequest("CONNECT", "www.somedomain.com");
141 
142         final HttpRoute route = new HttpRoute(this.target, null, false);
143 
144         final HttpClientContext context = HttpClientContext.create();
145         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
146         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
147         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
148         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
149 
150         final HttpRequestInterceptor interceptor = new RequestAddCookies();
151         interceptor.process(request, context);
152 
153         final Header[] headers1 = request.getHeaders(SM.COOKIE);
154         Assert.assertNotNull(headers1);
155         Assert.assertEquals(0, headers1.length);
156         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
157         Assert.assertNotNull(headers2);
158         Assert.assertEquals(0, headers2.length);
159     }
160 
161     @Test
162     public void testNoCookieStore() throws Exception {
163         final HttpRequest request = new BasicHttpRequest("GET", "/");
164 
165         final HttpRoute route = new HttpRoute(this.target, null, false);
166 
167         final HttpClientContext context = HttpClientContext.create();
168         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
169         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
170         context.setAttribute(HttpClientContext.COOKIE_STORE, null);
171         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
172 
173         final HttpRequestInterceptor interceptor = new RequestAddCookies();
174         interceptor.process(request, context);
175 
176         final Header[] headers1 = request.getHeaders(SM.COOKIE);
177         Assert.assertNotNull(headers1);
178         Assert.assertEquals(0, headers1.length);
179         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
180         Assert.assertNotNull(headers2);
181         Assert.assertEquals(0, headers2.length);
182     }
183 
184     @Test
185     public void testNoCookieSpecRegistry() throws Exception {
186         final HttpRequest request = new BasicHttpRequest("GET", "/");
187 
188         final HttpRoute route = new HttpRoute(this.target, null, false);
189 
190         final HttpClientContext context = HttpClientContext.create();
191         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
192         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
193         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
194         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, null);
195 
196         final HttpRequestInterceptor interceptor = new RequestAddCookies();
197         interceptor.process(request, context);
198 
199         final Header[] headers1 = request.getHeaders(SM.COOKIE);
200         Assert.assertNotNull(headers1);
201         Assert.assertEquals(0, headers1.length);
202         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
203         Assert.assertNotNull(headers2);
204         Assert.assertEquals(0, headers2.length);
205     }
206 
207     @Test
208     public void testNoTargetHost() throws Exception {
209         final HttpRequest request = new BasicHttpRequest("GET", "/");
210 
211         final HttpRoute route = new HttpRoute(this.target, null, false);
212 
213         final HttpClientContext context = HttpClientContext.create();
214         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, null);
215         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
216         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
217         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
218 
219         final HttpRequestInterceptor interceptor = new RequestAddCookies();
220         interceptor.process(request, context);
221 
222         final Header[] headers1 = request.getHeaders(SM.COOKIE);
223         Assert.assertNotNull(headers1);
224         Assert.assertEquals(0, headers1.length);
225         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
226         Assert.assertNotNull(headers2);
227         Assert.assertEquals(0, headers2.length);
228     }
229 
230     @Test
231     public void testNoHttpConnection() throws Exception {
232         final HttpRequest request = new BasicHttpRequest("GET", "/");
233 
234         final HttpClientContext context = HttpClientContext.create();
235         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
236         context.setAttribute(HttpCoreContext.HTTP_CONNECTION, null);
237         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
238         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
239 
240         final HttpRequestInterceptor interceptor = new RequestAddCookies();
241         interceptor.process(request, context);
242 
243         final Header[] headers1 = request.getHeaders(SM.COOKIE);
244         Assert.assertNotNull(headers1);
245         Assert.assertEquals(0, headers1.length);
246         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
247         Assert.assertNotNull(headers2);
248         Assert.assertEquals(0, headers2.length);
249     }
250 
251     @Test
252     public void testAddCookiesUsingExplicitCookieSpec() throws Exception {
253         final HttpRequest request = new BasicHttpRequest("GET", "/");
254         final RequestConfig config = RequestConfig.custom()
255             .setCookieSpec(CookieSpecs.NETSCAPE).build();
256         final HttpRoute route = new HttpRoute(this.target, null, false);
257 
258         final HttpClientContext context = HttpClientContext.create();
259         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
260         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
261         context.setAttribute(HttpClientContext.REQUEST_CONFIG, config);
262         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
263         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
264 
265         final HttpRequestInterceptor interceptor = new RequestAddCookies();
266         interceptor.process(request, context);
267 
268         final CookieSpec cookieSpec = context.getCookieSpec();
269         Assert.assertTrue(cookieSpec instanceof NetscapeDraftSpec);
270 
271         final Header[] headers1 = request.getHeaders(SM.COOKIE);
272         Assert.assertNotNull(headers1);
273         Assert.assertEquals(1, headers1.length);
274         Assert.assertEquals("name1=value1; name2=value2", headers1[0].getValue());
275     }
276 
277     @Test
278     public void testAuthScopeInvalidRequestURI() throws Exception {
279         final HttpRequest request = new BasicHttpRequest("GET", "crap:");
280 
281         final HttpRoute route = new HttpRoute(this.target, null, false);
282 
283         final HttpClientContext context = HttpClientContext.create();
284         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
285         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
286         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
287         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
288 
289         final HttpRequestInterceptor interceptor = new RequestAddCookies();
290         interceptor.process(request, context);
291     }
292 
293     @Test
294     public void testAuthScopeRemotePortWhenDirect() throws Exception {
295         final HttpRequest request = new BasicHttpRequest("GET", "/stuff");
296 
297         this.target = new HttpHost("localhost.local");
298         final HttpRoute route = new HttpRoute(new HttpHost("localhost.local", 1234), null, false);
299 
300         final HttpClientContext context = HttpClientContext.create();
301         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
302         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
303         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
304         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
305 
306         final HttpRequestInterceptor interceptor = new RequestAddCookies();
307         interceptor.process(request, context);
308 
309         final CookieOrigin cookieOrigin = context.getCookieOrigin();
310         Assert.assertNotNull(cookieOrigin);
311         Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost());
312         Assert.assertEquals(1234, cookieOrigin.getPort());
313         Assert.assertEquals("/stuff", cookieOrigin.getPath());
314         Assert.assertFalse(cookieOrigin.isSecure());
315     }
316 
317     @Test
318     public void testAuthDefaultHttpPortWhenProxy() throws Exception {
319         final HttpRequest request = new BasicHttpRequest("GET", "/stuff");
320 
321         this.target = new HttpHost("localhost.local");
322         final HttpRoute route = new HttpRoute(
323                 new HttpHost("localhost.local", 80), null, new HttpHost("localhost", 8888), false);
324 
325         final HttpClientContext context = HttpClientContext.create();
326         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
327         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
328         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
329         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
330 
331         final HttpRequestInterceptor interceptor = new RequestAddCookies();
332         interceptor.process(request, context);
333 
334         final CookieOrigin cookieOrigin = context.getCookieOrigin();
335         Assert.assertNotNull(cookieOrigin);
336         Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost());
337         Assert.assertEquals(80, cookieOrigin.getPort());
338         Assert.assertEquals("/stuff", cookieOrigin.getPath());
339         Assert.assertFalse(cookieOrigin.isSecure());
340     }
341 
342     @Test
343     public void testAuthDefaultHttpsPortWhenProxy() throws Exception {
344         final HttpRequest request = new BasicHttpRequest("GET", "/stuff");
345 
346         this.target = new HttpHost("localhost", -1, "https");
347         final HttpRoute route = new HttpRoute(
348                 new HttpHost("localhost", 443, "https"), null,
349                 new HttpHost("localhost", 8888), true, TunnelType.TUNNELLED, LayerType.LAYERED);
350 
351         final HttpClientContext context = HttpClientContext.create();
352         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
353         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
354         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
355         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
356 
357         final HttpRequestInterceptor interceptor = new RequestAddCookies();
358         interceptor.process(request, context);
359 
360         final CookieOrigin cookieOrigin = context.getCookieOrigin();
361         Assert.assertNotNull(cookieOrigin);
362         Assert.assertEquals(this.target.getHostName(), cookieOrigin.getHost());
363         Assert.assertEquals(443, cookieOrigin.getPort());
364         Assert.assertEquals("/stuff", cookieOrigin.getPath());
365         Assert.assertTrue(cookieOrigin.isSecure());
366     }
367 
368     @Test
369     public void testExcludeExpiredCookies() throws Exception {
370         final HttpRequest request = new BasicHttpRequest("GET", "/");
371 
372         final BasicClientCookie2 cookie3 = new BasicClientCookie2("name3", "value3");
373         cookie3.setVersion(1);
374         cookie3.setDomain("localhost.local");
375         cookie3.setPath("/");
376         cookie3.setExpiryDate(new Date(System.currentTimeMillis() + 100));
377         this.cookieStore.addCookie(cookie3);
378 
379         Assert.assertEquals(3, this.cookieStore.getCookies().size());
380 
381         this.cookieStore = Mockito.spy(this.cookieStore);
382 
383         final HttpRoute route = new HttpRoute(this.target, null, false);
384 
385         final HttpClientContext context = HttpClientContext.create();
386         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
387         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
388         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
389         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
390 
391         // Make sure the third cookie expires
392         Thread.sleep(200);
393 
394         final HttpRequestInterceptor interceptor = new RequestAddCookies();
395         interceptor.process(request, context);
396 
397         final Header[] headers1 = request.getHeaders(SM.COOKIE);
398         Assert.assertNotNull(headers1);
399         Assert.assertEquals(2, headers1.length);
400         Assert.assertEquals("$Version=1; name1=\"value1\"", headers1[0].getValue());
401         Assert.assertEquals("$Version=1; name2=\"value2\"", headers1[1].getValue());
402         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
403         Assert.assertNotNull(headers2);
404         Assert.assertEquals(0, headers2.length);
405 
406         Mockito.verify(this.cookieStore, Mockito.times(1)).clearExpired(Matchers.<Date>any());
407     }
408 
409     @Test
410     public void testNoMatchingCookies() throws Exception {
411         final HttpRequest request = new BasicHttpRequest("GET", "/");
412 
413         this.cookieStore.clear();
414         final BasicClientCookie cookie3 = new BasicClientCookie("name3", "value3");
415         cookie3.setDomain("www.somedomain.com");
416         cookie3.setPath("/");
417         this.cookieStore.addCookie(cookie3);
418 
419         final HttpRoute route = new HttpRoute(this.target, null, false);
420 
421         final HttpClientContext context = HttpClientContext.create();
422         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
423         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
424         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
425         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
426 
427         final HttpRequestInterceptor interceptor = new RequestAddCookies();
428         interceptor.process(request, context);
429 
430         final Header[] headers1 = request.getHeaders(SM.COOKIE);
431         Assert.assertNotNull(headers1);
432         Assert.assertEquals(0, headers1.length);
433         final Header[] headers2 = request.getHeaders(SM.COOKIE2);
434         Assert.assertNotNull(headers2);
435         Assert.assertEquals(0, headers2.length);
436     }
437 
438     // Helper method
439     private BasicClientCookie makeCookie(final String name, final String value, final String domain, final String path) {
440         final BasicClientCookie cookie = new BasicClientCookie(name, value);
441         cookie.setDomain(domain);
442         cookie.setPath(path);
443         return cookie;
444     }
445 
446     @Test
447     // Test for ordering adapted from test in Commons HC 3.1
448     public void testCookieOrder() throws Exception {
449         final HttpRequest request = new BasicHttpRequest("GET", "/foobar/yada/yada");
450 
451         this.cookieStore.clear();
452 
453         cookieStore.addCookie(makeCookie("nomatch", "value", "localhost.local", "/noway"));
454         cookieStore.addCookie(makeCookie("name2",   "value", "localhost.local", "/foobar/yada"));
455         cookieStore.addCookie(makeCookie("name3",   "value", "localhost.local", "/foobar"));
456         cookieStore.addCookie(makeCookie("name1",   "value", "localhost.local", "/foobar/yada/yada"));
457 
458         final HttpRoute route = new HttpRoute(this.target, null, false);
459 
460         final HttpClientContext context = HttpClientContext.create();
461         context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, this.target);
462         context.setAttribute(HttpClientContext.HTTP_ROUTE, route);
463         context.setAttribute(HttpClientContext.COOKIE_STORE, this.cookieStore);
464         context.setAttribute(HttpClientContext.COOKIESPEC_REGISTRY, this.cookieSpecRegistry);
465 
466         final HttpRequestInterceptor interceptor = new RequestAddCookies();
467         interceptor.process(request, context);
468 
469         final Header[] headers1 = request.getHeaders(SM.COOKIE);
470         Assert.assertNotNull(headers1);
471         Assert.assertEquals(1, headers1.length);
472 
473         Assert.assertEquals("name1=value; name2=value; name3=value", headers1[0].getValue());
474     }
475 
476 }