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.hc.client5.http.impl.classic;
28  
29  import java.io.Closeable;
30  import java.io.IOException;
31  import java.util.Arrays;
32  
33  import org.apache.hc.client5.http.ClientProtocolException;
34  import org.apache.hc.client5.http.HttpRoute;
35  import org.apache.hc.client5.http.auth.AuthSchemeFactory;
36  import org.apache.hc.client5.http.auth.CredentialsProvider;
37  import org.apache.hc.client5.http.classic.ExecChainHandler;
38  import org.apache.hc.client5.http.classic.methods.HttpGet;
39  import org.apache.hc.client5.http.config.RequestConfig;
40  import org.apache.hc.client5.http.cookie.CookieSpecFactory;
41  import org.apache.hc.client5.http.cookie.CookieStore;
42  import org.apache.hc.client5.http.io.HttpClientConnectionManager;
43  import org.apache.hc.client5.http.protocol.HttpClientContext;
44  import org.apache.hc.client5.http.routing.HttpRoutePlanner;
45  import org.apache.hc.core5.http.ClassicHttpRequest;
46  import org.apache.hc.core5.http.HttpException;
47  import org.apache.hc.core5.http.HttpHost;
48  import org.apache.hc.core5.http.ProtocolException;
49  import org.apache.hc.core5.http.config.Lookup;
50  import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
51  import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
52  import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
53  import org.junit.jupiter.api.Assertions;
54  import org.junit.jupiter.api.BeforeEach;
55  import org.junit.jupiter.api.Test;
56  import org.mockito.Mock;
57  import org.mockito.Mockito;
58  import org.mockito.MockitoAnnotations;
59  
60  /**
61   *  Simple tests for {@link InternalHttpClient}.
62   */
63  class TestInternalHttpClient {
64  
65      @Mock
66      private HttpClientConnectionManager connManager;
67      @Mock
68      private HttpRequestExecutor requestExecutor;
69      @Mock
70      private ExecChainHandler execChain;
71      @Mock
72      private HttpRoutePlanner routePlanner;
73      @Mock
74      private Lookup<CookieSpecFactory> cookieSpecRegistry;
75      @Mock
76      private Lookup<AuthSchemeFactory> authSchemeRegistry;
77      @Mock
78      private CookieStore cookieStore;
79      @Mock
80      private CredentialsProvider credentialsProvider;
81      @Mock
82      private RequestConfig defaultConfig;
83      @Mock
84      private Closeable closeable1;
85      @Mock
86      private Closeable closeable2;
87  
88      private InternalHttpClient client;
89  
90      @BeforeEach
91      void setup() {
92          MockitoAnnotations.openMocks(this);
93          client = new InternalHttpClient(connManager, requestExecutor, new ExecChainElement(execChain, null), routePlanner,
94                  cookieSpecRegistry, authSchemeRegistry, cookieStore, credentialsProvider,
95                  HttpClientContext::castOrCreate, defaultConfig, Arrays.asList(closeable1, closeable2));
96  
97      }
98  
99      @Test
100     void testExecute() throws Exception {
101         final HttpGet httpget = new HttpGet("http://somehost/stuff");
102         final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
103 
104         Mockito.when(routePlanner.determineRoute(
105                 Mockito.eq(new HttpHost("somehost")),
106                 Mockito.any(),
107                 Mockito.<HttpClientContext>any())).thenReturn(route);
108         Mockito.when(execChain.execute(
109                 Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(
110                 CloseableHttpResponse.adapt(new BasicClassicHttpResponse(200)));
111 
112         client.execute(httpget, response -> null);
113 
114         Mockito.verify(execChain).execute(
115                 Mockito.any(),
116                 Mockito.any(),
117                 Mockito.any());
118     }
119 
120     @Test
121     void testExecuteHttpException() throws Exception {
122         final HttpGet httpget = new HttpGet("http://somehost/stuff");
123         final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
124 
125         Mockito.when(routePlanner.determineRoute(
126                 Mockito.eq(new HttpHost("somehost")),
127                 Mockito.any(),
128                 Mockito.<HttpClientContext>any())).thenReturn(route);
129         Mockito.when(execChain.execute(
130                 Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(
131                 CloseableHttpResponse.adapt(new BasicClassicHttpResponse(200)));
132         Mockito.when(execChain.execute(
133                 Mockito.any(),
134                 Mockito.any(),
135                 Mockito.any())).thenThrow(new HttpException());
136 
137         Assertions.assertThrows(ClientProtocolException.class, () ->
138                 client.execute(httpget, response -> null));
139     }
140 
141     @Test
142     void testExecuteDefaultContext() throws Exception {
143         final HttpGet httpget = new HttpGet("http://somehost/stuff");
144         final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
145 
146         Mockito.when(routePlanner.determineRoute(
147                 Mockito.eq(new HttpHost("somehost")),
148                 Mockito.any(),
149                 Mockito.<HttpClientContext>any())).thenReturn(route);
150         Mockito.when(execChain.execute(
151                 Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(
152                 CloseableHttpResponse.adapt(new BasicClassicHttpResponse(200)));
153 
154         final HttpClientContext context = HttpClientContext.create();
155         client.execute(httpget, context, response -> null);
156 
157         Assertions.assertSame(cookieSpecRegistry, context.getCookieSpecRegistry());
158         Assertions.assertSame(authSchemeRegistry, context.getAuthSchemeRegistry());
159         Assertions.assertSame(cookieStore, context.getCookieStore());
160         Assertions.assertSame(credentialsProvider, context.getCredentialsProvider());
161         Assertions.assertSame(defaultConfig, context.getRequestConfigOrDefault());
162     }
163 
164     @Test
165     void testExecuteRequestConfig() throws Exception {
166         final HttpGet httpget = new HttpGet("http://somehost/stuff");
167         final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
168 
169         Mockito.when(routePlanner.determineRoute(
170                 Mockito.eq(new HttpHost("somehost")),
171                 Mockito.any(),
172                 Mockito.<HttpClientContext>any())).thenReturn(route);
173         Mockito.when(execChain.execute(
174                 Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(
175                 CloseableHttpResponse.adapt(new BasicClassicHttpResponse(200)));
176 
177         final RequestConfig config = RequestConfig.custom().build();
178         httpget.setConfig(config);
179         final HttpClientContext context = HttpClientContext.create();
180         client.execute(httpget, context, response -> null);
181 
182         Assertions.assertSame(config, context.getRequestConfigOrDefault());
183     }
184 
185     @Test
186     void testExecuteLocalContext() throws Exception {
187         final HttpGet httpget = new HttpGet("http://somehost/stuff");
188         final HttpRoute route = new HttpRoute(new HttpHost("somehost", 80));
189 
190         Mockito.when(routePlanner.determineRoute(
191                 Mockito.eq(new HttpHost("somehost")),
192                 Mockito.any(),
193                 Mockito.<HttpClientContext>any())).thenReturn(route);
194         Mockito.when(execChain.execute(
195                 Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(
196                 CloseableHttpResponse.adapt(new BasicClassicHttpResponse(200)));
197 
198         final HttpClientContext context = HttpClientContext.create();
199 
200         final Lookup<CookieSpecFactory> localCookieSpecRegistry = Mockito.mock(Lookup.class);
201         final Lookup<AuthSchemeFactory> localAuthSchemeRegistry = Mockito.mock(Lookup.class);
202         final CookieStore localCookieStore = Mockito.mock(CookieStore.class);
203         final CredentialsProvider localCredentialsProvider = Mockito.mock(CredentialsProvider.class);
204         final RequestConfig localConfig = RequestConfig.custom().build();
205 
206         context.setCookieSpecRegistry(localCookieSpecRegistry);
207         context.setAuthSchemeRegistry(localAuthSchemeRegistry);
208         context.setCookieStore(localCookieStore);
209         context.setCredentialsProvider(localCredentialsProvider);
210         context.setRequestConfig(localConfig);
211 
212         client.execute(httpget, context, response -> null);
213 
214         Assertions.assertSame(localCookieSpecRegistry, context.getCookieSpecRegistry());
215         Assertions.assertSame(localAuthSchemeRegistry, context.getAuthSchemeRegistry());
216         Assertions.assertSame(localCookieStore, context.getCookieStore());
217         Assertions.assertSame(localCredentialsProvider, context.getCredentialsProvider());
218         Assertions.assertSame(localConfig, context.getRequestConfigOrDefault());
219     }
220 
221     @Test
222     void testClientClose() throws Exception {
223         client.close();
224 
225         Mockito.verify(closeable1).close();
226         Mockito.verify(closeable2).close();
227     }
228 
229     @Test
230     void testClientCloseIOException() throws Exception {
231         Mockito.doThrow(new IOException()).when(closeable1).close();
232 
233         client.close();
234 
235         Mockito.verify(closeable1).close();
236         Mockito.verify(closeable2).close();
237     }
238 
239     @Test
240     void testDoExecuteThrowsWhenNoTargetOrHost() throws Exception {
241         final ClassicHttpRequest request = ClassicRequestBuilder.get("/foo").build();
242         final HttpClientContext context = HttpClientContext.create();
243         Mockito.when(routePlanner.determineRoute(
244                 Mockito.eq(null),
245                 Mockito.any(),
246                 Mockito.<HttpClientContext>any())).thenThrow(new ProtocolException());
247         Assertions.assertThrows(ClientProtocolException.class, () ->
248                 client.execute(null, request, context));
249     }
250 }