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.HttpEntityEnclosingRequest;
38  import org.apache.http.HttpRequest;
39  import org.apache.http.HttpResponse;
40  import org.apache.http.HttpVersion;
41  import org.apache.http.ReadableByteChannelMock;
42  import org.apache.http.WritableByteChannelMock;
43  import org.apache.http.entity.StringEntity;
44  import org.apache.http.impl.nio.codecs.LengthDelimitedDecoder;
45  import org.apache.http.message.BasicHttpResponse;
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.NHttpServerConnection;
50  import org.apache.http.nio.NHttpConnection;
51  import org.apache.http.nio.NHttpServerEventHandler;
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 TestDefaultNHttpServerConnection {
68  
69      @Mock
70      private IOSession session;
71      @Mock
72      private ByteChannel byteChan;
73      @Mock
74      private NHttpServerEventHandler handler;
75  
76      private DefaultNHttpServerConnection conn;
77  
78      @Before
79      public void setUp() throws Exception {
80          MockitoAnnotations.initMocks(this);
81          conn = new DefaultNHttpServerConnection(session, 32);
82      }
83  
84      @Test
85      public void testSubmitRequest() throws Exception {
86          final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
87          conn.submitResponse(response);
88  
89          Assert.assertNull(conn.getHttpResponse());
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 BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
98          response.setEntity(new StringEntity("stuff"));
99  
100         Mockito.when(session.channel()).thenReturn(byteChan);
101 
102         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
103         conn.submitResponse(response);
104 
105         Assert.assertSame(response, conn.getHttpResponse());
106         Assert.assertTrue(conn.hasBufferedOutput());
107         Assert.assertTrue(conn.isResponseSubmitted());
108         Assert.assertNotNull(conn.contentEncoder);
109         Assert.assertEquals(1, conn.getMetrics().getResponseCount());
110 
111         Mockito.verify(session).setEvent(SelectionKey.OP_WRITE);
112     }
113 
114     @Test
115     public void testOutputReset() throws Exception {
116         final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
117         response.setEntity(new StringEntity("stuff"));
118 
119         Mockito.when(session.channel()).thenReturn(byteChan);
120 
121         conn.submitResponse(response);
122 
123         Assert.assertNotNull(conn.getHttpResponse());
124         Assert.assertNotNull(conn.contentEncoder);
125 
126         conn.resetOutput();
127 
128         Assert.assertNull(conn.getHttpResponse());
129         Assert.assertNull(conn.contentEncoder);
130     }
131 
132     static class ResponseReadyAnswer implements Answer<Void> {
133 
134         private final HttpResponse response;
135 
136         ResponseReadyAnswer(final HttpResponse response) {
137             super();
138             this.response = response;
139         }
140 
141         @Override
142         public Void answer(final InvocationOnMock invocation) throws Throwable {
143             final Object[] args = invocation.getArguments();
144             final NHttpServerConnection conn = (NHttpServerConnection) args[0];
145             conn.submitResponse(response);
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 BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
172         final NStringEntity entity = new NStringEntity("stuff");
173         response.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.submitResponse(response);
180         Assert.assertEquals(19, conn.outbuf.length());
181 
182         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
183             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
184 
185         conn.produceOutput(handler);
186 
187         Assert.assertNull(conn.getHttpResponse());
188         Assert.assertNull(conn.contentEncoder);
189         Assert.assertEquals("HTTP/1.1 200 OK\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 BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
197         final NStringEntity entity = new NStringEntity("a lot of various stuff");
198         response.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.submitResponse(response);
205         Assert.assertEquals(19, conn.outbuf.length());
206 
207         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
208             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
209 
210         conn.produceOutput(handler);
211 
212         Assert.assertNull(conn.getHttpResponse());
213         Assert.assertNull(conn.contentEncoder);
214         Assert.assertEquals("HTTP/1.1 200 OK\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 BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
222         final NStringEntity entity = new NStringEntity("stuff");
223         response.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 ResponseReadyAnswer(response)).when(
230             handler).responseReady(Matchers.<NHttpServerConnection>any());
231 
232         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
233             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
234 
235         conn.produceOutput(handler);
236 
237         Assert.assertNull(conn.getHttpResponse());
238         Assert.assertNull(conn.contentEncoder);
239         Assert.assertEquals("HTTP/1.1 200 OK\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 BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
247         final NStringEntity entity = new NStringEntity("a lot of various stuff");
248         response.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 ResponseReadyAnswer(response)).when(
255             handler).responseReady(Matchers.<NHttpServerConnection>any());
256 
257         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
258             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
259 
260         conn.produceOutput(handler);
261 
262         Assert.assertNull(conn.getHttpResponse());
263         Assert.assertNull(conn.contentEncoder);
264         Assert.assertEquals("HTTP/1.1 200 OK\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 BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
272         final NStringEntity entity = new NStringEntity("a lot of various stuff");
273         response.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 ResponseReadyAnswer(response)).when(
280             handler).responseReady(Matchers.<NHttpServerConnection>any());
281 
282         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
283             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
284 
285         conn.produceOutput(handler);
286 
287         Assert.assertNull(conn.getHttpResponse());
288         Assert.assertNull(conn.contentEncoder);
289         Assert.assertEquals("HTTP/1.1 200 OK\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 DefaultNHttpServerConnection(session, 24);
299         final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
300         final NStringEntity entity = new NStringEntity("a loooooooooooooooooooooooot of various stuff");
301         response.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 ResponseReadyAnswer(response)).when(
308             handler).responseReady(Matchers.<NHttpServerConnection>any());
309 
310         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
311             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
312 
313         conn.produceOutput(handler);
314 
315         Assert.assertNotNull(conn.getHttpResponse());
316         Assert.assertNotNull(conn.contentEncoder);
317         Assert.assertEquals("HTTP/1.1 200 OK\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 DefaultNHttpServerConnection(session, 64);
326 
327         final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
328         response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
329         final NStringEntity entity = new NStringEntity("a lot of various stuff");
330         entity.setChunked(true);
331         response.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 ResponseReadyAnswer(response)).when(
338             handler).responseReady(Matchers.<NHttpServerConnection>any());
339 
340         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
341             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
342 
343         conn.produceOutput(handler);
344 
345         Assert.assertNull(conn.getHttpResponse());
346         Assert.assertNull(conn.contentEncoder);
347         Assert.assertEquals("HTTP/1.1 200 OK\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 DefaultNHttpServerConnection(session, 64);
356 
357         final BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
358         response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
359         final NStringEntity entity = new NStringEntity("a lot of various stuff");
360         entity.setChunked(true);
361         response.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 ResponseReadyAnswer(response)).when(
368             handler).responseReady(Matchers.<NHttpServerConnection>any());
369 
370         Mockito.doAnswer(new ProduceContentAnswer(entity)).when(
371             handler).outputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
372 
373         conn.produceOutput(handler);
374 
375         Assert.assertNull(conn.getHttpResponse());
376         Assert.assertNull(conn.contentEncoder);
377         Assert.assertEquals("HTTP/1.1 200 OK\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 BasicHttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
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.submitResponse(response);
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()).responseReady(
406             Matchers.<NHttpServerConnection>any());
407         Mockito.verify(handler, Mockito.never()).outputReady(
408             Matchers.<NHttpServerConnection>any(), Matchers.<ContentEncoder>any());
409     }
410 
411     static class RequestCapturingAnswer implements Answer<Void> {
412 
413         private final LinkedList<HttpRequest> requests;
414 
415         RequestCapturingAnswer(final LinkedList<HttpRequest> requests) {
416             super();
417             this.requests = requests;
418         }
419 
420         @Override
421         public Void answer(final InvocationOnMock invocation) throws Throwable {
422             final Object[] args = invocation.getArguments();
423             final NHttpServerConnection conn = (NHttpServerConnection) args[0];
424             if (conn != null) {
425                 final HttpRequest request = conn.getHttpRequest();
426                 if (request != null) {
427                     requests.add(request);
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[] {"POST / HTTP/1.1\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<HttpRequest> requests = new LinkedList<HttpRequest>();
463 
464         Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
465             handler).requestReceived(Matchers.<NHttpServerConnection>any());
466         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
467             handler).inputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentDecoder>any());
468 
469         Assert.assertEquals(0, conn.getMetrics().getRequestCount());
470 
471         conn.consumeInput(handler);
472 
473         Assert.assertNull(conn.getHttpResponse());
474         Assert.assertNull(conn.contentDecoder);
475         Assert.assertEquals(1, conn.getMetrics().getRequestCount());
476         Assert.assertEquals(43, conn.getMetrics().getReceivedBytesCount());
477 
478         Mockito.verify(handler, Mockito.times(1)).requestReceived(
479             Matchers.<NHttpServerConnection>any());
480         Mockito.verify(handler, Mockito.times(1)).inputReady(
481             Matchers.<NHttpServerConnection>any(), Matchers.<LengthDelimitedDecoder>any());
482         Mockito.verify(rchannel, Mockito.times(2)).read(Matchers.<ByteBuffer>any());
483         Mockito.verify(handler, Mockito.never()).exception(
484             Matchers.<NHttpServerConnection>any(), Matchers.<Exception>any());
485 
486         Assert.assertFalse(requests.isEmpty());
487         final HttpRequest request = requests.getFirst();
488         Assert.assertNotNull(request);
489         Assert.assertEquals(HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion());
490         Assert.assertEquals("POST", request.getRequestLine().getMethod());
491         Assert.assertEquals("/", request.getRequestLine().getUri());
492         Assert.assertTrue(request instanceof HttpEntityEnclosingRequest);
493         final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
494         Assert.assertNotNull(entity);
495         Assert.assertEquals(5, entity.getContentLength());
496     }
497 
498     @Test
499     public void testConsumeInputLongMessage() throws Exception {
500         conn = new DefaultNHttpServerConnection(session, 1024);
501         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
502             new String[] {"POST / HTTP/1.1\r\nContent-Length: 100\r\n\r\na lot of stuff",
503                 "", ""}, Consts.ASCII));
504         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
505         Mockito.when(session.channel()).thenReturn(channel);
506         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
507 
508         final LinkedList<HttpRequest> requests = new LinkedList<HttpRequest>();
509 
510         Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
511             handler).requestReceived(Matchers.<NHttpServerConnection>any());
512         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
513             handler).inputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentDecoder>any());
514 
515         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
516 
517         conn.consumeInput(handler);
518 
519         Assert.assertNotNull(conn.getHttpRequest());
520         Assert.assertNotNull(conn.contentDecoder);
521         Assert.assertEquals(1, conn.getMetrics().getRequestCount());
522         Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
523 
524         Mockito.verify(handler, Mockito.times(1)).requestReceived(
525             Matchers.<NHttpServerConnection>any());
526         Mockito.verify(handler, Mockito.times(1)).inputReady(
527             Matchers.<NHttpServerConnection>any(), Matchers.<LengthDelimitedDecoder>any());
528         Mockito.verify(rchannel, Mockito.times(2)).read(Matchers.<ByteBuffer>any());
529         Mockito.verify(handler, Mockito.never()).exception(
530             Matchers.<NHttpServerConnection>any(), Matchers.<Exception>any());
531 
532         Assert.assertFalse(requests.isEmpty());
533         final HttpRequest request = requests.getFirst();
534         Assert.assertNotNull(request);
535         Assert.assertEquals(HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion());
536         Assert.assertEquals("POST", request.getRequestLine().getMethod());
537         Assert.assertEquals("/", request.getRequestLine().getUri());
538         Assert.assertTrue(request instanceof HttpEntityEnclosingRequest);
539         final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
540         Assert.assertNotNull(entity);
541         Assert.assertEquals(100, entity.getContentLength());
542 
543         conn.consumeInput(handler);
544 
545         Assert.assertEquals(1, conn.getMetrics().getRequestCount());
546         Assert.assertEquals(54, conn.getMetrics().getReceivedBytesCount());
547 
548         Mockito.verify(rchannel, Mockito.times(3)).read(Matchers.<ByteBuffer>any());
549         Mockito.verify(handler, Mockito.never()).exception(
550             Matchers.<NHttpServerConnection>any(), Matchers.<Exception>any());
551     }
552 
553     @Test
554     public void testConsumeInputBasicMessageNoEntity() throws Exception {
555         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
556             new String[] {"GET / HTTP/1.1\r\n\r\n"}, Consts.ASCII));
557         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
558         Mockito.when(session.channel()).thenReturn(channel);
559         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
560 
561         final LinkedList<HttpRequest> requests = new LinkedList<HttpRequest>();
562 
563         Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
564             handler).requestReceived(Matchers.<NHttpServerConnection>any());
565         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
566             handler).inputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentDecoder>any());
567 
568         conn.consumeInput(handler);
569 
570         Assert.assertNull(conn.getHttpResponse());
571         Assert.assertNull(conn.contentDecoder);
572 
573         Mockito.verify(handler, Mockito.times(1)).requestReceived(
574             Matchers.<NHttpServerConnection>any());
575         Mockito.verify(handler, Mockito.never()).inputReady(
576             Matchers.<NHttpServerConnection>any(), Matchers.<LengthDelimitedDecoder>any());
577         Mockito.verify(rchannel, Mockito.times(1)).read(Matchers.<ByteBuffer>any());
578         Mockito.verify(handler, Mockito.never()).exception(
579             Matchers.<NHttpServerConnection>any(), Matchers.<Exception>any());
580 
581         Assert.assertFalse(requests.isEmpty());
582         final HttpRequest request = requests.getFirst();
583         Assert.assertNotNull(request);
584         Assert.assertEquals(HttpVersion.HTTP_1_1, request.getRequestLine().getProtocolVersion());
585         Assert.assertEquals("GET", request.getRequestLine().getMethod());
586         Assert.assertEquals("/", request.getRequestLine().getUri());
587         Assert.assertFalse(request instanceof HttpEntityEnclosingRequest);
588     }
589 
590     @Test
591     public void testConsumeInputNoData() throws Exception {
592         conn = new DefaultNHttpServerConnection(session, 1024);
593         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
594             new String[] {"", ""}, Consts.ASCII));
595         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
596         Mockito.when(session.channel()).thenReturn(channel);
597         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
598 
599         final LinkedList<HttpRequest> requests = new LinkedList<HttpRequest>();
600 
601         Mockito.doAnswer(new RequestCapturingAnswer(requests)).when(
602             handler).requestReceived(Matchers.<NHttpServerConnection>any());
603         Mockito.doAnswer(new ConsumeContentAnswer(new SimpleInputBuffer(64))).when(
604             handler).inputReady(Matchers.<NHttpServerConnection>any(), Matchers.<ContentDecoder>any());
605 
606         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
607 
608         conn.consumeInput(handler);
609 
610         Assert.assertNull(conn.getHttpResponse());
611         Assert.assertNull(conn.contentDecoder);
612         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
613         Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
614 
615         Mockito.verify(handler, Mockito.never()).requestReceived(
616             Matchers.<NHttpServerConnection>any());
617         Mockito.verify(handler, Mockito.never()).inputReady(
618             Matchers.<NHttpServerConnection>any(), Matchers.<LengthDelimitedDecoder>any());
619         Mockito.verify(rchannel, Mockito.times(1)).read(Matchers.<ByteBuffer>any());
620         Mockito.verify(handler, Mockito.never()).exception(
621             Matchers.<NHttpServerConnection>any(), Matchers.<Exception>any());
622 
623         conn.consumeInput(handler);
624 
625         Assert.assertNull(conn.getHttpResponse());
626         Assert.assertNull(conn.contentDecoder);
627         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
628         Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
629 
630         Mockito.verify(handler, Mockito.never()).requestReceived(
631             Matchers.<NHttpServerConnection>any());
632         Mockito.verify(handler, Mockito.never()).inputReady(
633             Matchers.<NHttpServerConnection>any(), Matchers.<LengthDelimitedDecoder>any());
634         Mockito.verify(rchannel, Mockito.times(2)).read(Matchers.<ByteBuffer>any());
635         Mockito.verify(handler, Mockito.never()).exception(
636             Matchers.<NHttpServerConnection>any(), Matchers.<Exception>any());
637 
638         conn.consumeInput(handler);
639         Assert.assertNull(conn.getHttpResponse());
640         Assert.assertNull(conn.contentDecoder);
641         Assert.assertEquals(0, conn.getMetrics().getResponseCount());
642         Assert.assertEquals(0, conn.getMetrics().getReceivedBytesCount());
643 
644         Mockito.verify(handler, Mockito.never()).requestReceived(
645             Matchers.<NHttpServerConnection>any());
646         Mockito.verify(handler, Mockito.never()).inputReady(
647             Matchers.<NHttpServerConnection>any(), Matchers.<LengthDelimitedDecoder>any());
648         Mockito.verify(rchannel, Mockito.times(3)).read(Matchers.<ByteBuffer>any());
649         Mockito.verify(handler, Mockito.times(1)).endOfInput(
650             Matchers.<NHttpServerConnection>any());
651         Mockito.verify(handler, Mockito.never()).exception(
652             Matchers.<NHttpServerConnection>any(), Matchers.<Exception>any());
653 
654     }
655 
656     @Test
657     public void testConsumeInputConnectionClosed() throws Exception {
658         conn = new DefaultNHttpServerConnection(session, 1024);
659         final ReadableByteChannelMock rchannel = Mockito.spy(new ReadableByteChannelMock(
660             new String[] {"", ""}, Consts.ASCII));
661         final ByteChannelMock channel = new ByteChannelMock(rchannel, null);
662         Mockito.when(session.channel()).thenReturn(channel);
663         Mockito.when(session.getEventMask()).thenReturn(SelectionKey.OP_READ);
664 
665         conn.close();
666         conn.consumeInput(handler);
667         Mockito.verify(rchannel, Mockito.never()).read(Matchers.<ByteBuffer>any());
668         Mockito.verify(session, Mockito.times(1)).clearEvent(SelectionKey.OP_READ);
669     }
670 
671 }