HttpService { public void handleRequest( final HttpServerConnection conn, final HttpContext context) throws IOException, HttpException { final AtomicBoolean responseSubmitted = new AtomicBoolean(false); try { final ClassicHttpRequest request = conn.receiveRequestHeader(); if (streamListener != null) { streamListener.onRequestHead(conn, request); } conn.receiveRequestEntity(request); final ProtocolVersion transportVersion = request.getVersion(); context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1); context.setAttribute(HttpCoreContext.SSL_SESSION, conn.getSSLSession()); context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, conn.getEndpointDetails()); context.setAttribute(HttpCoreContext.HTTP_REQUEST, request); this.processor.process(request, request.getEntity(), context); this.requestHandler.handle(request, new HttpServerRequestHandler.ResponseTrigger() { @Override public void sendInformation(final ClassicHttpResponse response) throws HttpException, IOException { if (responseSubmitted.get()) { throw new HttpException("Response already submitted"); } if (response.getCode() >= HttpStatus.SC_SUCCESS) { throw new HttpException("Invalid intermediate response"); } if (streamListener != null) { streamListener.onResponseHead(conn, response); } conn.sendResponseHeader(response); conn.flush(); } @Override public void submitResponse(final ClassicHttpResponse response) throws HttpException, IOException { try { final ProtocolVersion transportVersion = response.getVersion(); if (transportVersion != null && transportVersion.greaterEquals(HttpVersion.HTTP_2)) { throw new UnsupportedHttpVersionException(transportVersion); } ServerSupport.validateResponse(response, response.getEntity()); context.setProtocolVersion(transportVersion != null ? transportVersion : HttpVersion.HTTP_1_1); context.setAttribute(HttpCoreContext.HTTP_RESPONSE, response); processor.process(response, response.getEntity(), context); responseSubmitted.set(true); conn.sendResponseHeader(response); if (streamListener != null) { streamListener.onResponseHead(conn, response); } if (MessageSupport.canResponseHaveBody(request.getMethod(), response)) { conn.sendResponseEntity(response); } EntityUtils.consume(request.getEntity()); final boolean keepAlive = connReuseStrategy.keepAlive(request, response, context); if (streamListener != null) { streamListener.onExchangeComplete(conn, keepAlive); } if (!keepAlive) { conn.close(); } conn.flush(); } finally { response.close(); } } }, context); } catch (final HttpException ex) { if (responseSubmitted.get()) { throw ex; } try (final ClassicHttpResponse errorResponse = new BasicClassicHttpResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR)) { handleException(ex, errorResponse); errorResponse.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE); context.setAttribute(HttpCoreContext.HTTP_RESPONSE, errorResponse); this.processor.process(errorResponse, errorResponse.getEntity(), context); conn.sendResponseHeader(errorResponse); if (streamListener != null) { streamListener.onResponseHead(conn, errorResponse); } conn.sendResponseEntity(errorResponse); conn.close(); } } } HttpService(
            final HttpProcessor processor,
            final HttpRequestMapper<HttpRequestHandler> handlerMapper,
            final ConnectionReuseStrategy connReuseStrategy,
            final HttpResponseFactory<ClassicHttpResponse> responseFactory,
            final Http1StreamListener streamListener);  HttpService(
            final HttpProcessor processor,
            final HttpRequestMapper<HttpRequestHandler> handlerMapper,
            final ConnectionReuseStrategy connReuseStrategy,
            final HttpResponseFactory<ClassicHttpResponse> responseFactory);  HttpService(
            final HttpProcessor processor,
            final HttpServerRequestHandler requestHandler,
            final ConnectionReuseStrategy connReuseStrategy,
            final Http1StreamListener streamListener);  HttpService(
            final HttpProcessor processor, final HttpServerRequestHandler requestHandler); void handleRequest(
            final HttpServerConnection conn,
            final HttpContext context);  }
