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.nio;
28  
29  import java.nio.ByteBuffer;
30  import java.nio.channels.ByteChannel;
31  import java.nio.channels.SelectionKey;
32  import java.util.LinkedList;
33  
34  import org.apache.http.ByteChannelMock;
35  import org.apache.http.Consts;
36  import org.apache.http.HttpEntity;
37  import org.apache.http.HttpRequest;
38  import org.apache.http.HttpResponse;
39  import org.apache.http.HttpVersion;
40  import org.apache.http.ReadableByteChannelMock;
41  import org.apache.http.WritableByteChannelMock;
42  import org.apache.http.entity.StringEntity;
43  import org.apache.http.impl.nio.codecs.LengthDelimitedDecoder;
44  import org.apache.http.message.BasicHttpEntityEnclosingRequest;
45  import org.apache.http.message.BasicHttpRequest;
46  import org.apache.http.nio.ContentDecoder;
47  import org.apache.http.nio.ContentEncoder;
48  import org.apache.http.nio.IOControl;
49  import org.apache.http.nio.NHttpClientConnection;
50  import org.apache.http.nio.NHttpClientEventHandler;
51  import org.apache.http.nio.NHttpConnection;
52  import org.apache.http.nio.entity.HttpAsyncContentProducer;
53  import org.apache.http.nio.entity.NStringEntity;
54  import org.apache.http.nio.reactor.IOSession;
55  import org.apache.http.nio.util.SimpleInputBuffer;
56  import org.apache.http.protocol.HTTP;
57  import org.junit.Assert;
58  import org.junit.Before;
59  import org.junit.Test;
60  import org.mockito.Matchers;
61  import org.mockito.Mock;
62  import org.mockito.Mockito;
63  import org.mockito.MockitoAnnotations;
64  import org.mockito.invocation.InvocationOnMock;
65  import org.mockito.stubbing.Answer;
66  
67  public class TestDefaultNHttpClientConnection {
68  
69      @Mock
70      private IOSession session;
71      @Mock
72      private ByteChannel byteChan;
73      @Mock
74      private NHttpClientEventHandler handler;
75  
76      private DefaultNHttpClientConnection conn;
77  
78      @Before
79      public void setUp() throws Exception {
80          MockitoAnnotations.initMocks(this);
81          conn = new DefaultNHttpClientConnection(session, 32);
82      }
83  
84      @Test
85      public void testSubmitRequest() throws Exception {
86          final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
87          conn.submitRequest(request);
88  
89          Assert.assertNull(conn.getHttpRequest());
90          Assert.assertTrue(conn.hasBufferedOutput());
91  
92          Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
93      }
94  
95      @Test
96      public void testSubmitEntityEnclosingRequest() throws Exception {
97          final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
98          request.setEntity(new StringEntity("stuff"));
99  
100         Mockito.when(session.channel()).thenReturn(byteChan);
101 
102         Assert.assertEquals(0, conn.getMetrics().getRequestCount());
103         conn.submitRequest(request);
104 
105         Assert.assertSame(request, conn.getHttpRequest());
106         Assert.assertTrue(conn.hasBufferedOutput());
107         Assert.assertTrue(conn.isRequestSubmitted());
108         Assert.assertNotNull(conn.contentEncoder);
109         Assert.assertEquals(1, conn.getMetrics().getRequestCount());
110 
111         Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
112     }
113 
114     @Test
115     public void testOutputReset() throws Exception {
116         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
117         request.setEntity(new StringEntity("stuff"));
118 
119         Mockito.when(session.channel()).thenReturn(byteChan);
120 
121         conn.submitRequest(request);
122 
123         Assert.assertNotNull(conn.getHttpRequest());
124         Assert.assertNotNull(conn.contentEncoder);
125 
126         conn.resetOutput();
127 
128         Assert.assertNull(conn.getHttpRequest());
129         Assert.assertNull(conn.contentEncoder);
130     }
131 
132     static class RequestReadyAnswer implements Answer<Void> {
133 
134         private final HttpRequest request;
135 
136         RequestReadyAnswer(final HttpRequest request) {
137             super();
138             this.request = request;
139         }
140 
141         @Override
142         public Void answer(final InvocationOnMock invocation) throws Throwable {
143             final Object[] args = invocation.getArguments();
144             final NHttpClientConnection conn = (NHttpClientConnection) args[0];
145             conn.submitRequest(request);
146             return null;
147         }
148     }
149 
150     static class ProduceContentAnswer implements Answer<Void> {
151 
152         private final HttpAsyncContentProducer contentProducer;
153 
154         ProduceContentAnswer(final HttpAsyncContentProducer contentProducer) {
155             super();
156             this.contentProducer = contentProducer;
157         }
158 
159         @Override
160         public Void answer(final InvocationOnMock invocation) throws Throwable {
161             final Object[] args = invocation.getArguments();
162             final IOControl ioctrl = (IOControl) args[0];
163             final ContentEncoder encoder = (ContentEncoder) args[1];
164             contentProducer.produceContent(encoder, ioctrl);
165             return null;
166         }
167     }
168 
169     @Test
170     public void testProduceOutputShortMessageAfterSubmit() throws Exception {
171         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
172         final NStringEntity entity = new NStringEntity("stuff");
173         request.setEntity(entity);
174 
175         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
176         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
177         Mockito.when(session.channel()).thenReturn(channel);
178 
179         conn.submitRequest(request);
180         Assert.assertEquals(19, conn.outbuf.length());
181 
182         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
183             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
184 
185         conn.produceOutput(handler);
186 
187         Assert.assertNull(conn.getHttpRequest());
188         Assert.assertNull(conn.contentEncoder);
189         Assert.assertEquals("POST / HTTP/1.1\r\n\r\nstuff", wchannel.dump(Consts.ASCII));
190 
191         Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
192     }
193 
194     @Test
195     public void testProduceOutputLongMessageAfterSubmit() throws Exception {
196         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
197         final NStringEntity entity = new NStringEntity("a lot of various stuff");
198         request.setEntity(entity);
199 
200         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
201         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
202         Mockito.when(session.channel()).thenReturn(channel);
203 
204         conn.submitRequest(request);
205         Assert.assertEquals(19, conn.outbuf.length());
206 
207         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
208             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
209 
210         conn.produceOutput(handler);
211 
212         Assert.assertNull(conn.getHttpRequest());
213         Assert.assertNull(conn.contentEncoder);
214         Assert.assertEquals("POST / HTTP/1.1\r\n\r\na lot of various stuff", wchannel.dump(Consts.ASCII));
215 
216         Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
217     }
218 
219     @Test
220     public void testProduceOutputShortMessage() throws Exception {
221         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
222         final NStringEntity entity = new NStringEntity("stuff");
223         request.setEntity(entity);
224 
225         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
226         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
227         Mockito.when(session.channel()).thenReturn(channel);
228 
229         Mockito.doAnswer(new RequestReadyAnswer(request)).when(
230             handler).requestReady(Matchers.<NHttpClientConnection>any());
231 
232         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
233             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
234 
235         conn.produceOutput(handler);
236 
237         Assert.assertNull(conn.getHttpRequest());
238         Assert.assertNull(conn.contentEncoder);
239         Assert.assertEquals("POST / HTTP/1.1\r\n\r\nstuff", wchannel.dump(Consts.ASCII));
240 
241         Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
242     }
243 
244     @Test
245     public void testProduceOutputLongMessage() throws Exception {
246         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
247         final NStringEntity entity = new NStringEntity("a lot of various stuff");
248         request.setEntity(entity);
249 
250         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
251         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
252         Mockito.when(session.channel()).thenReturn(channel);
253 
254         Mockito.doAnswer(new RequestReadyAnswer(request)).when(
255             handler).requestReady(Matchers.<NHttpClientConnection>any());
256 
257         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
258             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
259 
260         conn.produceOutput(handler);
261 
262         Assert.assertNull(conn.getHttpRequest());
263         Assert.assertNull(conn.contentEncoder);
264         Assert.assertEquals("POST / HTTP/1.1\r\n\r\na lot of various stuff", wchannel.dump(Consts.ASCII));
265 
266         Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
267     }
268 
269     @Test
270     public void testProduceOutputLongMessageSaturatedChannel() throws Exception {
271         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
272         final NStringEntity entity = new NStringEntity("a lot of various stuff");
273         request.setEntity(entity);
274 
275         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 24));
276         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
277         Mockito.when(session.channel()).thenReturn(channel);
278 
279         Mockito.doAnswer(new RequestReadyAnswer(request)).when(
280             handler).requestReady(Matchers.<NHttpClientConnection>any());
281 
282         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
283             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
284 
285         conn.produceOutput(handler);
286 
287         Assert.assertNull(conn.getHttpRequest());
288         Assert.assertNull(conn.contentEncoder);
289         Assert.assertEquals("POST / HTTP/1.1\r\n\r\na lot", wchannel.dump(Consts.ASCII));
290         Assert.assertEquals(17, conn.outbuf.length());
291 
292         Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
293         Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
294     }
295 
296     @Test
297     public void testProduceOutputLongMessageSaturatedChannel2() throws Exception {
298         conn = new DefaultNHttpClientConnection(session, 24);
299         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
300         final NStringEntity entity = new NStringEntity("a loooooooooooooooooooooooot of various stuff");
301         request.setEntity(entity);
302 
303         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 24));
304         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
305         Mockito.when(session.channel()).thenReturn(channel);
306 
307         Mockito.doAnswer(new RequestReadyAnswer(request)).when(
308             handler).requestReady(Matchers.<NHttpClientConnection>any());
309 
310         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
311             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
312 
313         conn.produceOutput(handler);
314 
315         Assert.assertNotNull(conn.getHttpRequest());
316         Assert.assertNotNull(conn.contentEncoder);
317         Assert.assertEquals("POST / HTTP/1.1\r\n\r\na loo", wchannel.dump(Consts.ASCII));
318 
319         Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
320         Mockito.verify(wchannel, Mockito.times(3)).write(Matchers.<ByteBuffer>any());
321     }
322 
323     @Test
324     public void testProduceOutputLongChunkedMessage() throws Exception {
325         conn = new DefaultNHttpClientConnection(session, 64);
326 
327         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
328         request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
329         final NStringEntity entity = new NStringEntity("a lot of various stuff");
330         entity.setChunked(true);
331         request.setEntity(entity);
332 
333         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
334         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
335         Mockito.when(session.channel()).thenReturn(channel);
336 
337         Mockito.doAnswer(new RequestReadyAnswer(request)).when(
338             handler).requestReady(Matchers.<NHttpClientConnection>any());
339 
340         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
341             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
342 
343         conn.produceOutput(handler);
344 
345         Assert.assertNull(conn.getHttpRequest());
346         Assert.assertNull(conn.contentEncoder);
347         Assert.assertEquals("POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n" +
348                 "5\r\na lot\r\n11\r\n of various stuff\r\n0\r\n\r\n", wchannel.dump(Consts.ASCII));
349 
350         Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
351     }
352 
353     @Test
354     public void testProduceOutputLongChunkedMessageSaturatedChannel() throws Exception {
355         conn = new DefaultNHttpClientConnection(session, 64);
356 
357         final BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
358         request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
359         final NStringEntity entity = new NStringEntity("a lot of various stuff");
360         entity.setChunked(true);
361         request.setEntity(entity);
362 
363         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64, 64));
364         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
365         Mockito.when(session.channel()).thenReturn(channel);
366 
367         Mockito.doAnswer(new RequestReadyAnswer(request)).when(
368             handler).requestReady(Matchers.<NHttpClientConnection>any());
369 
370         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
371             handler).outputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
372 
373         conn.produceOutput(handler);
374 
375         Assert.assertNull(conn.getHttpRequest());
376         Assert.assertNull(conn.contentEncoder);
377         Assert.assertEquals("POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n" +
378                 "5\r\na lot\r\n11\r\n of", wchannel.dump(Consts.ASCII));
379         Assert.assertEquals(21, conn.outbuf.length());
380 
381         Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
382         Mockito.verify(wchannel, Mockito.times(2)).write(Matchers.<ByteBuffer>any());
383     }
384 
385     @Test
386     public void testProduceOutputClosingConnection() throws Exception {
387         final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
388 
389         final WritableByteChannelMock wchannel = Mockito.spy(new WritableByteChannelMock(64));
390         final ByteChannelMock channel = new ByteChannelMock(null, wchannel);
391         Mockito.when(session.channel()).thenReturn(channel);
392 
393         conn.submitRequest(request);
394         conn.close();
395 
396         Assert.assertEquals(NHttpConnection.CLOSING, conn.getStatus());
397 
398         conn.produceOutput(handler);
399 
400         Assert.assertEquals(NHttpConnection.CLOSED, conn.getStatus());
401 
402         Mockito.verify(wchannel, Mockito.times(1)).write(Matchers.<ByteBuffer>any());
403         Mockito.verify(session, Mockito.times(1)).close();
404         Mockito.verify(session, Mockito.never()).clearEvent(SelectionKey.OP_WRITE);
405         Mockito.verify(handler, Mockito.never()).requestReady(
406             Matchers.<NHttpClientConnection>any());
407         Mockito.verify(handler, Mockito.never()).outputReady(
408             Matchers.<NHttpClientConnection>any(), Matchers.<ContentEncoder>any());
409     }
410 
411     static class ResponseCapturingAnswer implements Answer<Void> {
412 
413         private final LinkedList<HttpResponse> responses;
414 
415         ResponseCapturingAnswer(final LinkedList<HttpResponse> responses) {
416             super();
417             this.responses = responses;
418         }
419 
420         @Override
421         public Void answer(final InvocationOnMock invocation) throws Throwable {
422             final Object[] args = invocation.getArguments();
423             final NHttpClientConnection conn = (NHttpClientConnection) args[0];
424             if (conn != null) {
425                 final HttpResponse response = conn.getHttpResponse();
426                 if (response != null) {
427                     responses.add(response);
428                 }
429             }
430             return null;
431         }
432 
433     }
434 
435     static class ConsumeContentAnswer implements Answer<Void> {
436 
437         private final SimpleInputBuffer buf;
438 
439         ConsumeContentAnswer(final SimpleInputBuffer buf) {
440             super();
441             this.buf = buf;
442         }
443 
444         @Override
445         public Void answer(final InvocationOnMock invocation) throws Throwable {
446             final Object[] args = invocation.getArguments();
447             final ContentDecoder decoder = (ContentDecoder) args[1];
448             buf.consumeContent(decoder);
449             return null;
450         }
451 
452     }
453 
454     @Test
455     public void testConsumeInputShortMessage() throws Exception {
456         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
457             new String[] {"HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nstuff"}, Consts.ASCII));
458         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
459         Mockito.when(session.channel()).thenReturn(channel);
460         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
461 
462         final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
463 
464         Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
465             handler).responseReceived(Matchers.<NHttpClientConnection>any());
466         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
467             handler).inputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentDecoder>any());
468 
469         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
470 
471         conn.consumeInput(handler);
472 
473         Assert.assertNull(conn.getHttpResponse());
474         Assert.assertNull(conn.contentDecoder);
475         Assert.assertEquals(1, conn.getMetrics().getResponseCount());
476         Assert.assertEquals(43, conn.getMetrics().getReceivedBytesCount());
477 
478         Mockito.verify(handler, Mockito.times(1)).responseReceived(
479             Matchers.<NHttpClientConnection>any());
480         Mockito.verify(handler, Mockito.times(1)).inputReady(
481             Matchers.<NHttpClientConnection>any(), Matchers.<LengthDelimitedDecoder>any());
482         Mockito.verify(rchannel, Mockito.times(2)).read(Matchers.<ByteBuffer>any());
483         Mockito.verify(handler, Mockito.never()).exception(
484             Matchers.<NHttpClientConnection>any(), Matchers.<Exception>any());
485 
486         Assert.assertFalse(responses.isEmpty());
487         final HttpResponse response = responses.getFirst();
488         Assert.assertNotNull(response);
489         Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
490         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
491         Assert.assertEquals("OK", response.getStatusLine().getReasonPhrase());
492         final HttpEntity entity = response.getEntity();
493         Assert.assertNotNull(entity);
494         Assert.assertEquals(5, entity.getContentLength());
495     }
496 
497     @Test
498     public void testConsumeInputLongMessage() throws Exception {
499         conn = new DefaultNHttpClientConnection(session, 1024);
500         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
501             new String[] {"HTTP/1.1 200 OK\r\nContent-Length: 100\r\n\r\na lot of stuff",
502                 "", ""}, Consts.ASCII));
503         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
504         Mockito.when(session.channel()).thenReturn(channel);
505         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
506 
507         final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
508 
509         Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
510             handler).responseReceived(Matchers.<NHttpClientConnection>any());
511         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
512             handler).inputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentDecoder>any());
513 
514         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
515 
516         conn.consumeInput(handler);
517 
518         Assert.assertNotNull(conn.getHttpResponse());
519         Assert.assertNotNull(conn.contentDecoder);
520         Assert.assertEquals(1, conn.getMetrics().getResponseCount());
521         Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
522 
523         Mockito.verify(handler, Mockito.times(1)).responseReceived(
524             Matchers.<NHttpClientConnection>any());
525         Mockito.verify(handler, Mockito.times(1)).inputReady(
526             Matchers.<NHttpClientConnection>any(), Matchers.<LengthDelimitedDecoder>any());
527         Mockito.verify(rchannel, Mockito.times(2)).read(Matchers.<ByteBuffer>any());
528         Mockito.verify(handler, Mockito.never()).exception(
529             Matchers.<NHttpClientConnection>any(), Matchers.<Exception>any());
530 
531         Assert.assertFalse(responses.isEmpty());
532         final HttpResponse response = responses.getFirst();
533         Assert.assertNotNull(response);
534         Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
535         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
536         Assert.assertEquals("OK", response.getStatusLine().getReasonPhrase());
537         final HttpEntity entity = response.getEntity();
538         Assert.assertNotNull(entity);
539         Assert.assertEquals(100, entity.getContentLength());
540 
541         conn.consumeInput(handler);
542 
543         Assert.assertEquals(1, conn.getMetrics().getResponseCount());
544         Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
545 
546         Mockito.verify(rchannel, Mockito.times(3)).read(Matchers.<ByteBuffer>any());
547         Mockito.verify(handler, Mockito.never()).exception(
548             Matchers.<NHttpClientConnection>any(), Matchers.<Exception>any());
549     }
550 
551     @Test
552     public void testConsumeInputBasicMessageNoEntity() throws Exception {
553         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
554             new String[] {"HTTP/1.1 100 Continue\r\n\r\n"}, Consts.ASCII));
555         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
556         Mockito.when(session.channel()).thenReturn(channel);
557         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
558 
559         final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
560 
561         Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
562             handler).responseReceived(Matchers.<NHttpClientConnection>any());
563         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
564             handler).inputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentDecoder>any());
565 
566         conn.consumeInput(handler);
567 
568         Assert.assertNull(conn.getHttpResponse());
569         Assert.assertNull(conn.contentDecoder);
570 
571         Mockito.verify(handler, Mockito.times(1)).responseReceived(
572             Matchers.<NHttpClientConnection>any());
573         Mockito.verify(handler, Mockito.never()).inputReady(
574             Matchers.<NHttpClientConnection>any(), Matchers.<LengthDelimitedDecoder>any());
575         Mockito.verify(rchannel, Mockito.times(1)).read(Matchers.<ByteBuffer>any());
576         Mockito.verify(handler, Mockito.never()).exception(
577             Matchers.<NHttpClientConnection>any(), Matchers.<Exception>any());
578 
579         Assert.assertFalse(responses.isEmpty());
580         final HttpResponse response = responses.getFirst();
581         Assert.assertNotNull(response);
582         Assert.assertEquals(HttpVersion.HTTP_1_1, response.getStatusLine().getProtocolVersion());
583         Assert.assertEquals(100, response.getStatusLine().getStatusCode());
584         final HttpEntity entity = response.getEntity();
585         Assert.assertNull(entity);
586     }
587 
588     @Test
589     public void testConsumeInputNoData() throws Exception {
590         conn = new DefaultNHttpClientConnection(session, 1024);
591         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
592             new String[] {"", ""}, Consts.ASCII));
593         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
594         Mockito.when(session.channel()).thenReturn(channel);
595         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
596 
597         final LinkedList<HttpResponse> responses = new LinkedList<HttpResponse>();
598 
599         Mockito.doAnswer(new ResponseCapturingAnswer(responses)).when(
600             handler).responseReceived(Matchers.<NHttpClientConnection>any());
601         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
602             handler).inputReady(Matchers.<NHttpClientConnection>any(), Matchers.<ContentDecoder>any());
603 
604         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
605 
606         conn.consumeInput(handler);
607 
608         Assert.assertNull(conn.getHttpResponse());
609         Assert.assertNull(conn.contentDecoder);
610         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
611         Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
612 
613         Mockito.verify(handler, Mockito.never()).responseReceived(
614             Matchers.<NHttpClientConnection>any());
615         Mockito.verify(handler, Mockito.never()).inputReady(
616             Matchers.<NHttpClientConnection>any(), Matchers.<LengthDelimitedDecoder>any());
617         Mockito.verify(rchannel, Mockito.times(1)).read(Matchers.<ByteBuffer>any());
618         Mockito.verify(handler, Mockito.never()).exception(
619             Matchers.<NHttpClientConnection>any(), Matchers.<Exception>any());
620 
621         conn.consumeInput(handler);
622 
623         Assert.assertNull(conn.getHttpResponse());
624         Assert.assertNull(conn.contentDecoder);
625         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
626         Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
627 
628         Mockito.verify(handler, Mockito.never()).responseReceived(
629             Matchers.<NHttpClientConnection>any());
630         Mockito.verify(handler, Mockito.never()).inputReady(
631             Matchers.<NHttpClientConnection>any(), Matchers.<LengthDelimitedDecoder>any());
632         Mockito.verify(rchannel, Mockito.times(2)).read(Matchers.<ByteBuffer>any());
633         Mockito.verify(handler, Mockito.never()).exception(
634             Matchers.<NHttpClientConnection>any(), Matchers.<Exception>any());
635 
636         conn.consumeInput(handler);
637         Assert.assertNull(conn.getHttpResponse());
638         Assert.assertNull(conn.contentDecoder);
639         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
640         Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
641 
642         Mockito.verify(handler, Mockito.never()).responseReceived(
643             Matchers.<NHttpClientConnection>any());
644         Mockito.verify(handler, Mockito.never()).inputReady(
645             Matchers.<NHttpClientConnection>any(), Matchers.<LengthDelimitedDecoder>any());
646         Mockito.verify(rchannel, Mockito.times(3)).read(Matchers.<ByteBuffer>any());
647         Mockito.verify(handler, Mockito.times(1)).endOfInput(
648             Matchers.<NHttpClientConnection>any());
649         Mockito.verify(handler, Mockito.never()).exception(
650             Matchers.<NHttpClientConnection>any(), Matchers.<Exception>any());
651 
652     }
653 
654     @Test
655     public void testConsumeInputConnectionClosed() throws Exception {
656         conn = new DefaultNHttpClientConnection(session, 1024);
657         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
658             new String[] {"", ""}, Consts.ASCII));
659         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
660         Mockito.when(session.channel()).thenReturn(channel);
661         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
662 
663         conn.close();
664         conn.consumeInput(handler);
665         Mockito.verify(rchannel, Mockito.never()).read(Matchers.<ByteBuffer>any());
666         Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_READ);
667     }
668 
669 }