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