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