hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject [2/3] httpcomponents-core git commit: Improvements and bug fixes in the reverse proxy examples
Date Mon, 03 Jul 2017 12:52:18 GMT
Improvements and bug fixes in the reverse proxy examples


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/b4756bb4
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/b4756bb4
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/b4756bb4

Branch: refs/heads/master
Commit: b4756bb469edeafba32a49024a7d6283f374d311
Parents: 1d21c8e
Author: Oleg Kalnichevski <olegk@apache.org>
Authored: Sun Jul 2 11:26:30 2017 +0200
Committer: Oleg Kalnichevski <olegk@apache.org>
Committed: Mon Jul 3 14:17:43 2017 +0200

----------------------------------------------------------------------
 .../testing/classic/ClassicTestServer.java      |   6 ++
 .../http/examples/AsyncReverseProxyExample.java | 108 ++++++++++++-------
 .../http/examples/ClassicFileServerExample.java |   6 ++
 .../examples/ClassicReverseProxyExample.java    |  62 ++++++-----
 .../apache/hc/core5/http/ExceptionListener.java |  11 ++
 .../core5/http/impl/bootstrap/HttpServer.java   |   2 +-
 .../hc/core5/http/impl/bootstrap/Worker.java    |   2 +-
 7 files changed, 132 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/b4756bb4/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
----------------------------------------------------------------------
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
index 02cb505..97067f8 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/classic/ClassicTestServer.java
@@ -38,6 +38,7 @@ import javax.net.ssl.SSLSocket;
 
 import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.ExceptionListener;
