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.client.integration;
28  
29  import java.io.ByteArrayInputStream;
30  import java.io.IOException;
31  import java.net.URI;
32  import java.util.List;
33  
34  import org.apache.http.Header;
35  import org.apache.http.HttpClientConnection;
36  import org.apache.http.HttpException;
37  import org.apache.http.HttpHost;
38  import org.apache.http.HttpRequest;
39  import org.apache.http.HttpRequestInterceptor;
40  import org.apache.http.HttpResponse;
41  import org.apache.http.HttpStatus;
42  import org.apache.http.client.ClientProtocolException;
43  import org.apache.http.client.HttpRequestRetryHandler;
44  import org.apache.http.client.NonRepeatableRequestException;
45  import org.apache.http.client.methods.HttpGet;
46  import org.apache.http.client.methods.HttpPost;
47  import org.apache.http.client.protocol.HttpClientContext;
48  import org.apache.http.client.utils.URIBuilder;
49  import org.apache.http.client.utils.URIUtils;
50  import org.apache.http.entity.InputStreamEntity;
51  import org.apache.http.entity.StringEntity;
52  import org.apache.http.localserver.LocalServerTestBase;
53  import org.apache.http.message.BasicHttpRequest;
54  import org.apache.http.protocol.HttpContext;
55  import org.apache.http.protocol.HttpRequestExecutor;
56  import org.apache.http.protocol.HttpRequestHandler;
57  import org.apache.http.util.EntityUtils;
58  import org.junit.Assert;
59  import org.junit.Test;
60  
61  /**
62   * Client protocol handling tests.
63   */
64  public class TestClientRequestExecution extends LocalServerTestBase {
65  
66      private static class SimpleService implements HttpRequestHandler {
67  
68          public SimpleService() {
69              super();
70          }
71  
72          @Override
73          public void handle(
74                  final HttpRequest request,
75                  final HttpResponse response,
76                  final HttpContext context) throws HttpException, IOException {
77              response.setStatusCode(HttpStatus.SC_OK);
78              final StringEntity entity = new StringEntity("Whatever");
79              response.setEntity(entity);
80          }
81      }
82  
83      private static class FaultyHttpRequestExecutor extends HttpRequestExecutor {
84  
85          private static final String MARKER = "marker";
86  
87          private final String failureMsg;
88  
89          public FaultyHttpRequestExecutor(final String failureMsg) {
90              this.failureMsg = failureMsg;
91          }
92  
93          @Override
94          public HttpResponse execute(
95                  final HttpRequest request,
96                  final HttpClientConnection conn,
97                  final HttpContext context) throws IOException, HttpException {
98  
99              final HttpResponse response = super.execute(request, conn, context);
100             final Object marker = context.getAttribute(MARKER);
101             if (marker == null) {
102                 context.setAttribute(MARKER, Boolean.TRUE);
103                 throw new IOException(failureMsg);
104             }
105             return response;
106         }
107 
108     }
109 
110     @Test
111     public void testAutoGeneratedHeaders() throws Exception {
112         this.serverBootstrap.registerHandler("*", new SimpleService());
113 
114         final HttpRequestInterceptor interceptor = new HttpRequestInterceptor() {
115 
116             @Override
117             public void process(
118                     final HttpRequest request,
119                     final HttpContext context) throws HttpException, IOException {
120                 request.addHeader("my-header", "stuff");
121             }
122 
123         };
124 
125         final HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {
126 
127             @Override
128             public boolean retryRequest(
129                     final IOException exception,
130                     final int executionCount,
131                     final HttpContext context) {
132                 return true;
133             }
134 
135         };
136 
137         this.httpclient = this.clientBuilder
138             .addInterceptorFirst(interceptor)
139             .setRequestExecutor(new FaultyHttpRequestExecutor("Oppsie"))
140             .setRetryHandler(requestRetryHandler)
141             .build();
142 
143         final HttpHost target = start();
144 
145         final HttpClientContext context = HttpClientContext.create();
146 
147         final HttpGet httpget = new HttpGet("/");
148 
149         final HttpResponse response = this.httpclient.execute(target, httpget, context);
150         EntityUtils.consume(response.getEntity());
151 
152         final HttpRequest reqWrapper = context.getRequest();
153 
154         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
155 
156         final Header[] myheaders = reqWrapper.getHeaders("my-header");
157         Assert.assertNotNull(myheaders);
158         Assert.assertEquals(1, myheaders.length);
159     }
160 
161     @Test(expected=ClientProtocolException.class)
162     public void testNonRepeatableEntity() throws Exception {
163         this.serverBootstrap.registerHandler("*", new SimpleService());
164 
165         final HttpRequestRetryHandler requestRetryHandler = new HttpRequestRetryHandler() {
166 
167             @Override
168             public boolean retryRequest(
169                     final IOException exception,
170                     final int executionCount,
171                     final HttpContext context) {
172                 return true;
173             }
174 
175         };
176 
177         this.httpclient = this.clientBuilder
178             .setRequestExecutor(new FaultyHttpRequestExecutor("a message showing that this failed"))
179             .setRetryHandler(requestRetryHandler)
180             .build();
181 
182         final HttpHost target = start();
183 
184         final HttpClientContext context = HttpClientContext.create();
185 
186         final HttpPost httppost = new HttpPost("/");
187         httppost.setEntity(new InputStreamEntity(
188                 new ByteArrayInputStream(
189                         new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
190                         -1));
191 
192         try {
193             this.httpclient.execute(target, httppost, context);
194         } catch (final ClientProtocolException ex) {
195             Assert.assertTrue(ex.getCause() instanceof NonRepeatableRequestException);
196             final NonRepeatableRequestException nonRepeat = (NonRepeatableRequestException)ex.getCause();
197             Assert.assertTrue(nonRepeat.getCause() instanceof IOException);
198             Assert.assertEquals("a message showing that this failed", nonRepeat.getCause().getMessage());
199             throw ex;
200         }
201     }
202 
203     @Test
204     public void testNonCompliantURI() throws Exception {
205         this.serverBootstrap.registerHandler("*", new SimpleService());
206 
207         final HttpHost target = start();
208 
209         final HttpClientContext context = HttpClientContext.create();
210         final BasicHttpRequest request = new BasicHttpRequest("GET", "blah.:.blah.:.");
211         final HttpResponse response = this.httpclient.execute(target, request, context);
212         EntityUtils.consume(response.getEntity());
213 
214         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
215 
216         final HttpRequest reqWrapper = context.getRequest();
217 
218         Assert.assertEquals("blah.:.blah.:.", reqWrapper.getRequestLine().getUri());
219     }
220 
221     @Test
222     public void testRelativeRequestURIWithFragment() throws Exception {
223         this.serverBootstrap.registerHandler("*", new SimpleService());
224 
225         final HttpHost target = start();
226 
227         final HttpGet httpget = new HttpGet("/stuff#blahblah");
228         final HttpClientContext context = HttpClientContext.create();
229 
230         final HttpResponse response = this.httpclient.execute(target, httpget, context);
231         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
232         EntityUtils.consume(response.getEntity());
233 
234         final HttpRequest request = context.getRequest();
235         Assert.assertEquals("/stuff", request.getRequestLine().getUri());
236     }
237 
238     @Test
239     public void testAbsoluteRequestURIWithFragment() throws Exception {
240         this.serverBootstrap.registerHandler("*", new SimpleService());
241 
242         final HttpHost target = start();
243 
244         final URI uri = new URIBuilder()
245             .setHost(target.getHostName())
246             .setPort(target.getPort())
247             .setScheme(target.getSchemeName())
248             .setPath("/stuff")
249             .setFragment("blahblah")
250             .build();
251 
252         final HttpGet httpget = new HttpGet(uri);
253         final HttpClientContext context = HttpClientContext.create();
254 
255         final HttpResponse response = this.httpclient.execute(httpget, context);
256         Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
257         EntityUtils.consume(response.getEntity());
258 
259         final HttpRequest request = context.getRequest();
260         Assert.assertEquals("/stuff", request.getRequestLine().getUri());
261 
262         final List<URI> redirectLocations = context.getRedirectLocations();
263         final URI location = URIUtils.resolve(uri, target, redirectLocations);
264         Assert.assertEquals(uri, location);
265     }
266 
267 }