@Test public void testBasicExecution() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest(Method.GET, "/"); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(connReuseStrategy.keepAlive(request, response, context)).thenReturn(Boolean.FALSE); httpservice.handleRequest(conn, context); Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getCode()); Assert.assertSame(request, context.getRequest()); Assert.assertSame(response, context.getResponse()); Mockito.verify(httprocessor).process(request, request.getEntity(), context); Mockito.verify(httprocessor).process(response, response.getEntity(), context); Mockito.verify(conn).sendResponseHeader(response); Mockito.verify(conn).sendResponseEntity(response); Mockito.verify(conn).flush(); Mockito.verify(conn).close(); Mockito.verify(response).close(); }
@Test public void testExecutionEntityEnclosingRequest() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest(Method.POST, "/"); final InputStream inStream = Mockito.mock(InputStream.class); final InputStreamEntity entity = new InputStreamEntity(inStream, -1, null); request.setEntity(entity); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(connReuseStrategy.keepAlive(ArgumentMatchers.eq(request), ArgumentMatchers.argThat(new ArgumentMatcher<HttpResponse>() { @Override public boolean matches(final HttpResponse errorResponse) { return errorResponse.getCode() == HttpStatus.SC_NOT_IMPLEMENTED; } }), ArgumentMatchers.eq(context))).thenReturn(Boolean.TRUE); httpservice.handleRequest(conn, context); final ArgumentCaptor<ClassicHttpResponse> responseCaptor = ArgumentCaptor.forClass(ClassicHttpResponse.class); Mockito.verify(conn).sendResponseHeader(responseCaptor.capture()); final ClassicHttpResponse response = responseCaptor.getValue(); Assert.assertNotNull(response); Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getCode()); Assert.assertSame(request, context.getRequest()); Mockito.verify(httprocessor).process(request, request.getEntity(), context); Mockito.verify(inStream).close(); Mockito.verify(httprocessor).process(response, response.getEntity(), context); Mockito.verify(conn).sendResponseHeader(response); Mockito.verify(conn).sendResponseEntity(response); Mockito.verify(conn).flush(); Mockito.verify(conn, Mockito.never()).close(); Mockito.verify(response).close(); }
@Test public void testExecutionEntityEnclosingRequestWithExpectContinue() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest(Method.POST, "/"); request.addHeader(HttpHeaders.EXPECT, HeaderElements.CONTINUE); final InputStream inStream = Mockito.mock(InputStream.class); final InputStreamEntity entity = new InputStreamEntity(inStream, -1, null); request.setEntity(entity); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(connReuseStrategy.keepAlive(ArgumentMatchers.eq(request), ArgumentMatchers.argThat(new ArgumentMatcher<HttpResponse>() { @Override public boolean matches(final HttpResponse errorResponse) { return errorResponse.getCode() == HttpStatus.SC_NOT_IMPLEMENTED; } }), ArgumentMatchers.eq(context))).thenReturn(Boolean.TRUE); httpservice.handleRequest(conn, context); final ArgumentCaptor<ClassicHttpResponse> responseCaptor = ArgumentCaptor.forClass(ClassicHttpResponse.class); Mockito.verify(conn, Mockito.times(2)).sendResponseHeader(responseCaptor.capture()); final List<ClassicHttpResponse> responses = responseCaptor.getAllValues(); Assert.assertNotNull(responses); Assert.assertEquals(2, responses.size()); final ClassicHttpResponse ack = responses.get(0); final ClassicHttpResponse response = responses.get(1); Assert.assertEquals(HttpStatus.SC_CONTINUE, ack.getCode()); Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getCode()); Assert.assertSame(request, context.getRequest()); Mockito.verify(httprocessor).process(request, request.getEntity(), context); Mockito.verify(inStream).close(); Mockito.verify(httprocessor).process(response, response.getEntity(), context); Mockito.verify(conn).sendResponseHeader(response); Mockito.verify(conn).sendResponseEntity(response); Mockito.verify(conn, Mockito.times(2)).flush(); Mockito.verify(conn, Mockito.never()).close(); Mockito.verify(response).close(); }
@Test public void testMethodNotSupported() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest("whatever", "/"); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(handlerResolver.resolve(request, context)).thenReturn(requestHandler); Mockito.doThrow(new MethodNotSupportedException("whatever")).when( requestHandler).handle(request, response, context); httpservice.handleRequest(conn, context); final ArgumentCaptor<ClassicHttpResponse> responseCaptor = ArgumentCaptor.forClass(ClassicHttpResponse.class); Mockito.verify(conn).sendResponseHeader(responseCaptor.capture()); final ClassicHttpResponse error = responseCaptor.getValue(); Assert.assertNotNull(error); Assert.assertSame(request, context.getRequest()); Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, error.getCode()); Mockito.verify(httprocessor).process(error, error.getEntity(), context); Mockito.verify(conn).sendResponseHeader(error); Mockito.verify(conn).sendResponseEntity(error); Mockito.verify(conn).close(); }
@Test public void testUnsupportedHttpVersionException() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest("whatever", "/"); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(handlerResolver.resolve(request, context)).thenReturn(requestHandler); Mockito.doThrow(new UnsupportedHttpVersionException()).when( requestHandler).handle(request, response, context); httpservice.handleRequest(conn, context); final ArgumentCaptor<ClassicHttpResponse> responseCaptor = ArgumentCaptor.forClass(ClassicHttpResponse.class); Mockito.verify(conn).sendResponseHeader(responseCaptor.capture()); final ClassicHttpResponse error = responseCaptor.getValue(); Assert.assertNotNull(error); Assert.assertSame(request, context.getRequest()); Assert.assertEquals(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED, error.getCode()); Mockito.verify(httprocessor).process(error, error.getEntity(), context); Mockito.verify(conn).sendResponseHeader(error); Mockito.verify(conn).sendResponseEntity(error); Mockito.verify(conn).close(); }
@Test public void testProtocolException() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest("whatever", "/"); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(handlerResolver.resolve(request, context)).thenReturn(requestHandler); Mockito.doThrow(new ProtocolException("oh, this world is wrong")).when( requestHandler).handle(request, response, context); httpservice.handleRequest(conn, context); final ArgumentCaptor<ClassicHttpResponse> responseCaptor = ArgumentCaptor.forClass(ClassicHttpResponse.class); Mockito.verify(conn).sendResponseHeader(responseCaptor.capture()); final ClassicHttpResponse error = responseCaptor.getValue(); Assert.assertNotNull(error); Assert.assertSame(request, context.getRequest()); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, error.getCode()); Mockito.verify(httprocessor).process(error, error.getEntity(), context); Mockito.verify(conn).sendResponseHeader(error); Mockito.verify(conn).sendResponseEntity(error); Mockito.verify(conn).close(); }
@Test public void testConnectionKeepAlive() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest(Method.GET, "/"); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(handlerResolver.resolve(request, context)).thenReturn(requestHandler); Mockito.when(connReuseStrategy.keepAlive(request, response, context)).thenReturn(Boolean.TRUE); httpservice.handleRequest(conn, context); Assert.assertEquals(HttpStatus.SC_OK, response.getCode()); Assert.assertSame(request, context.getRequest()); Assert.assertSame(response, context.getResponse()); Mockito.verify(httprocessor).process(request, request.getEntity(), context); Mockito.verify(httprocessor).process(response, response.getEntity(), context); Mockito.verify(conn).sendResponseHeader(response); Mockito.verify(conn).sendResponseEntity(response); Mockito.verify(conn).flush(); Mockito.verify(conn, Mockito.never()).close(); Mockito.verify(response).close(); }
@Test public void testNoContentResponse() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest(Method.GET, "/"); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(handlerResolver.resolve(request, context)).thenReturn(new HttpRequestHandler() { @Override public void handle( final ClassicHttpRequest request, final ClassicHttpResponse response, final HttpContext context) throws HttpException, IOException { response.setCode(HttpStatus.SC_NO_CONTENT); } }); Mockito.when(connReuseStrategy.keepAlive(request, response, context)).thenReturn(Boolean.TRUE); httpservice.handleRequest(conn, context); Assert.assertSame(request, context.getRequest()); Mockito.verify(httprocessor).process(response, response.getEntity(), context); Mockito.verify(conn).sendResponseHeader(response); Mockito.verify(conn, Mockito.never()).sendResponseEntity(ArgumentMatchers.<ClassicHttpResponse>any()); Mockito.verify(conn).flush(); Mockito.verify(conn, Mockito.never()).close(); Mockito.verify(response).close(); }
@Test public void testResponseToHead() throws Exception { final HttpCoreContext context = HttpCoreContext.create(); final ClassicHttpRequest request = new BasicClassicHttpRequest(Method.HEAD, "/"); Mockito.when(conn.receiveRequestHeader()).thenReturn(request); Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response); Mockito.when(handlerResolver.resolve(request, context)).thenReturn(requestHandler); Mockito.when(connReuseStrategy.keepAlive(request, response, context)).thenReturn(Boolean.TRUE); httpservice.handleRequest(conn, context); Assert.assertSame(request, context.getRequest()); Mockito.verify(httprocessor).process(response, response.getEntity(), context); Mockito.verify(requestHandler).handle(request, response, context); Mockito.verify(conn).sendResponseHeader(response); Mockito.verify(conn, Mockito.never()).sendResponseEntity(ArgumentMatchers.<ClassicHttpResponse>any()); Mockito.verify(conn).flush(); Mockito.verify(conn, Mockito.never()).close(); Mockito.verify(response).close(); }