1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.nio.protocol;
29
30 import java.io.IOException;
31 import java.net.SocketTimeoutException;
32
33 import org.apache.http.ConnectionClosedException;
34 import org.apache.http.HttpException;
35 import org.apache.http.HttpRequest;
36 import org.apache.http.HttpStatus;
37 import org.apache.http.HttpVersion;
38 import org.apache.http.entity.BasicHttpEntity;
39 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
40 import org.apache.http.message.BasicHttpRequest;
41 import org.apache.http.message.BasicHttpResponse;
42 import org.apache.http.nio.ContentDecoder;
43 import org.apache.http.nio.ContentEncoder;
44 import org.apache.http.nio.NHttpClientConnection;
45 import org.apache.http.nio.NHttpConnection;
46 import org.apache.http.nio.entity.NStringEntity;
47 import org.apache.http.nio.protocol.HttpAsyncRequestExecutor.State;
48 import org.apache.http.protocol.BasicHttpContext;
49 import org.apache.http.protocol.HTTP;
50 import org.apache.http.protocol.HttpContext;
51 import org.junit.After;
52 import org.junit.Assert;
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.mockito.Matchers;
56 import org.mockito.Mockito;
57
58 public class TestHttpAsyncRequestExecutor {
59
60 private HttpAsyncRequestExecutor protocolHandler;
61 private HttpContext connContext;
62 private NHttpClientConnection conn;
63 private HttpAsyncClientExchangeHandler exchangeHandler;
64 private ContentEncoder encoder;
65 private ContentDecoder decoder;
66
67 @Before
68 public void setUp() throws Exception {
69 this.protocolHandler = new HttpAsyncRequestExecutor();
70 this.connContext = new BasicHttpContext();
71 this.conn = Mockito.mock(NHttpClientConnection.class);
72 this.exchangeHandler = Mockito.mock(HttpAsyncClientExchangeHandler.class);
73 this.encoder = Mockito.mock(ContentEncoder.class);
74 this.decoder = Mockito.mock(ContentDecoder.class);
75 Mockito.when(this.conn.getContext()).thenReturn(this.connContext);
76 }
77
78 @After
79 public void tearDown() throws Exception {
80 }
81
82 @Test
83 public void testConnected() throws Exception {
84 final HttpRequest request = new BasicHttpRequest("GET", "/");
85 Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
86 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
87
88 this.protocolHandler.connected(this.conn, null);
89
90 final State state = (State) this.connContext.getAttribute(
91 HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE);
92 Assert.assertNotNull(state);
93 Mockito.verify(this.exchangeHandler).generateRequest();
94 Assert.assertSame(request, state.getRequest());
95 Mockito.verify(this.conn).submitRequest(request);
96 Mockito.verify(this.exchangeHandler).requestCompleted();
97 Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
98 Assert.assertEquals("request state: COMPLETED; request: GET / HTTP/1.1; " +
99 "response state: READY; response: ; valid: true;", state.toString());
100 }
101
102 @Test
103 public void testClosed() throws Exception {
104 final State state = new HttpAsyncRequestExecutor.State();
105 state.setRequestState(MessageState.READY);
106 state.setResponseState(MessageState.READY);
107 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
108 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
109
110 this.protocolHandler.closed(this.conn);
111
112 Mockito.verify(this.exchangeHandler, Mockito.never()).close();
113 }
114
115 @Test
116 public void testClosedNullState() throws Exception {
117 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
118
119 this.protocolHandler.closed(this.conn);
120
121 Mockito.verify(this.exchangeHandler).close();
122 }
123
124 @Test
125 public void testClosedInconsistentState() throws Exception {
126 final State state = new HttpAsyncRequestExecutor.State();
127 state.setRequestState(MessageState.COMPLETED);
128 state.setResponseState(MessageState.INIT);
129 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
130 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
131
132 this.protocolHandler.closed(this.conn);
133
134 Mockito.verify(this.exchangeHandler).failed(Matchers.any(ConnectionClosedException.class));
135 }
136
137 @Test
138 public void testHttpExceptionHandling() throws Exception {
139 final State state = new HttpAsyncRequestExecutor.State();
140 state.setRequestState(MessageState.COMPLETED);
141 state.setResponseState(MessageState.COMPLETED);
142 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
143 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
144
145 final HttpException httpex = new HttpException();
146 this.protocolHandler.exception(this.conn, httpex);
147
148 Mockito.verify(this.exchangeHandler).failed(httpex);
149 Mockito.verify(this.conn).shutdown();
150 }
151
152 @Test
153 public void testIOExceptionHandling() throws Exception {
154 final State state = new HttpAsyncRequestExecutor.State();
155 state.setRequestState(MessageState.COMPLETED);
156 state.setResponseState(MessageState.COMPLETED);
157 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
158 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
159
160 final IOException ioex = new IOException();
161 this.protocolHandler.exception(this.conn, ioex);
162
163 Mockito.verify(this.exchangeHandler).failed(ioex);
164 Mockito.verify(this.conn).shutdown();
165 }
166
167 @Test
168 public void testBasicRequest() throws Exception {
169 final State state = new HttpAsyncRequestExecutor.State();
170 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
171 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
172 final HttpRequest request = new BasicHttpRequest("GET", "/");
173 Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
174
175 this.protocolHandler.requestReady(this.conn);
176
177 Mockito.verify(this.exchangeHandler).generateRequest();
178 Assert.assertSame(request, state.getRequest());
179
180 Mockito.verify(this.conn).submitRequest(request);
181 Mockito.verify(this.exchangeHandler).requestCompleted();
182 Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
183 }
184
185 @Test
186 public void testNullRequest() throws Exception {
187 final State state = new HttpAsyncRequestExecutor.State();
188 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
189 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
190 Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(null);
191
192 this.protocolHandler.requestReady(this.conn);
193
194 Mockito.verify(this.exchangeHandler).generateRequest();
195 Assert.assertNull(state.getRequest());
196
197 Mockito.verify(this.conn, Mockito.times(1)).suspendOutput();
198 Mockito.verify(this.conn, Mockito.never()).submitRequest(Matchers.<HttpRequest>any());
199 }
200
201 @Test
202 public void testEntityEnclosingRequestWithoutExpectContinue() throws Exception {
203 final State state = new HttpAsyncRequestExecutor.State();
204 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
205 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
206 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
207 request.setEntity(new NStringEntity("stuff"));
208 Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
209
210 this.protocolHandler.requestReady(this.conn);
211
212 Mockito.verify(this.exchangeHandler).generateRequest();
213 Assert.assertSame(request, state.getRequest());
214 Mockito.verify(this.conn).submitRequest(request);
215 Mockito.verify(this.exchangeHandler, Mockito.never()).requestCompleted();
216 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
217 }
218
219 @Test
220 public void testEntityEnclosingRequestWithExpectContinue() throws Exception {
221 final State state = new HttpAsyncRequestExecutor.State();
222 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
223 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
224 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
225 request.setHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE);
226 Mockito.when(this.exchangeHandler.generateRequest()).thenReturn(request);
227 Mockito.when(this.conn.getSocketTimeout()).thenReturn(1000);
228
229 this.protocolHandler.requestReady(this.conn);
230
231 Mockito.verify(this.exchangeHandler).generateRequest();
232 Assert.assertSame(request, state.getRequest());
233 Mockito.verify(this.conn).submitRequest(request);
234 Mockito.verify(this.conn).setSocketTimeout(3000);
235 Assert.assertEquals(1000, state.getTimeout());
236 Mockito.verify(this.exchangeHandler, Mockito.never()).requestCompleted();
237 Assert.assertEquals(MessageState.ACK_EXPECTED, state.getRequestState());
238 }
239
240 @Test
241 public void testRequestContentOutput() throws Exception {
242 final State state = new HttpAsyncRequestExecutor.State();
243 state.setRequestState(MessageState.BODY_STREAM);
244 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
245 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
246 Mockito.when(this.encoder.isCompleted()).thenReturn(Boolean.FALSE);
247
248 this.protocolHandler.outputReady(this.conn, this.encoder);
249
250 Mockito.verify(this.exchangeHandler).produceContent(this.encoder, this.conn);
251 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
252 }
253
254 @Test
255 public void testRequestContentOutputCompleted() throws Exception {
256 final State state = new HttpAsyncRequestExecutor.State();
257 state.setRequestState(MessageState.BODY_STREAM);
258 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
259 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
260 Mockito.when(this.encoder.isCompleted()).thenReturn(Boolean.TRUE);
261
262 this.protocolHandler.outputReady(this.conn, this.encoder);
263
264 Mockito.verify(this.exchangeHandler).produceContent(this.encoder, this.conn);
265 Mockito.verify(this.exchangeHandler).requestCompleted();
266 Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
267 }
268
269 @Test
270 public void testRequestContentContinueExpected() throws Exception {
271 final State state = new HttpAsyncRequestExecutor.State();
272 state.setRequestState(MessageState.ACK_EXPECTED);
273 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
274 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
275
276 this.protocolHandler.outputReady(this.conn, this.encoder);
277
278 Mockito.verify(this.conn).suspendOutput();
279 Mockito.verify(this.exchangeHandler, Mockito.never()).produceContent(this.encoder, this.conn);
280 Assert.assertEquals(MessageState.ACK_EXPECTED, state.getRequestState());
281 }
282
283 @Test
284 public void testBasicResponse() throws Exception {
285 final State state = new HttpAsyncRequestExecutor.State();
286 final HttpRequest request = new BasicHttpRequest("GET", "/");
287 state.setRequest(request);
288 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
289 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
290 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
291 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
292
293 this.protocolHandler.responseReceived(this.conn);
294
295 Assert.assertSame(response, state.getResponse());
296 Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
297 }
298
299 @Test
300 public void testResponseContinue() throws Exception {
301 final State state = new HttpAsyncRequestExecutor.State();
302 state.setRequestState(MessageState.ACK_EXPECTED);
303 state.setTimeout(1000);
304 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
305 request.setEntity(new NStringEntity("stuff"));
306 state.setRequest(request);
307 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
308 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
309 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
310 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
311
312 this.protocolHandler.responseReceived(this.conn);
313
314 Assert.assertNull(state.getResponse());
315 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
316 Assert.assertEquals(MessageState.READY, state.getResponseState());
317 Mockito.verify(this.conn).setSocketTimeout(1000);
318 Mockito.verify(this.conn).requestOutput();
319 }
320
321 @Test
322 public void testResponseContinueOutOfSequence() throws Exception {
323 final State state = new HttpAsyncRequestExecutor.State();
324 state.setRequestState(MessageState.COMPLETED);
325 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
326 request.setEntity(new NStringEntity("stuff"));
327 state.setRequest(request);
328 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
329 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
330 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 100, "Continue");
331 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
332
333 this.protocolHandler.responseReceived(this.conn);
334
335 Assert.assertNull(state.getResponse());
336 Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
337 Mockito.verify(this.conn, Mockito.never()).requestOutput();
338 }
339
340 @Test(expected=HttpException.class)
341 public void testResponseUnsupported1xx() throws Exception {
342 final State state = new HttpAsyncRequestExecutor.State();
343 state.setRequestState(MessageState.ACK_EXPECTED);
344 state.setTimeout(1000);
345 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
346 request.setEntity(new NStringEntity("stuff"));
347 state.setRequest(request);
348 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
349 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
350 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 111, "WTF?");
351 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
352
353 this.protocolHandler.responseReceived(this.conn);
354 }
355
356 @Test
357 public void testResponseExpectationFailed() throws Exception {
358 final State state = new HttpAsyncRequestExecutor.State();
359 state.setRequestState(MessageState.ACK_EXPECTED);
360 state.setTimeout(1000);
361 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
362 request.setEntity(new NStringEntity("stuff"));
363 state.setRequest(request);
364 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
365 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
366 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
367 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
368
369 this.protocolHandler.responseReceived(this.conn);
370
371 Assert.assertSame(response, state.getResponse());
372 Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
373 Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
374 Mockito.verify(this.conn).setSocketTimeout(1000);
375 Mockito.verify(this.conn).resetOutput();
376 }
377
378 @Test
379 public void testEarlyResponse() throws Exception {
380 final State state = new HttpAsyncRequestExecutor.State();
381 state.setRequestState(MessageState.BODY_STREAM);
382 state.setTimeout(1000);
383 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
384 request.setEntity(new NStringEntity("stuff"));
385 state.setRequest(request);
386 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
387 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
388 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 403, "Unauthorized");
389 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
390
391 this.protocolHandler.responseReceived(this.conn);
392
393 Assert.assertSame(response, state.getResponse());
394 Assert.assertEquals(MessageState.COMPLETED, state.getRequestState());
395 Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
396 Mockito.verify(this.conn).suspendOutput();
397 Mockito.verify(this.conn).resetOutput();
398 Assert.assertFalse(state.isValid());
399 }
400
401 @Test
402 public void testEarlyNonErrorResponse() throws Exception {
403 final State state = new HttpAsyncRequestExecutor.State();
404 state.setRequestState(MessageState.BODY_STREAM);
405 state.setTimeout(1000);
406 final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
407 request.setEntity(new NStringEntity("stuff"));
408 state.setRequest(request);
409 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
410 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
411 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
412 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
413
414 this.protocolHandler.responseReceived(this.conn);
415
416 Assert.assertSame(response, state.getResponse());
417 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
418 Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
419 Mockito.verify(this.conn, Mockito.never()).suspendOutput();
420 Mockito.verify(this.conn, Mockito.never()).resetOutput();
421 Assert.assertTrue(state.isValid());
422 }
423
424 @Test
425 public void testResponseToHead() throws Exception {
426 final State state = new HttpAsyncRequestExecutor.State();
427 final HttpRequest request = new BasicHttpRequest("HEAD", "/");
428 state.setRequest(request);
429 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
430 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
431 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
432 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
433
434 this.protocolHandler.responseReceived(this.conn);
435
436 Assert.assertEquals(MessageState.READY, state.getResponseState());
437 Assert.assertEquals(MessageState.READY, state.getRequestState());
438 Assert.assertNull(state.getRequest());
439 Assert.assertNull(state.getResponse());
440 Mockito.verify(this.exchangeHandler).responseReceived(response);
441 Mockito.verify(this.conn).resetInput();
442 Mockito.verify(this.conn, Mockito.never()).close();
443 }
444
445 @Test
446 public void testResponseToConnect() throws Exception {
447 final State state = new HttpAsyncRequestExecutor.State();
448 final HttpRequest request = new BasicHttpRequest("Connect", "/");
449 state.setRequest(request);
450 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
451 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
452 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
453 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
454
455 this.protocolHandler.responseReceived(this.conn);
456
457 Assert.assertEquals(MessageState.READY, state.getResponseState());
458 Assert.assertEquals(MessageState.READY, state.getRequestState());
459 Assert.assertNull(state.getRequest());
460 Assert.assertNull(state.getResponse());
461 Mockito.verify(this.exchangeHandler).responseReceived(response);
462 Mockito.verify(this.conn).resetInput();
463 Mockito.verify(this.conn, Mockito.never()).close();
464 }
465
466 @Test
467 public void testResponseNotModified() throws Exception {
468 final State state = new HttpAsyncRequestExecutor.State();
469 final HttpRequest request = new BasicHttpRequest("Connect", "/");
470 state.setRequest(request);
471 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
472 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
473 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
474 HttpStatus.SC_NOT_MODIFIED, "Not modified");
475 response.setEntity(new BasicHttpEntity());
476 Mockito.when(this.conn.getHttpResponse()).thenReturn(response);
477
478 this.protocolHandler.responseReceived(this.conn);
479
480 Assert.assertEquals(MessageState.READY, state.getResponseState());
481 Assert.assertEquals(MessageState.READY, state.getRequestState());
482 Assert.assertNull(state.getRequest());
483 Assert.assertNull(state.getResponse());
484 Assert.assertNull(response.getEntity());
485 Mockito.verify(this.exchangeHandler).responseReceived(response);
486 Mockito.verify(this.conn).resetInput();
487 Mockito.verify(this.conn, Mockito.never()).close();
488 }
489
490 @Test
491 public void testResponseContentInput() throws Exception {
492 final State state = new HttpAsyncRequestExecutor.State();
493 state.setResponseState(MessageState.BODY_STREAM);
494 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
495 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
496 Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.FALSE);
497
498 this.protocolHandler.inputReady(this.conn, this.decoder);
499
500 Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
501 Assert.assertEquals(MessageState.BODY_STREAM, state.getResponseState());
502 }
503
504 @Test
505 public void testResponseContentOutputCompleted() throws Exception {
506 final State state = new HttpAsyncRequestExecutor.State();
507 final HttpRequest request = new BasicHttpRequest("GET", "/");
508 state.setRequest(request);
509 state.setResponseState(MessageState.BODY_STREAM);
510 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
511 state.setResponse(response);
512 Mockito.when(this.exchangeHandler.isDone()).thenReturn(Boolean.TRUE);
513 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
514 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
515 Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
516
517 this.protocolHandler.inputReady(this.conn, this.decoder);
518
519 Assert.assertEquals(MessageState.READY, state.getRequestState());
520 Assert.assertEquals(MessageState.READY, state.getResponseState());
521 Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
522 Mockito.verify(this.exchangeHandler).responseCompleted();
523 Mockito.verify(this.conn, Mockito.never()).close();
524 }
525
526 @Test
527 public void testResponseContentOutputCompletedHandlerNotDone() throws Exception {
528 final State state = new HttpAsyncRequestExecutor.State();
529 state.setResponseState(MessageState.BODY_STREAM);
530 final HttpRequest request = new BasicHttpRequest("GET", "/");
531 state.setRequest(request);
532 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
533 state.setResponse(response);
534 Mockito.when(this.exchangeHandler.isDone()).thenReturn(Boolean.FALSE);
535 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
536 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
537 Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
538 Mockito.when(this.conn.isOpen()).thenReturn(Boolean.TRUE);
539
540 this.protocolHandler.inputReady(this.conn, this.decoder);
541
542 Assert.assertEquals(MessageState.READY, state.getRequestState());
543 Assert.assertEquals(MessageState.READY, state.getResponseState());
544 Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
545 Mockito.verify(this.exchangeHandler).responseCompleted();
546 Mockito.verify(this.conn).requestOutput();
547 }
548
549 @Test
550 public void testResponseContentOutputCompletedHandlerNotDoneConnClosed() throws Exception {
551 final State state = new HttpAsyncRequestExecutor.State();
552 final HttpRequest request = new BasicHttpRequest("GET", "/");
553 state.setRequest(request);
554 state.setResponseState(MessageState.BODY_STREAM);
555 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
556 state.setResponse(response);
557 Mockito.when(this.exchangeHandler.isDone()).thenReturn(Boolean.FALSE);
558 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
559 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
560 Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
561 Mockito.when(this.conn.isOpen()).thenReturn(Boolean.FALSE);
562
563 this.protocolHandler.inputReady(this.conn, this.decoder);
564
565 Assert.assertEquals(MessageState.READY, state.getRequestState());
566 Assert.assertEquals(MessageState.READY, state.getResponseState());
567 Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
568 Mockito.verify(this.exchangeHandler).responseCompleted();
569 Mockito.verify(this.conn, Mockito.never()).requestOutput();
570 }
571
572 @Test
573 public void testResponseInvalidState() throws Exception {
574 final State state = new HttpAsyncRequestExecutor.State();
575 final HttpRequest request = new BasicHttpRequest("GET", "/");
576 state.setRequest(request);
577 state.setResponseState(MessageState.BODY_STREAM);
578 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
579 state.setResponse(response);
580 state.invalidate();
581 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
582 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
583 Mockito.when(this.decoder.isCompleted()).thenReturn(Boolean.TRUE);
584
585 this.protocolHandler.inputReady(this.conn, this.decoder);
586
587 Assert.assertEquals(MessageState.READY, state.getRequestState());
588 Assert.assertEquals(MessageState.READY, state.getResponseState());
589 Mockito.verify(this.exchangeHandler).consumeContent(this.decoder, this.conn);
590 Mockito.verify(this.conn).close();
591 }
592
593 @Test
594 public void testEndOfInput() throws Exception {
595 final State state = new HttpAsyncRequestExecutor.State();
596 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
597
598 this.protocolHandler.endOfInput(this.conn);
599
600 Mockito.verify(this.conn).close();
601 }
602
603 @Test
604 public void testPrematureEndOfInput() throws Exception {
605 final State state = new HttpAsyncRequestExecutor.State();
606 state.setRequestState(MessageState.COMPLETED);
607 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
608 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
609
610 this.protocolHandler.endOfInput(this.conn);
611
612 Assert.assertFalse(state.isValid());
613
614 Mockito.verify(this.conn).close();
615 Mockito.verify(this.exchangeHandler).failed(Matchers.any(ConnectionClosedException.class));
616 }
617
618 @Test
619 public void testPrematureEndOfInputRequestReady() throws Exception {
620 final State state = new HttpAsyncRequestExecutor.State();
621 state.setRequestState(MessageState.READY);
622 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
623 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
624
625 this.protocolHandler.endOfInput(this.conn);
626
627 Assert.assertTrue(state.isValid());
628
629 Mockito.verify(this.exchangeHandler).inputTerminated();
630 }
631
632 @Test
633 public void testTimeoutNoHandler() throws Exception {
634 final State state = new HttpAsyncRequestExecutor.State();
635 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
636
637 Mockito.when(this.conn.getStatus()).thenReturn(
638 NHttpConnection.ACTIVE, NHttpConnection.CLOSING);
639
640 this.protocolHandler.timeout(this.conn);
641
642 Mockito.verify(this.conn).close();
643 Mockito.verify(this.conn).setSocketTimeout(250);
644 }
645
646 @Test
647 public void testExpectContinueTimeout() throws Exception {
648 final State state = new HttpAsyncRequestExecutor.State();
649 state.setRequestState(MessageState.ACK_EXPECTED);
650 state.setTimeout(1000);
651 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
652 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
653
654 this.protocolHandler.timeout(this.conn);
655
656 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
657 Assert.assertTrue(state.isValid());
658 Mockito.verify(this.conn).setSocketTimeout(1000);
659 Mockito.verify(this.conn).requestOutput();
660 }
661
662 @Test
663 public void testTimeoutActiveConnection() throws Exception {
664 final State state = new HttpAsyncRequestExecutor.State();
665 state.setRequestState(MessageState.BODY_STREAM);
666 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
667 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
668 Mockito.when(this.conn.getStatus()).thenReturn(NHttpConnection.ACTIVE, NHttpConnection.CLOSED);
669
670 this.protocolHandler.timeout(this.conn);
671
672 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
673 Assert.assertFalse(state.isValid());
674 Mockito.verify(this.exchangeHandler).failed(Matchers.any(SocketTimeoutException.class));
675 Mockito.verify(this.exchangeHandler).close();
676 Mockito.verify(this.conn).close();
677 Mockito.verify(this.conn, Mockito.never()).setSocketTimeout(Matchers.anyInt());
678 }
679
680 @Test
681 public void testTimeoutActiveConnectionBufferedData() throws Exception {
682 final State state = new HttpAsyncRequestExecutor.State();
683 state.setRequestState(MessageState.BODY_STREAM);
684 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
685 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
686 Mockito.when(this.conn.getStatus()).thenReturn(NHttpConnection.ACTIVE, NHttpConnection.CLOSING);
687
688 this.protocolHandler.timeout(this.conn);
689
690 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
691 Assert.assertFalse(state.isValid());
692 Mockito.verify(this.exchangeHandler).failed(Matchers.any(SocketTimeoutException.class));
693 Mockito.verify(this.exchangeHandler).close();
694 Mockito.verify(this.conn).close();
695 Mockito.verify(this.conn).setSocketTimeout(250);
696 }
697
698 @Test
699 public void testTimeoutClosingConnection() throws Exception {
700 final State state = new HttpAsyncRequestExecutor.State();
701 state.setRequestState(MessageState.BODY_STREAM);
702 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
703 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
704 Mockito.when(this.conn.getStatus()).thenReturn(NHttpConnection.CLOSING, NHttpConnection.CLOSED);
705
706 this.protocolHandler.timeout(this.conn);
707
708 Assert.assertEquals(MessageState.BODY_STREAM, state.getRequestState());
709 Assert.assertFalse(state.isValid());
710 Mockito.verify(this.exchangeHandler).failed(Matchers.any(SocketTimeoutException.class));
711 Mockito.verify(this.exchangeHandler).close();
712 Mockito.verify(this.conn).shutdown();
713 }
714
715 @Test
716 public void testExchangeDone() throws Exception {
717 final State state = new HttpAsyncRequestExecutor.State();
718 final HttpRequest request = new BasicHttpRequest("GET", "/");
719 state.setRequest(request);
720 final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
721 state.setResponse(response);
722 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_EXCHANGE_STATE, state);
723 this.connContext.setAttribute(HttpAsyncRequestExecutor.HTTP_HANDLER, this.exchangeHandler);
724 Mockito.when(this.exchangeHandler.isDone()).thenReturn(Boolean.TRUE);
725
726 Assert.assertEquals("request state: READY; request: GET / HTTP/1.1; " +
727 "response state: READY; response: HTTP/1.1 200 OK; valid: true;",
728 state.toString());
729
730 this.protocolHandler.requestReady(this.conn);
731
732 Assert.assertEquals(MessageState.READY, state.getRequestState());
733 Assert.assertEquals(MessageState.READY, state.getResponseState());
734 }
735
736 }