+import org.apache.hc.core5.http.HttpConnection;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.config.SocketConfig;
@@ -151,6 +152,11 @@ public class ClassicTestServer {
 
         @Override
         public void onError(final Exception ex) {
+            this.log.error(ex.getMessage(), ex);
+        }
+
+        @Override
+        public void onError(final HttpConnection conn, final Exception ex) {
             if (ex instanceof ConnectionClosedException) {
                 this.log.debug(ex.getMessage());
             } else if (ex instanceof SocketException) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/b4756bb4/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
b/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
index 8331247..e66efcb 100644
--- a/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
+++ b/httpcore5/src/examples/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
@@ -40,11 +40,11 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
@@ -58,7 +58,6 @@ import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.impl.BasicEntityDetails;
 import org.apache.hc.core5.http.impl.Http1StreamListener;
-import org.apache.hc.core5.http.impl.LazyEntityDetails;
 import org.apache.hc.core5.http.impl.bootstrap.AsyncRequesterBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.AsyncServerBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
@@ -109,14 +108,17 @@ public class AsyncReverseProxyExample {
 
                     @Override
                     public void onLease(final HttpHost route, final ConnPoolStats<HttpHost>
connPoolStats) {
+                        StringBuilder buf = new StringBuilder();
+                        buf.append("[proxy->origin] connection leased ").append(route);
+                        System.out.println(buf.toString());
                     }
 
                     @Override
                     public void onRelease(final HttpHost route, final ConnPoolStats<HttpHost>
connPoolStats) {
                         StringBuilder buf = new StringBuilder();
-                        buf.append(route).append(" ");
+                        buf.append("[proxy->origin] connection released ").append(route);
                         PoolStats totals = connPoolStats.getTotalStats();
-                        buf.append(" total kept alive: ").append(totals.getAvailable()).append(";
");
+                        buf.append("; total kept alive: ").append(totals.getAvailable()).append(";
");
                         buf.append("total allocated: ").append(totals.getLeased() + totals.getAvailable());
                         buf.append(" of ").append(totals.getMax());
                         System.out.println(buf.toString());
@@ -126,11 +128,11 @@ public class AsyncReverseProxyExample {
                 .setStreamListener(new Http1StreamListener() {
 
                     @Override
-                    public void onRequestHead(final HttpConnection connection, HttpRequest
request) {
+                    public void onRequestHead(final HttpConnection connection, final HttpRequest
request) {
                     }
 
                     @Override
-                    public void onResponseHead(final HttpConnection connection, HttpResponse
response) {
+                    public void onResponseHead(final HttpConnection connection, final HttpResponse
response) {
                     }
 
                     @Override
@@ -149,11 +151,11 @@ public class AsyncReverseProxyExample {
                 .setStreamListener(new Http1StreamListener() {
 
                     @Override
-                    public void onRequestHead(final HttpConnection connection, HttpRequest
request) {
+                    public void onRequestHead(final HttpConnection connection, final HttpRequest
request) {
                     }
 
                     @Override
-                    public void onResponseHead(final HttpConnection connection, HttpResponse
response) {
+                    public void onResponseHead(final HttpConnection connection, final HttpResponse
response) {
                     }
 
                     @Override
@@ -220,17 +222,22 @@ public class AsyncReverseProxyExample {
 
         final String id;
 
-        ProxyBuffer inBuf;
-        ProxyBuffer outBuf;
         HttpRequest request;
-        HttpResponse response;
+        EntityDetails requestEntityDetails;
+        DataStreamChannel requestDataChannel;
+        CapacityChannel requestCapacityChannel;
+        ProxyBuffer inBuf;
         boolean inputEnd;
-        boolean outputEnd;
+
+        HttpResponse response;
+        EntityDetails responseEntityDetails;
         ResponseChannel responseMessageChannel;
-        CapacityChannel requestCapacityChannel;
-        CapacityChannel responseCapacityChannel;
-        DataStreamChannel requestDataChannel;
         DataStreamChannel responseDataChannel;
+        CapacityChannel responseCapacityChannel;
+        ProxyBuffer outBuf;
+        boolean outputEnd;
+
+        AsyncClientEndpoint clientEndpoint;
 
         ProxyExchangeState() {
             this.id = String.format("%08X", COUNT.getAndIncrement());
@@ -244,14 +251,12 @@ public class AsyncReverseProxyExample {
 
         private final HttpHost targetHost;
         private final HttpAsyncRequester requester;
-        private final AtomicBoolean consistent;
         private final ProxyExchangeState exchangeState;
 
         IncomingExchangeHandler(final HttpHost targetHost, final HttpAsyncRequester requester)
{
             super();
             this.targetHost = targetHost;
             this.requester = requester;
-            this.consistent = new AtomicBoolean(true);
             this.exchangeState = new ProxyExchangeState();
         }
 
@@ -265,6 +270,7 @@ public class AsyncReverseProxyExample {
                 System.out.println("[client->proxy] " + exchangeState.id + " " +
                         incomingRequest.getMethod() + " " + incomingRequest.getRequestUri());
                 exchangeState.request = incomingRequest;
+                exchangeState.requestEntityDetails = entityDetails;
                 exchangeState.inputEnd = entityDetails == null;
                 exchangeState.responseMessageChannel = responseChannel;
 
@@ -283,7 +289,10 @@ public class AsyncReverseProxyExample {
                 @Override
                 public void completed(final AsyncClientEndpoint clientEndpoint) {
                     System.out.println("[proxy->origin] " + exchangeState.id + " connection
leased");
-                    clientEndpoint.execute(new OutgoingExchangeHandler(clientEndpoint, exchangeState),
null);
+                    synchronized (exchangeState) {
+                        exchangeState.clientEndpoint = clientEndpoint;
+                    }
+                    clientEndpoint.execute(new OutgoingExchangeHandler(targetHost, clientEndpoint,
exchangeState), null);
                 }
 
                 @Override
@@ -291,8 +300,9 @@ public class AsyncReverseProxyExample {
                     HttpResponse outgoingResponse = new BasicHttpResponse(HttpStatus.SC_SERVICE_UNAVAILABLE);
                     outgoingResponse.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
                     exchangeState.response = outgoingResponse;
-
                     ByteBuffer msg = StandardCharsets.US_ASCII.encode(CharBuffer.wrap(cause.getMessage()));
+                    EntityDetails entityDetails = new BasicEntityDetails(msg.remaining(),
ContentType.TEXT_PLAIN);
+                    exchangeState.responseEntityDetails = entityDetails;
                     exchangeState.outBuf = new ProxyBuffer(1024);
                     exchangeState.outBuf.put(msg);
                     exchangeState.outputEnd = true;
@@ -300,7 +310,6 @@ public class AsyncReverseProxyExample {
                     System.out.println("[client<-proxy] " + exchangeState.id + " status
" + outgoingResponse.getCode());
 
                     try {
-                        EntityDetails entityDetails = new BasicEntityDetails(msg.remaining(),
ContentType.TEXT_PLAIN);
                         responseChannel.sendResponse(outgoingResponse, entityDetails);
                     } catch (HttpException | IOException ignore) {
                     }
@@ -410,10 +419,15 @@ public class AsyncReverseProxyExample {
 
         @Override
         public void failed(final Exception cause) {
-            System.out.println("[client<-proxy] " + exchangeState.id + " error: " + cause.getMessage());
-            cause.printStackTrace(System.out);
-            consistent.set(false);
-            releaseResources();
+            System.out.println("[client<-proxy] " + exchangeState.id + " " + cause.getMessage());
+            if (!(cause instanceof ConnectionClosedException)) {
+                cause.printStackTrace(System.out);
+            }
+            synchronized (exchangeState) {
+                if (exchangeState.clientEndpoint != null) {
+                    exchangeState.clientEndpoint.releaseAndDiscard();
+                }
+            }
         }
 
         @Override
@@ -428,6 +442,7 @@ public class AsyncReverseProxyExample {
     }
 
     private final static Set<String> HOP_BY_HOP = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+            HttpHeaders.HOST.toLowerCase(Locale.ROOT),
             HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ROOT),
             HttpHeaders.TRANSFER_ENCODING.toLowerCase(Locale.ROOT),
             HttpHeaders.CONNECTION.toLowerCase(Locale.ROOT),
@@ -439,10 +454,15 @@ public class AsyncReverseProxyExample {
 
     private static class OutgoingExchangeHandler implements AsyncClientExchangeHandler {
 
+        private final HttpHost targetHost;
         private final AsyncClientEndpoint clientEndpoint;
         private final ProxyExchangeState exchangeState;
 
-        OutgoingExchangeHandler(final AsyncClientEndpoint clientEndpoint, final ProxyExchangeState
exchangeState) {
+        OutgoingExchangeHandler(
+                final HttpHost targetHost,
+                final AsyncClientEndpoint clientEndpoint,
+                final ProxyExchangeState exchangeState) {
+            this.targetHost = targetHost;
             this.clientEndpoint = clientEndpoint;
             this.exchangeState = exchangeState;
         }
@@ -452,7 +472,11 @@ public class AsyncReverseProxyExample {
                 final RequestChannel channel) throws HttpException, IOException {
             synchronized (exchangeState) {
                 HttpRequest incomingRequest = exchangeState.request;
-                HttpRequest outgoingRequest = new BasicHttpRequest(incomingRequest.getMethod(),
incomingRequest.getPath());
+                EntityDetails entityDetails = exchangeState.requestEntityDetails;
+                HttpRequest outgoingRequest = new BasicHttpRequest(
+                        incomingRequest.getMethod(),
+                        targetHost,
+                        incomingRequest.getPath());
                 for (Iterator<Header> it = incomingRequest.headerIterator(); it.hasNext();
) {
                     Header header = it.next();
                     if (!HOP_BY_HOP.contains(header.getName().toLowerCase(Locale.ROOT)))
{
@@ -463,9 +487,7 @@ public class AsyncReverseProxyExample {
                 System.out.println("[proxy->origin] " + exchangeState.id + " " +
                         outgoingRequest.getMethod() + " " + outgoingRequest.getRequestUri());
 
-                channel.sendRequest(
-                        outgoingRequest,
-                        !exchangeState.inputEnd ? new LazyEntityDetails(outgoingRequest)
: null);
+                channel.sendRequest(outgoingRequest, entityDetails);
             }
         }
 
@@ -516,6 +538,9 @@ public class AsyncReverseProxyExample {
                 final EntityDetails entityDetails) throws HttpException, IOException {
             synchronized (exchangeState) {
                 System.out.println("[proxy<-origin] " + exchangeState.id + " status "
+ incomingResponse.getCode());
+                if (entityDetails == null) {
+                    System.out.println("[proxy<-origin] " + exchangeState.id + " end of
input");
+                }
 
                 HttpResponse outgoingResponse = new BasicHttpResponse(incomingResponse.getCode());
                 for (Iterator<Header> it = incomingResponse.headerIterator(); it.hasNext();
) {
@@ -526,14 +551,17 @@ public class AsyncReverseProxyExample {
                 }
 
                 exchangeState.response = outgoingResponse;
+                exchangeState.responseEntityDetails = entityDetails;
                 exchangeState.outputEnd = entityDetails == null;
 
                 ResponseChannel responseChannel = exchangeState.responseMessageChannel;
-                responseChannel.sendResponse(
-                        outgoingResponse,
-                        !exchangeState.outputEnd ?  new LazyEntityDetails(outgoingResponse)
: null);
+                responseChannel.sendResponse(outgoingResponse, entityDetails);
 
                 System.out.println("[client<-proxy] " + exchangeState.id + " status "
+ outgoingResponse.getCode());
+                if (entityDetails == null) {
+                    System.out.println("[client<-proxy] " + exchangeState.id + " end of
output");
+                    clientEndpoint.releaseAndReuse();
+                }
             }
         }
 
@@ -588,19 +616,22 @@ public class AsyncReverseProxyExample {
                 if (dataChannel != null && (exchangeState.outBuf == null || !exchangeState.outBuf.hasData()))
{
                     System.out.println("[client<-proxy] " + exchangeState.id + " end of
output");
                     dataChannel.endStream();
+                    clientEndpoint.releaseAndReuse();
                 }
             }
         }
 
         @Override
         public void cancel() {
-            releaseResources();
+            clientEndpoint.releaseAndDiscard();
         }
 
         @Override
         public void failed(final Exception cause) {
-            System.out.println("[client<-proxy] " + exchangeState.id + " error: " + cause.getMessage());
-            cause.printStackTrace(System.out);
+            System.out.println("[client<-proxy] " + exchangeState.id + " " + cause.getMessage());
+            if (!(cause instanceof ConnectionClosedException)) {
+                cause.printStackTrace(System.out);
+            }
             synchronized (exchangeState) {
                 if (exchangeState.response == null) {
                     int status = cause instanceof IOException ? HttpStatus.SC_SERVICE_UNAVAILABLE
: HttpStatus.SC_INTERNAL_SERVER_ERROR;
@@ -609,6 +640,7 @@ public class AsyncReverseProxyExample {
                     exchangeState.response = outgoingResponse;
 
                     ByteBuffer msg = StandardCharsets.US_ASCII.encode(CharBuffer.wrap(cause.getMessage()));
+                    int contentLen = msg.remaining();
                     exchangeState.outBuf = new ProxyBuffer(1024);
                     exchangeState.outBuf.put(msg);
                     exchangeState.outputEnd = true;
@@ -616,14 +648,14 @@ public class AsyncReverseProxyExample {
                     System.out.println("[client<-proxy] " + exchangeState.id + " status
" + outgoingResponse.getCode());
 
                     try {
-                        EntityDetails entityDetails = new BasicEntityDetails(msg.remaining(),
ContentType.TEXT_PLAIN);
+                        EntityDetails entityDetails = new BasicEntityDetails(contentLen,
ContentType.TEXT_PLAIN);
                         exchangeState.responseMessageChannel.sendResponse(outgoingResponse,
entityDetails);
                     } catch (HttpException | IOException ignore) {
                     }
                 } else {
                     exchangeState.outputEnd = true;
                 }
-                releaseResources();
+                clientEndpoint.releaseAndDiscard();
             }
         }
 
@@ -632,8 +664,8 @@ public class AsyncReverseProxyExample {
             synchronized (exchangeState) {
                 exchangeState.requestDataChannel = null;
                 exchangeState.responseCapacityChannel = null;
+                clientEndpoint.releaseAndDiscard();
             }
-            clientEndpoint.releaseAndReuse();
         }
 
     }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/b4756bb4/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
index 4706bfc..0202338 100644
--- a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
+++ b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
@@ -44,6 +44,7 @@ import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.EndpointDetails;
 import org.apache.hc.core5.http.ExceptionListener;
+import org.apache.hc.core5.http.HttpConnection;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpStatus;
@@ -104,6 +105,11 @@ public class ClassicFileServerExample {
 
                     @Override
                     public void onError(final Exception ex) {
+                        ex.printStackTrace();
+                    }
+
+                    @Override
+                    public void onError(final HttpConnection conn, final Exception ex) {
                         if (ex instanceof SocketTimeoutException) {
                             System.err.println("Connection timed out");
                         } else if (ex instanceof ConnectionClosedException) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/b4756bb4/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
index 961c2d9..b5f2c34 100644
--- a/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
+++ b/httpcore5/src/examples/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
@@ -28,6 +28,7 @@
 package org.apache.hc.core5.http.examples;
 
 import java.io.IOException;
+import java.net.SocketException;
 import java.net.SocketTimeoutException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -54,8 +55,6 @@ import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
-import org.apache.hc.core5.http.message.RequestLine;
-import org.apache.hc.core5.http.message.StatusLine;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.io.ShutdownType;
@@ -88,22 +87,19 @@ public class ClassicReverseProxyExample {
 
                     @Override
                     public void onRequestHead(final HttpConnection connection, final HttpRequest
request) {
-                        System.out.println(connection + " >> " + new RequestLine(request));
-
+                        System.out.println("[proxy->origin] " + Thread.currentThread()
 + " " +
+                                request.getMethod() + " " + request.getRequestUri());
                     }
 
                     @Override
                     public void onResponseHead(final HttpConnection connection, final HttpResponse
response) {
-                        System.out.println(connection + " << " + new StatusLine(response));
+                        System.out.println("[proxy<-origin] " + Thread.currentThread()
 + " status " + response.getCode());
                     }
 
                     @Override
                     public void onExchangeComplete(final HttpConnection connection, final
boolean keepAlive) {
-                        if (keepAlive) {
-                            System.out.println(connection + " >> can be kept alive");
-                        } else {
-                            System.out.println(connection + " >> cannot be kept alive");
-                        }
+                        System.out.println("[proxy<-origin] " + Thread.currentThread()
+ " exchange completed; " +
+                                "connection " + (keepAlive ? "kept alive" : "cannot be kept
alive"));
                     }
 
                 })
@@ -111,14 +107,17 @@ public class ClassicReverseProxyExample {
 
                     @Override
                     public void onLease(final HttpHost route, final ConnPoolStats<HttpHost>
connPoolStats) {
+                        StringBuilder buf = new StringBuilder();
+                        buf.append("[proxy->origin] " + Thread.currentThread()  + " connection
leased ").append(route);
+                        System.out.println(buf.toString());
                     }
 
                     @Override
                     public void onRelease(final HttpHost route, final ConnPoolStats<HttpHost>
connPoolStats) {
                         StringBuilder buf = new StringBuilder();
-                        buf.append(route).append(" ");
+                        buf.append("[proxy->origin] " + Thread.currentThread()  + " connection
released ").append(route);
                         PoolStats totals = connPoolStats.getTotalStats();
-                        buf.append(" total kept alive: ").append(totals.getAvailable()).append(";
");
+                        buf.append("; total kept alive: ").append(totals.getAvailable()).append(";
");
                         buf.append("total allocated: ").append(totals.getLeased() + totals.getAvailable());
                         buf.append(" of ").append(totals.getMax());
                         System.out.println(buf.toString());
@@ -133,22 +132,19 @@ public class ClassicReverseProxyExample {
 
                     @Override
                     public void onRequestHead(final HttpConnection connection, final HttpRequest
request) {
-                        System.out.println(connection + " >> " + new RequestLine(request));
-
+                        System.out.println("[client->proxy] " + Thread.currentThread()
+ " " +
+                                request.getMethod() + " " + request.getRequestUri());
                     }
 
                     @Override
                     public void onResponseHead(final HttpConnection connection, final HttpResponse
response) {
-                        System.out.println(connection + " << " + new StatusLine(response));
+                        System.out.println("[client<-proxy] " + Thread.currentThread()
+ " status " + response.getCode());
                     }
 
                     @Override
                     public void onExchangeComplete(final HttpConnection connection, final
boolean keepAlive) {
-                        if (keepAlive) {
-                            System.out.println(connection + " >> can be kept alive");
-                        } else {
-                            System.out.println(connection + " >> cannot be kept alive");
-                        }
+                        System.out.println("[client<-proxy] " + Thread.currentThread()
+ " exchange completed; " +
+                                "connection " + (keepAlive ? "kept alive" : "cannot be kept
alive"));
                     }
 
                 })
@@ -156,12 +152,23 @@ public class ClassicReverseProxyExample {
 
                     @Override
                     public void onError(final Exception ex) {
+                        if (ex instanceof SocketException) {
+                            System.out.println("[client->proxy] " + Thread.currentThread()
+ " " + ex.getMessage());
+                        } else {
+                            System.out.println("[client->proxy] " + Thread.currentThread()
 + " " + ex.getMessage());
+                            ex.printStackTrace(System.out);
+                        }
+                    }
+
+                    @Override
+                    public void onError(final HttpConnection connection, final Exception
ex) {
                         if (ex instanceof SocketTimeoutException) {
-                            System.err.println("Connection timed out");
-                        } else if (ex instanceof ConnectionClosedException) {
-                            System.err.println(ex.getMessage());
+                            System.out.println("[client->proxy] " + Thread.currentThread()
+ " time out");
+                        } else if (ex instanceof SocketException || ex instanceof ConnectionClosedException)
{
+                            System.out.println("[client->proxy] " + Thread.currentThread()
+ " " + ex.getMessage());
                         } else {
-                            ex.printStackTrace();
+                            System.out.println("[client->proxy] " + Thread.currentThread()
+ " " + ex.getMessage());
+                            ex.printStackTrace(System.out);
                         }
                     }
 
@@ -183,6 +190,7 @@ public class ClassicReverseProxyExample {
     }
 
     private final static Set<String> HOP_BY_HOP = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+            HttpHeaders.HOST.toLowerCase(Locale.ROOT),
             HttpHeaders.CONTENT_LENGTH.toLowerCase(Locale.ROOT),
             HttpHeaders.TRANSFER_ENCODING.toLowerCase(Locale.ROOT),
             HttpHeaders.CONNECTION.toLowerCase(Locale.ROOT),
@@ -213,13 +221,17 @@ public class ClassicReverseProxyExample {
                 final HttpContext serverContext) throws HttpException, IOException {
 
             final HttpCoreContext clientContext = HttpCoreContext.create();
-            final ClassicHttpRequest outgoingRequest = new BasicClassicHttpRequest(incomingRequest.getMethod(),
incomingRequest.getPath());
+            final ClassicHttpRequest outgoingRequest = new BasicClassicHttpRequest(
+                    incomingRequest.getMethod(),
+                    targetHost,
+                    incomingRequest.getPath());
             for (Iterator<Header> it = incomingRequest.headerIterator(); it.hasNext();
) {
                 Header header = it.next();
                 if (!HOP_BY_HOP.contains(header.getName().toLowerCase(Locale.ROOT))) {
                     outgoingRequest.addHeader(header);
                 }
             }
+            outgoingRequest.setEntity(incomingRequest.getEntity());
             final ClassicHttpResponse incomingResponse = requester.execute(
                     targetHost, outgoingRequest, Timeout.ofMinutes(1), clientContext);
             outgoingResponse.setCode(incomingResponse.getCode());

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/b4756bb4/httpcore5/src/main/java/org/apache/hc/core5/http/ExceptionListener.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/ExceptionListener.java b/httpcore5/src/main/java/org/apache/hc/core5/http/ExceptionListener.java
index d204a5f..cdb5561 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/ExceptionListener.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/ExceptionListener.java
@@ -41,6 +41,10 @@ public interface ExceptionListener {
         public void onError(final Exception ex) {
         }
 
+        @Override
+        public void onError(final HttpConnection connection, final Exception ex) {
+        }
+
     };
 
     ExceptionListener STD_ERR = new ExceptionListener() {
@@ -50,8 +54,15 @@ public interface ExceptionListener {
             ex.printStackTrace();
         }
 
+        @Override
+        public void onError(final HttpConnection connection, final Exception ex) {
+            ex.printStackTrace();
+        }
+
     };
 
     void onError(Exception ex);
 
+    void onError(HttpConnection connection, Exception ex);
+
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/b4756bb4/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
index 68ca53b..45ae733 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
@@ -106,7 +106,7 @@ public class HttpServer implements GracefullyCloseable {
         this.workerExecutorService = new WorkerPoolExecutor(
                 0, Integer.MAX_VALUE, 1L, TimeUnit.SECONDS,
                 new SynchronousQueue<Runnable>(),
-                new DefaultThreadFactory("HTTP-worker", this.workerThreads, false));
+                new DefaultThreadFactory("HTTP-worker", this.workerThreads, true));
         this.status = new AtomicReference<>(Status.READY);
     }
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/b4756bb4/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/Worker.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/Worker.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/Worker.java
index e721aa3..9825aa9 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/Worker.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/Worker.java
@@ -67,7 +67,7 @@ class Worker implements Runnable {
             }
             this.conn.close();
         } catch (final Exception ex) {
-            this.exceptionListener.onError(ex);
+            this.exceptionListener.onError(this.conn, ex);
         } finally {
             this.conn.shutdown(ShutdownType.IMMEDIATE);
         }


Mime
View raw message