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.impl.execchain;
28  
29  import java.io.IOException;
30  import java.net.URI;
31  
32  import org.apache.http.HttpException;
33  import org.apache.http.HttpHost;
34  import org.apache.http.auth.AuthScope;
35  import org.apache.http.auth.Credentials;
36  import org.apache.http.client.CredentialsProvider;
37  import org.apache.http.client.methods.CloseableHttpResponse;
38  import org.apache.http.client.methods.HttpExecutionAware;
39  import org.apache.http.client.methods.HttpGet;
40  import org.apache.http.client.methods.HttpRequestWrapper;
41  import org.apache.http.client.protocol.HttpClientContext;
42  import org.apache.http.conn.routing.HttpRoute;
43  import org.apache.http.message.BasicHttpRequest;
44  import org.apache.http.protocol.HttpContext;
45  import org.apache.http.protocol.HttpProcessor;
46  import org.junit.Assert;
47  import org.junit.Before;
48  import org.junit.Test;
49  import org.mockito.Mock;
50  import org.mockito.Mockito;
51  import org.mockito.MockitoAnnotations;
52  
53  @SuppressWarnings({"static-access"}) // test code
54  public class TestProtocolExec {
55  
56      @Mock
57      private ClientExecChain requestExecutor;
58      @Mock
59      private HttpProcessor httpProcessor;
60      @Mock
61      private HttpExecutionAware execAware;
62  
63      private ProtocolExec protocolExec;
64      private HttpHost target;
65      private HttpHost proxy;
66  
67      @Before
68      public void setup() throws Exception {
69          MockitoAnnotations.initMocks(this);
70          protocolExec = new ProtocolExec(requestExecutor, httpProcessor);
71          target = new HttpHost("foo", 80);
72          proxy = new HttpHost("bar", 8888);
73      }
74  
75      @Test
76      public void testFundamentals() throws Exception {
77          final HttpRoute route = new HttpRoute(target);
78          final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test"));
79          final HttpClientContext context = HttpClientContext.create();
80  
81          final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class);
82  
83          Mockito.when(requestExecutor.execute(
84                  Mockito.eq(route),
85                  Mockito.<HttpRequestWrapper>any(),
86                  Mockito.<HttpClientContext>any(),
87                  Mockito.<HttpExecutionAware>any())).thenReturn(response);
88  
89          protocolExec.execute(route, request, context, execAware);
90  
91          Mockito.verify(httpProcessor).process(request, context);
92          Mockito.verify(requestExecutor).execute(route, request, context, execAware);
93          Mockito.verify(httpProcessor).process(response, context);
94  
95          Assert.assertEquals(new HttpHost("foo", 80), context.getTargetHost());
96          Assert.assertEquals(target, context.getTargetHost());
97          Assert.assertEquals(route, context.getHttpRoute());
98          Assert.assertSame(request, context.getRequest());
99          Assert.assertSame(response, context.getResponse());
100     }
101 
102     @Test
103     public void testRewriteAbsoluteRequestURI() throws Exception {
104         final HttpRoute route = new HttpRoute(target);
105         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
106                 new HttpGet("http://foo/test"));
107         protocolExec.rewriteRequestURI(request, route, true);
108         Assert.assertEquals(new URI("/test"), request.getURI());
109     }
110 
111     @Test
112     public void testRewriteEmptyRequestURI() throws Exception {
113         final HttpRoute route = new HttpRoute(target);
114         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
115                 new HttpGet(""));
116         protocolExec.rewriteRequestURI(request, route, true);
117         Assert.assertEquals(new URI("/"), request.getURI());
118     }
119 
120     @Test
121     public void testRewriteAbsoluteRequestURIViaPRoxy() throws Exception {
122         final HttpRoute route = new HttpRoute(target, proxy);
123         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
124                 new HttpGet("http://foo/test"));
125         protocolExec.rewriteRequestURI(request, route, true);
126         Assert.assertEquals(new URI("http://foo/test"), request.getURI());
127     }
128 
129     @Test
130     public void testRewriteRelativeRequestURIViaPRoxy() throws Exception {
131         final HttpRoute route = new HttpRoute(target, proxy);
132         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
133                 new HttpGet("/test"));
134         protocolExec.rewriteRequestURI(request, route, true);
135         Assert.assertEquals(new URI("http://foo:80/test"), request.getURI());
136     }
137 
138     @Test
139     public void testHostHeaderUriRequest() throws Exception {
140         final HttpRoute route = new HttpRoute(target);
141         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
142                 new HttpGet("http://bar/test"));
143         final HttpClientContext context = HttpClientContext.create();
144         protocolExec.execute(route, request, context, execAware);
145         // ProtocolExect should have extracted the host from request URI
146         Assert.assertEquals(new HttpHost("bar", -1, "http"), context.getTargetHost());
147     }
148 
149     @Test
150     public void testHostHeaderWhenNonUriRequest() throws Exception {
151         final HttpRoute route = new HttpRoute(target);
152         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
153                 new BasicHttpRequest("GET", "http://bar/test"));
154         final HttpClientContext context = HttpClientContext.create();
155         protocolExec.execute(route, request, context, execAware);
156         // ProtocolExect should have extracted the host from request URI
157         Assert.assertEquals(new HttpHost("bar", -1, "http"), context.getTargetHost());
158     }
159 
160     @Test
161     public void testHostHeaderWhenNonUriRequestAndInvalidUri() throws Exception {
162         final HttpRoute route = new HttpRoute(target);
163         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
164                 new BasicHttpRequest("GET", "http://bar/test|"));
165         final HttpClientContext context = HttpClientContext.create();
166         protocolExec.execute(route, request, context, execAware);
167         // ProtocolExect should have fall back to physical host as request URI
168         // is not parseable
169         Assert.assertEquals(new HttpHost("foo", 80, "http"), context.getTargetHost());
170     }
171 
172     @Test
173     public void testHostHeaderImplicitHost() throws Exception {
174         final HttpRoute route = new HttpRoute(new HttpHost("somehost", 8080));
175         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
176                 new HttpGet("/test"));
177         final HttpClientContext context = HttpClientContext.create();
178         protocolExec.execute(route, request, context, execAware);
179         Assert.assertEquals(new HttpHost("somehost", 8080), context.getTargetHost());
180     }
181 
182     @Test
183     public void testUserInfoInRequestURI() throws Exception {
184         final HttpRoute route = new HttpRoute(new HttpHost("somehost", 8080));
185         final HttpRequestWrapper request = HttpRequestWrapper.wrap(
186                 new HttpGet("http://somefella:secret@bar/test"));
187         final HttpClientContext context = HttpClientContext.create();
188         protocolExec.execute(route, request, context, execAware);
189         Assert.assertEquals(new URI("/test"), request.getURI());
190         Assert.assertEquals(new HttpHost("bar", -1), context.getTargetHost());
191         final CredentialsProvider credentialsProvider = context.getCredentialsProvider();
192         Assert.assertNotNull(credentialsProvider);
193         final Credentials creds = credentialsProvider.getCredentials(new AuthScope("bar", -1, null));
194         Assert.assertNotNull(creds);
195         Assert.assertEquals("somefella", creds.getUserPrincipal().getName());
196     }
197 
198     @Test(expected = HttpException.class)
199     public void testPostProcessHttpException() throws Exception {
200         final HttpRoute route = new HttpRoute(target);
201         final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test"));
202         final HttpClientContext context = HttpClientContext.create();
203 
204         final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class);
205 
206         Mockito.when(requestExecutor.execute(
207                 Mockito.eq(route),
208                 Mockito.<HttpRequestWrapper>any(),
209                 Mockito.<HttpClientContext>any(),
210                 Mockito.<HttpExecutionAware>any())).thenReturn(response);
211         Mockito.doThrow(new HttpException("Ooopsie")).when(httpProcessor).process(
212                 Mockito.same(response), Mockito.<HttpContext>any());
213         try {
214             protocolExec.execute(route, request, context, execAware);
215         } catch (final Exception ex) {
216             Mockito.verify(response).close();
217             throw ex;
218         }
219     }
220 
221     @Test(expected = IOException.class)
222     public void testPostProcessIOException() throws Exception {
223         final HttpRoute route = new HttpRoute(target);
224         final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test"));
225         final HttpClientContext context = HttpClientContext.create();
226 
227         final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class);
228         Mockito.when(requestExecutor.execute(
229                 Mockito.eq(route),
230                 Mockito.<HttpRequestWrapper>any(),
231                 Mockito.<HttpClientContext>any(),
232                 Mockito.<HttpExecutionAware>any())).thenReturn(response);
233         Mockito.doThrow(new IOException("Ooopsie")).when(httpProcessor).process(
234                 Mockito.same(response), Mockito.<HttpContext>any());
235         try {
236             protocolExec.execute(route, request, context, execAware);
237         } catch (final Exception ex) {
238             Mockito.verify(response).close();
239             throw ex;
240         }
241     }
242 
243     @Test(expected = RuntimeException.class)
244     public void testPostProcessRuntimeException() throws Exception {
245         final HttpRoute route = new HttpRoute(target);
246         final HttpRequestWrapper request = HttpRequestWrapper.wrap(new HttpGet("/test"));
247         final HttpClientContext context = HttpClientContext.create();
248 
249         final CloseableHttpResponse response = Mockito.mock(CloseableHttpResponse.class);
250         Mockito.when(requestExecutor.execute(
251                 Mockito.eq(route),
252                 Mockito.<HttpRequestWrapper>any(),
253                 Mockito.<HttpClientContext>any(),
254                 Mockito.<HttpExecutionAware>any())).thenReturn(response);
255         Mockito.doThrow(new RuntimeException("Ooopsie")).when(httpProcessor).process(
256                 Mockito.same(response), Mockito.<HttpContext>any());
257         try {
258             protocolExec.execute(route, request, context, execAware);
259         } catch (final Exception ex) {
260             Mockito.verify(response).close();
261             throw ex;
262         }
263     }
264 
265 }