You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/04/15 16:32:13 UTC

svn commit: r1791520 - in /httpcomponents/httpcore/trunk: httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java

Author: olegk
Date: Sat Apr 15 16:32:13 2017
New Revision: 1791520

URL: http://svn.apache.org/viewvc?rev=1791520&view=rev
Log:
Corrected protocol exception handling by the server HTTP/1.1 stream handler

Modified:
    httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
    httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java?rev=1791520&r1=1791519&r2=1791520&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java Sat Apr 15 16:32:13 2017
@@ -73,6 +73,7 @@ import org.apache.hc.core5.http.HttpStat
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.MalformedChunkCodingException;
 import org.apache.hc.core5.http.Message;
+import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.config.CharCodingConfig;
 import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.impl.BasicHttpTransportMetrics;
@@ -1611,4 +1612,85 @@ public class Http1IntegrationTest extend
         Assert.assertEquals(digest, map.get("digest"));
     }
 
+    @Test
+    public void testProtocolException() throws Exception {
+        server.register("/boom", new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new AsyncServerExchangeHandler() {
+
+                    private final StringAsyncEntityProducer entityProducer = new StringAsyncEntityProducer("Everyting is OK");
+
+                    @Override
+                    public void releaseResources() {
+                        entityProducer.releaseResources();
+                    }
+
+                    @Override
+                    public void handleRequest(
+                            final HttpRequest request,
+                            final EntityDetails entityDetails,
+                            final ResponseChannel responseChannel) throws HttpException, IOException {
+                        final String requestUri = request.getRequestUri();
+                        if (requestUri.endsWith("boom")) {
+                            throw new ProtocolException("Boom!!!");
+                        } else {
+                            responseChannel.sendResponse(new BasicHttpResponse(200), entityProducer);
+                        }
+                    }
+
+                    @Override
+                    public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                        capacityChannel.update(Integer.MAX_VALUE);
+                    }
+
+                    @Override
+                    public int consume(final ByteBuffer src) throws IOException {
+                        return Integer.MAX_VALUE;
+                    }
+
+                    @Override
+                    public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+
+                    }
+
+                    @Override
+                    public int available() {
+                        return entityProducer.available();
+                    }
+
+                    @Override
+                    public void produce(final DataStreamChannel channel) throws IOException {
+                        entityProducer.produce(channel);
+                    }
+
+                    @Override
+                    public void failed(final Exception cause) {
+                        releaseResources();
+                    }
+
+                };
+            }
+
+        });
+
+        final InetSocketAddress serverEndpoint = server.start();
+
+        client.start();
+        final Future<ClientSessionEndpoint> connectFuture = client.connect(
+                "localhost", serverEndpoint.getPort(), TIMEOUT);
+        final ClientSessionEndpoint streamEndpoint = connectFuture.get();
+        final Future<Message<HttpResponse, String>> future = streamEndpoint.execute(
+                new BasicRequestProducer("GET", createRequestURI(serverEndpoint, "/boom")),
+                new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+        final Message<HttpResponse, String> result = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
+        Assert.assertNotNull(result);
+        final HttpResponse response1 = result.getHead();
+        final String entity1 = result.getBody();
+        Assert.assertNotNull(response1);
+        Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, response1.getCode());
+        Assert.assertEquals("Boom!!!", entity1);
+    }
+
 }

Modified: httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java?rev=1791520&r1=1791519&r2=1791520&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java (original)
+++ httpcomponents/httpcore/trunk/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java Sat Apr 15 16:32:13 2017
@@ -258,14 +258,7 @@ class ServerHttp1StreamHandler implement
         }
 
         final EntityDetails requestEntityDetails = requestEndStream ? null : new LazyEntityDetails(request);
-        try {
-            httpProcessor.process(request, requestEntityDetails, context);
-        } catch (final HttpException ex) {
-            final AsyncResponseProducer responseProducer = handleException(ex);
-            exchangeHandler = new ImmediateResponseExchangeHandler(responseProducer);
-        }
-
-        exchangeHandler.handleRequest(request, requestEntityDetails, new ResponseChannel() {
+        final ResponseChannel responseChannel = new ResponseChannel() {
 
             @Override
             public void sendInformation(final HttpResponse response) throws HttpException, IOException {
@@ -285,7 +278,19 @@ class ServerHttp1StreamHandler implement
                 commitPromise();
             }
 
-        });
+        };
+        try {
+            httpProcessor.process(request, requestEntityDetails, context);
+            exchangeHandler.handleRequest(request, requestEntityDetails, responseChannel);
+        } catch (final HttpException ex) {
+            if (!responseCommitted.get()) {
+                final AsyncResponseProducer responseProducer = handleException(ex);
+                exchangeHandler = new ImmediateResponseExchangeHandler(responseProducer);
+                exchangeHandler.handleRequest(request, requestEntityDetails, responseChannel);
+            } else {
+                throw ex;
+            }
+        }
 
     }