| /* |
| * ==================================================================== |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| * |
| */ |
| package org.apache.hc.client5.http.protocol; |
| |
| import java.time.Instant; |
| |
| import org.apache.hc.client5.http.HttpRoute; |
| import org.apache.hc.client5.http.RouteInfo.LayerType; |
| import org.apache.hc.client5.http.RouteInfo.TunnelType; |
| import org.apache.hc.client5.http.config.RequestConfig; |
| import org.apache.hc.client5.http.cookie.BasicCookieStore; |
| import org.apache.hc.client5.http.cookie.CookieOrigin; |
| import org.apache.hc.client5.http.cookie.CookieSpec; |
| import org.apache.hc.client5.http.cookie.CookieSpecFactory; |
| import org.apache.hc.client5.http.cookie.CookieStore; |
| import org.apache.hc.client5.http.cookie.StandardCookieSpec; |
| import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; |
| import org.apache.hc.client5.http.impl.cookie.IgnoreCookieSpecFactory; |
| import org.apache.hc.client5.http.impl.cookie.RFC6265CookieSpecFactory; |
| import org.apache.hc.client5.http.impl.cookie.RFC6265StrictSpec; |
| import org.apache.hc.core5.http.Header; |
| import org.apache.hc.core5.http.HttpHost; |
| import org.apache.hc.core5.http.HttpRequest; |
| import org.apache.hc.core5.http.HttpRequestInterceptor; |
| import org.apache.hc.core5.http.config.Lookup; |
| import org.apache.hc.core5.http.config.RegistryBuilder; |
| import org.apache.hc.core5.http.message.BasicHttpRequest; |
| import org.junit.jupiter.api.Assertions; |
| import org.junit.jupiter.api.BeforeEach; |
| import org.junit.jupiter.api.Test; |
| import org.mockito.ArgumentMatchers; |
| import org.mockito.Mockito; |
| |
| public class TestRequestAddCookies { |
| |
| private HttpHost target; |
| private CookieStore cookieStore; |
| private Lookup<CookieSpecFactory> cookieSpecRegistry; |
| |
| @BeforeEach |
| public void setUp() { |
| this.target = new HttpHost("localhost.local", 80); |
| this.cookieStore = new BasicCookieStore(); |
| final BasicClientCookie cookie1 = new BasicClientCookie("name1", "value1"); |
| cookie1.setDomain("localhost.local"); |
| cookie1.setPath("/"); |
| this.cookieStore.addCookie(cookie1); |
| final BasicClientCookie cookie2 = new BasicClientCookie("name2", "value2"); |
| cookie2.setDomain("localhost.local"); |
| cookie2.setPath("/"); |
| this.cookieStore.addCookie(cookie2); |
| |
| this.cookieSpecRegistry = RegistryBuilder.<CookieSpecFactory>create() |
| .register(StandardCookieSpec.RELAXED, new RFC6265CookieSpecFactory( |
| RFC6265CookieSpecFactory.CompatibilityLevel.RELAXED, null)) |
| .register(StandardCookieSpec.STRICT, new RFC6265CookieSpecFactory( |
| RFC6265CookieSpecFactory.CompatibilityLevel.STRICT, null)) |
| .register(StandardCookieSpec.IGNORE, new IgnoreCookieSpecFactory()) |
| .build(); |
| } |
| |
| @Test |
| public void testRequestParameterCheck() throws Exception { |
| final HttpClientContext context = HttpClientContext.create(); |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| Assertions.assertThrows(NullPointerException.class, () -> |
| interceptor.process(null, null, context)); |
| } |
| |
| @Test |
| public void testContextParameterCheck() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| Assertions.assertThrows(NullPointerException.class, () -> |
| interceptor.process(request, null, null)); |
| } |
| |
| @Test |
| public void testAddCookies() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers); |
| Assertions.assertEquals(1, headers.length); |
| Assertions.assertEquals("name1=value1; name2=value2", headers[0].getValue()); |
| |
| final CookieOrigin cookieOrigin = context.getCookieOrigin(); |
| Assertions.assertNotNull(cookieOrigin); |
| Assertions.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); |
| Assertions.assertEquals(this.target.getPort(), cookieOrigin.getPort()); |
| Assertions.assertEquals("/", cookieOrigin.getPath()); |
| Assertions.assertFalse(cookieOrigin.isSecure()); |
| } |
| |
| @Test |
| public void testCookiesForConnectRequest() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("CONNECT", "www.somedomain.com"); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers); |
| Assertions.assertEquals(0, headers.length); |
| } |
| |
| @Test |
| public void testNoCookieStore() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(null); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers); |
| Assertions.assertEquals(0, headers.length); |
| } |
| |
| @Test |
| public void testNoCookieSpecRegistry() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(null); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers); |
| Assertions.assertEquals(0, headers.length); |
| } |
| |
| @Test |
| public void testNoHttpConnection() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setEndpointDetails(null); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers); |
| Assertions.assertEquals(0, headers.length); |
| } |
| |
| @Test |
| public void testAddCookiesUsingExplicitCookieSpec() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| final RequestConfig config = RequestConfig.custom() |
| .setCookieSpec(StandardCookieSpec.STRICT) |
| .build(); |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setRequestConfig(config); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final CookieSpec cookieSpec = context.getCookieSpec(); |
| Assertions.assertTrue(cookieSpec instanceof RFC6265StrictSpec); |
| |
| final Header[] headers1 = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers1); |
| Assertions.assertEquals(1, headers1.length); |
| Assertions.assertEquals("name1=value1; name2=value2", headers1[0].getValue()); |
| } |
| |
| @Test |
| public void testAuthScopeInvalidRequestURI() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "crap:"); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| } |
| |
| @Test |
| public void testAuthScopeRemotePortWhenDirect() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/stuff"); |
| |
| this.target = new HttpHost("localhost.local"); |
| final HttpRoute route = new HttpRoute(new HttpHost("localhost.local", 1234), null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final CookieOrigin cookieOrigin = context.getCookieOrigin(); |
| Assertions.assertNotNull(cookieOrigin); |
| Assertions.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); |
| Assertions.assertEquals(1234, cookieOrigin.getPort()); |
| Assertions.assertEquals("/stuff", cookieOrigin.getPath()); |
| Assertions.assertFalse(cookieOrigin.isSecure()); |
| } |
| |
| @Test |
| public void testAuthDefaultHttpPortWhenProxy() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/stuff"); |
| |
| this.target = new HttpHost("localhost.local"); |
| final HttpRoute route = new HttpRoute( |
| new HttpHost("localhost.local", 80), null, new HttpHost("localhost", 8888), false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final CookieOrigin cookieOrigin = context.getCookieOrigin(); |
| Assertions.assertNotNull(cookieOrigin); |
| Assertions.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); |
| Assertions.assertEquals(80, cookieOrigin.getPort()); |
| Assertions.assertEquals("/stuff", cookieOrigin.getPath()); |
| Assertions.assertFalse(cookieOrigin.isSecure()); |
| } |
| |
| @Test |
| public void testAuthDefaultHttpsPortWhenProxy() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/stuff"); |
| |
| this.target = new HttpHost("https", "localhost", -1); |
| final HttpRoute route = new HttpRoute( |
| new HttpHost("https", "localhost", 443), null, |
| new HttpHost("http", "localhost", 8888), true, TunnelType.TUNNELLED, LayerType.LAYERED); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final CookieOrigin cookieOrigin = context.getCookieOrigin(); |
| Assertions.assertNotNull(cookieOrigin); |
| Assertions.assertEquals(this.target.getHostName(), cookieOrigin.getHost()); |
| Assertions.assertEquals(443, cookieOrigin.getPort()); |
| Assertions.assertEquals("/stuff", cookieOrigin.getPath()); |
| Assertions.assertTrue(cookieOrigin.isSecure()); |
| } |
| |
| @Test |
| public void testExcludeExpiredCookies() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| |
| final BasicClientCookie cookie3 = new BasicClientCookie("name3", "value3"); |
| cookie3.setDomain("localhost.local"); |
| cookie3.setPath("/"); |
| cookie3.setExpiryDate(Instant.now().plusMillis(100)); |
| this.cookieStore.addCookie(cookie3); |
| |
| Assertions.assertEquals(3, this.cookieStore.getCookies().size()); |
| |
| this.cookieStore = Mockito.spy(this.cookieStore); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| // Make sure the third cookie expires |
| Thread.sleep(200); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers); |
| Assertions.assertEquals(1, headers.length); |
| Assertions.assertEquals("name1=value1; name2=value2", headers[0].getValue()); |
| |
| Mockito.verify(this.cookieStore, Mockito.times(1)).clearExpired(ArgumentMatchers.any(Instant.class)); |
| } |
| |
| @Test |
| public void testNoMatchingCookies() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/"); |
| |
| this.cookieStore.clear(); |
| final BasicClientCookie cookie3 = new BasicClientCookie("name3", "value3"); |
| cookie3.setDomain("www.somedomain.com"); |
| cookie3.setPath("/"); |
| this.cookieStore.addCookie(cookie3); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers); |
| Assertions.assertEquals(0, headers.length); |
| } |
| |
| // Helper method |
| private BasicClientCookie makeCookie(final String name, final String value, final String domain, final String path) { |
| final BasicClientCookie cookie = new BasicClientCookie(name, value); |
| cookie.setDomain(domain); |
| cookie.setPath(path); |
| return cookie; |
| } |
| |
| @Test |
| // Test for ordering adapted from test in Commons HC 3.1 |
| public void testCookieOrder() throws Exception { |
| final HttpRequest request = new BasicHttpRequest("GET", "/foobar/yada/yada"); |
| |
| this.cookieStore.clear(); |
| |
| cookieStore.addCookie(makeCookie("nomatch", "value", "localhost.local", "/noway")); |
| cookieStore.addCookie(makeCookie("name2", "value", "localhost.local", "/foobar/yada")); |
| cookieStore.addCookie(makeCookie("name3", "value", "localhost.local", "/foobar")); |
| cookieStore.addCookie(makeCookie("name1", "value", "localhost.local", "/foobar/yada/yada")); |
| |
| final HttpRoute route = new HttpRoute(this.target, null, false); |
| |
| final HttpClientContext context = HttpClientContext.create(); |
| context.setRoute(route); |
| context.setCookieStore(this.cookieStore); |
| context.setCookieSpecRegistry(this.cookieSpecRegistry); |
| |
| final HttpRequestInterceptor interceptor = RequestAddCookies.INSTANCE; |
| interceptor.process(request, null, context); |
| |
| final Header[] headers1 = request.getHeaders("Cookie"); |
| Assertions.assertNotNull(headers1); |
| Assertions.assertEquals(1, headers1.length); |
| |
| Assertions.assertEquals("name1=value; name2=value; name3=value", headers1[0].getValue()); |
| } |
| |
| } |