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  
28  package org.apache.http.protocol;
29  
30  import java.io.IOException;
31  
32  import org.apache.http.HttpClientConnection;
33  import org.apache.http.HttpEntity;
34  import org.apache.http.HttpEntityEnclosingRequest;
35  import org.apache.http.HttpRequest;
36  import org.apache.http.HttpResponse;
37  import org.apache.http.HttpVersion;
38  import org.apache.http.ProtocolException;
39  import org.apache.http.message.BasicHttpEntityEnclosingRequest;
40  import org.apache.http.message.BasicHttpRequest;
41  import org.apache.http.message.BasicHttpResponse;
42  import org.junit.Assert;
43  import org.junit.Test;
44  import org.mockito.Mockito;
45  
46  public class TestHttpRequestExecutor {
47  
48  
49      @Test
50      public void testInvalidInput() throws Exception {
51          final HttpCoreContext context = HttpCoreContext.create();
52          final HttpRequest request = new BasicHttpRequest("GET", "/");
53          final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
54          final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
55          final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
56          try {
57              final HttpRequestExecutor executor = new HttpRequestExecutor();
58              executor.execute(null, conn, context);
59              Assert.fail("IllegalArgumentException expected");
60          } catch (final IllegalArgumentException expected) {
61          }
62          try {
63              final HttpRequestExecutor executor = new HttpRequestExecutor();
64              executor.execute(request, null, context);
65              Assert.fail("IllegalArgumentException expected");
66          } catch (final IllegalArgumentException expected) {
67          }
68          try {
69              final HttpRequestExecutor executor = new HttpRequestExecutor();
70              executor.execute(request, conn, null);
71              Assert.fail("IllegalArgumentException expected");
72          } catch (final IllegalArgumentException expected) {
73          }
74  
75          try {
76              final HttpRequestExecutor executor = new HttpRequestExecutor();
77              executor.doSendRequest(null, conn, context);
78              Assert.fail("IllegalArgumentException expected");
79          } catch (final IllegalArgumentException expected) {
80          }
81          try {
82              final HttpRequestExecutor executor = new HttpRequestExecutor();
83              executor.doSendRequest(request, null, context);
84              Assert.fail("IllegalArgumentException expected");
85          } catch (final IllegalArgumentException expected) {
86          }
87          try {
88              final HttpRequestExecutor executor = new HttpRequestExecutor();
89              executor.doSendRequest(request, conn, null);
90              Assert.fail("IllegalArgumentException expected");
91          } catch (final IllegalArgumentException expected) {
92          }
93  
94          try {
95              final HttpRequestExecutor executor = new HttpRequestExecutor();
96              executor.doReceiveResponse(null, conn, context);
97              Assert.fail("IllegalArgumentException expected");
98          } catch (final IllegalArgumentException expected) {
99          }
100         try {
101             final HttpRequestExecutor executor = new HttpRequestExecutor();
102             executor.doReceiveResponse(request, null, context);
103             Assert.fail("IllegalArgumentException expected");
104         } catch (final IllegalArgumentException expected) {
105         }
106         try {
107             final HttpRequestExecutor executor = new HttpRequestExecutor();
108             executor.doReceiveResponse(request, conn, null);
109             Assert.fail("IllegalArgumentException expected");
110         } catch (final IllegalArgumentException expected) {
111         }
112 
113         try {
114             final HttpRequestExecutor executor = new HttpRequestExecutor();
115             executor.preProcess(null, httprocessor, context);
116             Assert.fail("IllegalArgumentException expected");
117         } catch (final IllegalArgumentException expected) {
118         }
119         try {
120             final HttpRequestExecutor executor = new HttpRequestExecutor();
121             executor.preProcess(request, null, context);
122             Assert.fail("IllegalArgumentException expected");
123         } catch (final IllegalArgumentException expected) {
124         }
125         try {
126             final HttpRequestExecutor executor = new HttpRequestExecutor();
127             executor.preProcess(request, httprocessor, null);
128             Assert.fail("IllegalArgumentException expected");
129         } catch (final IllegalArgumentException expected) {
130         }
131 
132         try {
133             final HttpRequestExecutor executor = new HttpRequestExecutor();
134             executor.postProcess(null, httprocessor, context);
135             Assert.fail("IllegalArgumentException expected");
136         } catch (final IllegalArgumentException expected) {
137         }
138         try {
139             final HttpRequestExecutor executor = new HttpRequestExecutor();
140             executor.postProcess(response, null, context);
141             Assert.fail("IllegalArgumentException expected");
142         } catch (final IllegalArgumentException expected) {
143         }
144         try {
145             final HttpRequestExecutor executor = new HttpRequestExecutor();
146             executor.postProcess(response, httprocessor, null);
147             Assert.fail("IllegalArgumentException expected");
148         } catch (final IllegalArgumentException expected) {
149         }
150     }
151 
152     @Test
153     public void testBasicExecution() throws Exception {
154         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
155         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
156         final HttpRequestExecutor executor = new HttpRequestExecutor();
157 
158         final HttpCoreContext context = HttpCoreContext.create();
159         final HttpRequest request = new BasicHttpRequest("GET", "/");
160 
161         executor.preProcess(request, httprocessor, context);
162         Mockito.verify(httprocessor).process(request, context);
163 
164         Mockito.when(conn.receiveResponseHeader()).thenReturn(
165                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
166 
167         final HttpResponse response = executor.execute(request, conn, context);
168         Mockito.verify(conn).sendRequestHeader(request);
169         Mockito.verify(conn).flush();
170         Mockito.verify(conn).receiveResponseHeader();
171         Mockito.verify(conn).receiveResponseEntity(response);
172 
173         executor.postProcess(response, httprocessor, context);
174         Mockito.verify(httprocessor).process(response, context);
175 
176         Assert.assertSame(conn, context.getConnection());
177         Assert.assertSame(request, context.getRequest());
178         Assert.assertSame(response, context.getResponse());
179     }
180 
181     @Test
182     public void testExecutionSkipIntermediateResponses() throws Exception {
183         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
184         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
185         final HttpRequestExecutor executor = new HttpRequestExecutor();
186 
187         final HttpCoreContext context = HttpCoreContext.create();
188         final HttpRequest request = new BasicHttpRequest("GET", "/");
189 
190         executor.preProcess(request, httprocessor, context);
191         Mockito.verify(httprocessor).process(request, context);
192 
193         Mockito.when(conn.receiveResponseHeader()).thenReturn(
194                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "OK"),
195                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 101, "OK"),
196                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 102, "OK"),
197                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
198 
199         final HttpResponse response = executor.execute(request, conn, context);
200         Mockito.verify(conn).sendRequestHeader(request);
201         Mockito.verify(conn).flush();
202         Mockito.verify(conn, Mockito.times(4)).receiveResponseHeader();
203         Mockito.verify(conn, Mockito.times(1)).receiveResponseEntity(response);
204 
205         executor.postProcess(response, httprocessor, context);
206         Mockito.verify(httprocessor).process(response, context);
207 
208         Assert.assertSame(conn, context.getConnection());
209         Assert.assertSame(request, context.getRequest());
210         Assert.assertSame(response, context.getResponse());
211     }
212 
213     @Test
214     public void testExecutionNoResponseBody() throws Exception {
215         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
216         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
217         final HttpRequestExecutor executor = new HttpRequestExecutor();
218 
219         final HttpCoreContext context = HttpCoreContext.create();
220         final HttpRequest request = new BasicHttpRequest("GET", "/");
221 
222         executor.preProcess(request, httprocessor, context);
223         Mockito.verify(httprocessor).process(request, context);
224 
225         Mockito.when(conn.receiveResponseHeader()).thenReturn(
226                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 204, "OK"));
227 
228         final HttpResponse response = executor.execute(request, conn, context);
229         Mockito.verify(conn).sendRequestHeader(request);
230         Mockito.verify(conn).flush();
231         Mockito.verify(conn).receiveResponseHeader();
232         Mockito.verify(conn, Mockito.never()).receiveResponseEntity(response);
233 
234         executor.postProcess(response, httprocessor, context);
235         Mockito.verify(httprocessor).process(response, context);
236     }
237 
238     @Test
239     public void testExecutionHead() throws Exception {
240         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
241         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
242         final HttpRequestExecutor executor = new HttpRequestExecutor();
243 
244         final HttpCoreContext context = HttpCoreContext.create();
245         final HttpRequest request = new BasicHttpRequest("HEAD", "/");
246 
247         executor.preProcess(request, httprocessor, context);
248         Mockito.verify(httprocessor).process(request, context);
249 
250         Mockito.when(conn.receiveResponseHeader()).thenReturn(
251                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
252 
253         final HttpResponse response = executor.execute(request, conn, context);
254         Mockito.verify(conn).sendRequestHeader(request);
255         Mockito.verify(conn).flush();
256         Mockito.verify(conn).receiveResponseHeader();
257         Mockito.verify(conn, Mockito.never()).receiveResponseEntity(response);
258 
259         executor.postProcess(response, httprocessor, context);
260         Mockito.verify(httprocessor).process(response, context);
261     }
262 
263     @Test
264     public void testExecutionEntityEnclosingRequest() throws Exception {
265         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
266         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
267         final HttpRequestExecutor executor = new HttpRequestExecutor();
268 
269         final HttpCoreContext context = HttpCoreContext.create();
270         final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
271 //        request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
272         final HttpEntity entity = Mockito.mock(HttpEntity.class);
273         request.setEntity(entity);
274 
275         executor.preProcess(request, httprocessor, context);
276         Mockito.verify(httprocessor).process(request, context);
277 
278         Mockito.when(conn.receiveResponseHeader()).thenReturn(
279                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
280 
281         final HttpResponse response = executor.execute(request, conn, context);
282         Mockito.verify(conn).sendRequestHeader(request);
283         Mockito.verify(conn).sendRequestEntity(request);
284         Mockito.verify(conn).flush();
285         Mockito.verify(conn).receiveResponseHeader();
286         Mockito.verify(conn).receiveResponseEntity(response);
287 
288         executor.postProcess(response, httprocessor, context);
289         Mockito.verify(httprocessor).process(response, context);
290     }
291 
292     @Test
293     public void testExecutionEntityEnclosingRequestWithExpectContinueSuccess() throws Exception {
294         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
295         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
296         final HttpRequestExecutor executor = new HttpRequestExecutor();
297 
298         final HttpCoreContext context = HttpCoreContext.create();
299         final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
300         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
301         final HttpEntity entity = Mockito.mock(HttpEntity.class);
302         request.setEntity(entity);
303 
304         executor.preProcess(request, httprocessor, context);
305         Mockito.verify(httprocessor).process(request, context);
306 
307         Mockito.when(conn.receiveResponseHeader()).thenReturn(
308                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue"),
309                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
310         Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.TRUE);
311 
312         final HttpResponse response = executor.execute(request, conn, context);
313         Mockito.verify(conn).sendRequestHeader(request);
314         Mockito.verify(conn).sendRequestEntity(request);
315         Mockito.verify(conn, Mockito.times(2)).flush();
316         Mockito.verify(conn).isResponseAvailable(3000);
317         Mockito.verify(conn, Mockito.times(2)).receiveResponseHeader();
318         Mockito.verify(conn).receiveResponseEntity(response);
319 
320         executor.postProcess(response, httprocessor, context);
321         Mockito.verify(httprocessor).process(response, context);
322 
323         Assert.assertEquals(Boolean.TRUE, context.isRequestSent());
324     }
325 
326     @Test
327     public void testExecutionEntityEnclosingRequestWithExpectContinueFailure() throws Exception {
328         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
329         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
330         final HttpRequestExecutor executor = new HttpRequestExecutor();
331 
332         final HttpCoreContext context = HttpCoreContext.create();
333         final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
334         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
335         final HttpEntity entity = Mockito.mock(HttpEntity.class);
336         request.setEntity(entity);
337 
338         executor.preProcess(request, httprocessor, context);
339         Mockito.verify(httprocessor).process(request, context);
340 
341         Mockito.when(conn.receiveResponseHeader()).thenReturn(
342                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 402, "OK"));
343         Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.TRUE);
344 
345         final HttpResponse response = executor.execute(request, conn, context);
346         Mockito.verify(conn).sendRequestHeader(request);
347         Mockito.verify(conn, Mockito.never()).sendRequestEntity(request);
348         Mockito.verify(conn, Mockito.times(2)).flush();
349         Mockito.verify(conn).isResponseAvailable(3000);
350         Mockito.verify(conn).receiveResponseHeader();
351         Mockito.verify(conn).receiveResponseEntity(response);
352 
353         executor.postProcess(response, httprocessor, context);
354         Mockito.verify(httprocessor).process(response, context);
355     }
356 
357     @Test
358     public void testExecutionEntityEnclosingRequestUnsupportedIntermediateResponse() throws Exception {
359         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
360         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
361         final HttpRequestExecutor executor = new HttpRequestExecutor();
362 
363         final HttpCoreContext context = HttpCoreContext.create();
364         final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
365         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
366         final HttpEntity entity = Mockito.mock(HttpEntity.class);
367         request.setEntity(entity);
368 
369         executor.preProcess(request, httprocessor, context);
370         Mockito.verify(httprocessor).process(request, context);
371 
372         Mockito.when(conn.receiveResponseHeader()).thenReturn(
373                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 101, "OK"));
374         Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.TRUE);
375 
376         try {
377             executor.execute(request, conn, context);
378             Assert.fail("ProtocolException should have been thrown");
379         } catch (final ProtocolException ex) {
380             Mockito.verify(conn).close();
381             Assert.assertEquals(Boolean.FALSE, context.isRequestSent());
382         }
383     }
384 
385     @Test
386     public void testExecutionEntityEnclosingRequestWithExpectContinueNoResponse() throws Exception {
387         final HttpProcessor httprocessor = Mockito.mock(HttpProcessor.class);
388         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
389         final HttpRequestExecutor executor = new HttpRequestExecutor();
390 
391         final HttpCoreContext context = HttpCoreContext.create();
392         final HttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
393         request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
394         final HttpEntity entity = Mockito.mock(HttpEntity.class);
395         request.setEntity(entity);
396 
397         executor.preProcess(request, httprocessor, context);
398         Mockito.verify(httprocessor).process(request, context);
399 
400         Mockito.when(conn.receiveResponseHeader()).thenReturn(
401                 new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"));
402         Mockito.when(conn.isResponseAvailable(Mockito.anyInt())).thenReturn(Boolean.FALSE);
403 
404         final HttpResponse response = executor.execute(request, conn, context);
405         Mockito.verify(conn).sendRequestHeader(request);
406         Mockito.verify(conn).sendRequestEntity(request);
407         Mockito.verify(conn, Mockito.times(2)).flush();
408         Mockito.verify(conn).isResponseAvailable(3000);
409         Mockito.verify(conn).receiveResponseHeader();
410         Mockito.verify(conn).receiveResponseEntity(response);
411 
412         executor.postProcess(response, httprocessor, context);
413         Mockito.verify(httprocessor).process(response, context);
414     }
415 
416     @Test
417     public void testExecutionIOException() throws Exception {
418         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
419         final HttpRequestExecutor executor = new HttpRequestExecutor();
420 
421         final HttpCoreContext context = HttpCoreContext.create();
422         final HttpRequest request = new BasicHttpRequest("GET", "/");
423 
424         Mockito.doThrow(new IOException("Oopsie")).when(conn).sendRequestHeader(request);
425         try {
426             executor.execute(request, conn, context);
427             Assert.fail("IOException should have been thrown");
428         } catch (final IOException ex) {
429             Mockito.verify(conn).close();
430             Assert.assertEquals(Boolean.FALSE, context.isRequestSent());
431         }
432     }
433 
434     @Test
435     public void testExecutionRuntimeException() throws Exception {
436         final HttpClientConnection conn = Mockito.mock(HttpClientConnection.class);
437         final HttpRequestExecutor executor = new HttpRequestExecutor();
438 
439         final HttpCoreContext context = HttpCoreContext.create();
440         final HttpRequest request = new BasicHttpRequest("GET", "/");
441 
442         Mockito.doThrow(new RuntimeException("Oopsie")).when(conn).receiveResponseHeader();
443         try {
444             executor.execute(request, conn, context);
445             Assert.fail("IOException should have been thrown");
446         } catch (final RuntimeException ex) {
447             Mockito.verify(conn).close();
448             Assert.assertEquals(Boolean.TRUE, context.isRequestSent());
449         }
450     }
451 
452 }