From d0f03723ccc8dccb1282e1fbb649c16e4afcc9be Mon Sep 17 00:00:00 2001 From: Slava Fomin Date: Mon, 19 Jun 2017 19:00:45 +0300 Subject: [PATCH 1/5] Implements custom proxy to server error handler --- .../proxy/HttpProxyServerBootstrap.java | 16 ++++++++++++++ .../proxy/ProxyToServerExHandler.java | 10 +++++++++ .../proxy/impl/DefaultHttpProxyServer.java | 21 ++++++++++++++++++- .../proxy/impl/ProxyToServerConnection.java | 8 ++++++- 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/littleshoot/proxy/ProxyToServerExHandler.java diff --git a/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java b/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java index 118205a5e..cc31a4b6c 100644 --- a/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java +++ b/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java @@ -181,6 +181,22 @@ HttpProxyServerBootstrap withChainProxyManager( HttpProxyServerBootstrap withManInTheMiddle( MitmManagerFactory mitmManager); + + /** + *

+ * Specify an {@link ProxyToServerExHandler} to handle proxy to server errors + *

+ * + *

+ * Default = null + *

+ * + * @param proxyToServerExHandler + * @return + */ + HttpProxyServerBootstrap withProxyToServerExHandler( + ProxyToServerExHandler proxyToServerExHandler); + /** *

* Specify a {@link HttpFiltersSource} to use for filtering requests and/or diff --git a/src/main/java/org/littleshoot/proxy/ProxyToServerExHandler.java b/src/main/java/org/littleshoot/proxy/ProxyToServerExHandler.java new file mode 100644 index 000000000..270036a18 --- /dev/null +++ b/src/main/java/org/littleshoot/proxy/ProxyToServerExHandler.java @@ -0,0 +1,10 @@ +package org.littleshoot.proxy; + +public interface ProxyToServerExHandler { + + /** + * Handles proxy to server error + * @param cause error cause + */ + void handle(Throwable cause); +} diff --git a/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java b/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java index 64bb78cbe..784036969 100644 --- a/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java +++ b/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java @@ -31,6 +31,7 @@ import org.littleshoot.proxy.MitmManager; import org.littleshoot.proxy.MitmManagerFactory; import org.littleshoot.proxy.ProxyAuthenticator; +import org.littleshoot.proxy.ProxyToServerExHandler; import org.littleshoot.proxy.SslEngineSource; import org.littleshoot.proxy.TransportProtocol; import org.littleshoot.proxy.UnknownTransportProtocolException; @@ -110,6 +111,7 @@ public class DefaultHttpProxyServer implements HttpProxyServer { private final ProxyAuthenticator proxyAuthenticator; private final ChainedProxyManager chainProxyManager; private final MitmManagerFactory mitmManagerFactory; + private final ProxyToServerExHandler proxyToServerExHandler; private final HttpFiltersSource filtersSource; private final FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer; private final boolean transparent; @@ -243,6 +245,7 @@ private DefaultHttpProxyServer(ServerGroup serverGroup, ProxyAuthenticator proxyAuthenticator, ChainedProxyManager chainProxyManager, MitmManagerFactory mitmManagerFactory, + ProxyToServerExHandler proxyToServerExHandler, HttpFiltersSource filtersSource, FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer, boolean transparent, @@ -266,6 +269,7 @@ private DefaultHttpProxyServer(ServerGroup serverGroup, this.proxyAuthenticator = proxyAuthenticator; this.chainProxyManager = chainProxyManager; this.mitmManagerFactory = mitmManagerFactory; + this.proxyToServerExHandler = proxyToServerExHandler; this.filtersSource = filtersSource; this.unrecoverableFailureHttpResponseComposer = unrecoverableFailureHttpResponseComposer; this.transparent = transparent; @@ -401,6 +405,7 @@ public HttpProxyServerBootstrap clone() { proxyAuthenticator, chainProxyManager, mitmManagerFactory, + proxyToServerExHandler, filtersSource, unrecoverableFailureHttpResponseComposer, transparent, @@ -579,6 +584,10 @@ protected MitmManager getMitmManager(Channel channel) { return null; } + protected ProxyToServerExHandler getProxyToServerExHandler() { + return proxyToServerExHandler; + } + protected SslEngineSource getSslEngineSource() { return sslEngineSource; } @@ -621,6 +630,7 @@ private static class DefaultHttpProxyServerBootstrap implements HttpProxyServerB private ProxyAuthenticator proxyAuthenticator = null; private ChainedProxyManager chainProxyManager = null; private MitmManagerFactory mitmManagerFactory = null; + private ProxyToServerExHandler proxyToServerExHandler = null; private HttpFiltersSource filtersSource = new HttpFiltersSourceAdapter(); private FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer = new BadGatewayFailureHttpResponseComposer(); private boolean transparent = false; @@ -652,6 +662,7 @@ private DefaultHttpProxyServerBootstrap( ProxyAuthenticator proxyAuthenticator, ChainedProxyManager chainProxyManager, MitmManagerFactory mitmManagerFactory, + ProxyToServerExHandler proxyToServerExHandler, HttpFiltersSource filtersSource, FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer, boolean transparent, int idleConnectionTimeout, @@ -674,6 +685,7 @@ private DefaultHttpProxyServerBootstrap( this.proxyAuthenticator = proxyAuthenticator; this.chainProxyManager = chainProxyManager; this.mitmManagerFactory = mitmManagerFactory; + this.proxyToServerExHandler = proxyToServerExHandler; this.filtersSource = filtersSource; this.unrecoverableFailureHttpResponseComposer = unrecoverableFailureHttpResponseComposer; this.transparent = transparent; @@ -807,6 +819,13 @@ public HttpProxyServerBootstrap withManInTheMiddle( return this; } + @Override + public HttpProxyServerBootstrap withProxyToServerExHandler( + ProxyToServerExHandler proxyToServerExHandler) { + this.proxyToServerExHandler = proxyToServerExHandler; + return this; + } + @Override public HttpProxyServerBootstrap withFiltersSource( HttpFiltersSource filtersSource) { @@ -922,7 +941,7 @@ private DefaultHttpProxyServer build() { return new DefaultHttpProxyServer(serverGroup, transportProtocol, determineListenAddress(), sslEngineSource, authenticateSslClients, - proxyAuthenticator, chainProxyManager, mitmManagerFactory, + proxyAuthenticator, chainProxyManager, mitmManagerFactory, proxyToServerExHandler, filtersSource, unrecoverableFailureHttpResponseComposer, transparent, idleConnectionTimeout, activityTrackers, connectTimeout, serverResolver, readThrottleBytesPerSecond, writeThrottleBytesPerSecond, diff --git a/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java b/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java index bb5e09d5e..f7d158d68 100644 --- a/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java +++ b/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java @@ -39,6 +39,7 @@ import org.littleshoot.proxy.FullFlowContext; import org.littleshoot.proxy.HttpFilters; import org.littleshoot.proxy.MitmManager; +import org.littleshoot.proxy.ProxyToServerExHandler; import org.littleshoot.proxy.TransportProtocol; import org.littleshoot.proxy.UnknownTransportProtocolException; @@ -439,7 +440,12 @@ protected void exceptionCaught(Throwable cause) { LOG.info("An executor rejected a read or write operation on the ProxyToServerConnection (this is normal if the proxy is shutting down). Message: " + cause.getMessage()); LOG.debug("A RejectedExecutionException occurred on ProxyToServerConnection", cause); } else { - LOG.error("Caught an exception on ProxyToServerConnection", cause); + ProxyToServerExHandler exHandler = proxyServer.getProxyToServerExHandler(); + if (exHandler != null) { + exHandler.handle(cause); + } else { + LOG.error("Caught an exception on ProxyToServerConnection", cause); + } } } finally { if (!is(DISCONNECTED)) { From 4797d6192d68bcb9930cfebf10e26fdab98af6f8 Mon Sep 17 00:00:00 2001 From: Slava Fomin Date: Tue, 20 Jun 2017 15:09:42 +0300 Subject: [PATCH 2/5] Adds unit test --- .../CustomProxyToServerExHandlerTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java diff --git a/src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java b/src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java new file mode 100644 index 000000000..a7432a1a3 --- /dev/null +++ b/src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java @@ -0,0 +1,44 @@ +package org.littleshoot.proxy; + +import org.junit.Assert; +import org.junit.Test; +import org.littleshoot.proxy.extras.SelfSignedMitmManagerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class CustomProxyToServerExHandlerTest extends MitmWithBadServerAuthenticationTCPChainedProxyTest { + + private List customExHandlerEntered = new ArrayList<>(); + + @Override + protected void setUp() { + this.upstreamProxy = upstreamProxy().start(); + + this.proxyServer = bootstrapProxy() + .withPort(0) + .withChainProxyManager(chainedProxyManager()) + .plusActivityTracker(DOWNSTREAM_TRACKER) + .withManInTheMiddle(new SelfSignedMitmManagerFactory()) + .withProxyToServerExHandler(new ProxyToServerExHandler() { + @Override + public void handle(Throwable cause) { + customExHandlerEntered.add(cause); + } + }) + .start(); + } + + @Override + protected void tearDown() throws Exception { + this.upstreamProxy.abort(); + } + + @Test + public void testCustomExHandler() throws Exception { + super.testSimpleGetRequestOverHTTPS(); + Assert.assertFalse("Custom ex handler was not called", customExHandlerEntered.isEmpty()); + Assert.assertEquals("Incorrect exception was passed to custom ex handles", + customExHandlerEntered.get(0).getMessage(), "javax.net.ssl.SSLHandshakeException: General SSLEngine problem"); + } +} From a1897f76f984c852be5686719cdd5ec8cfc1427a Mon Sep 17 00:00:00 2001 From: Slava Fomin Date: Tue, 20 Jun 2017 19:59:12 +0300 Subject: [PATCH 3/5] Adds client to proxy exception handler --- ...erExHandler.java => ExceptionHandler.java} | 2 +- .../proxy/HttpProxyServerBootstrap.java | 18 ++++++- .../proxy/impl/ClientToProxyConnection.java | 9 +++- .../proxy/impl/DefaultHttpProxyServer.java | 35 ++++++++++--- .../proxy/impl/ProxyToServerConnection.java | 5 +- .../CustomClientToProxyExHandlerTest.java | 51 +++++++++++++++++++ .../CustomProxyToServerExHandlerTest.java | 6 +-- 7 files changed, 109 insertions(+), 17 deletions(-) rename src/main/java/org/littleshoot/proxy/{ProxyToServerExHandler.java => ExceptionHandler.java} (77%) create mode 100644 src/test/java/org/littleshoot/proxy/CustomClientToProxyExHandlerTest.java diff --git a/src/main/java/org/littleshoot/proxy/ProxyToServerExHandler.java b/src/main/java/org/littleshoot/proxy/ExceptionHandler.java similarity index 77% rename from src/main/java/org/littleshoot/proxy/ProxyToServerExHandler.java rename to src/main/java/org/littleshoot/proxy/ExceptionHandler.java index 270036a18..0912f1a5c 100644 --- a/src/main/java/org/littleshoot/proxy/ProxyToServerExHandler.java +++ b/src/main/java/org/littleshoot/proxy/ExceptionHandler.java @@ -1,6 +1,6 @@ package org.littleshoot.proxy; -public interface ProxyToServerExHandler { +public interface ExceptionHandler { /** * Handles proxy to server error diff --git a/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java b/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java index cc31a4b6c..30f451e7f 100644 --- a/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java +++ b/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java @@ -181,10 +181,24 @@ HttpProxyServerBootstrap withChainProxyManager( HttpProxyServerBootstrap withManInTheMiddle( MitmManagerFactory mitmManager); + /** + *

+ * Specify an {@link ExceptionHandler} to handle proxy to server errors + *

+ * + *

+ * Default = null + *

+ * + * @param clientToProxyExHandler + * @return + */ + HttpProxyServerBootstrap withClientToProxyExHandler( + ExceptionHandler clientToProxyExHandler); /** *

- * Specify an {@link ProxyToServerExHandler} to handle proxy to server errors + * Specify an {@link ExceptionHandler} to handle proxy to server errors *

* *

@@ -195,7 +209,7 @@ HttpProxyServerBootstrap withManInTheMiddle( * @return */ HttpProxyServerBootstrap withProxyToServerExHandler( - ProxyToServerExHandler proxyToServerExHandler); + ExceptionHandler proxyToServerExHandler); /** *

diff --git a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java index f5e6a908b..b53dc9a74 100644 --- a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java +++ b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java @@ -26,6 +26,7 @@ import org.apache.commons.lang3.StringUtils; import org.littleshoot.proxy.ActivityTracker; import org.littleshoot.proxy.BadGatewayFailureHttpResponseComposer; +import org.littleshoot.proxy.ExceptionHandler; import org.littleshoot.proxy.FailureHttpResponseComposer; import org.littleshoot.proxy.FlowContext; import org.littleshoot.proxy.FullFlowContext; @@ -755,7 +756,13 @@ protected void exceptionCaught(Throwable cause) { LOG.info("An executor rejected a read or write operation on the ClientToProxyConnection (this is normal if the proxy is shutting down). Message: " + cause.getMessage()); LOG.debug("A RejectedExecutionException occurred on ClientToProxyConnection", cause); } else { - LOG.error("Caught an exception on ClientToProxyConnection", cause); + ExceptionHandler exHandler = proxyServer.getClientToProxyExHandler(); + if (exHandler != null) { + LOG.debug("Custom exception handler is used to process the cause"); + exHandler.handle(cause); + } else { + LOG.error("Caught an exception on ClientToProxyConnection", cause); + } } } finally { // always disconnect the client when an exception occurs on the channel diff --git a/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java b/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java index 784036969..91a2b710e 100644 --- a/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java +++ b/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java @@ -31,7 +31,7 @@ import org.littleshoot.proxy.MitmManager; import org.littleshoot.proxy.MitmManagerFactory; import org.littleshoot.proxy.ProxyAuthenticator; -import org.littleshoot.proxy.ProxyToServerExHandler; +import org.littleshoot.proxy.ExceptionHandler; import org.littleshoot.proxy.SslEngineSource; import org.littleshoot.proxy.TransportProtocol; import org.littleshoot.proxy.UnknownTransportProtocolException; @@ -111,7 +111,8 @@ public class DefaultHttpProxyServer implements HttpProxyServer { private final ProxyAuthenticator proxyAuthenticator; private final ChainedProxyManager chainProxyManager; private final MitmManagerFactory mitmManagerFactory; - private final ProxyToServerExHandler proxyToServerExHandler; + private final ExceptionHandler clientToProxyExHandler; + private final ExceptionHandler proxyToServerExHandler; private final HttpFiltersSource filtersSource; private final FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer; private final boolean transparent; @@ -245,7 +246,8 @@ private DefaultHttpProxyServer(ServerGroup serverGroup, ProxyAuthenticator proxyAuthenticator, ChainedProxyManager chainProxyManager, MitmManagerFactory mitmManagerFactory, - ProxyToServerExHandler proxyToServerExHandler, + ExceptionHandler clientToProxyExHandler, + ExceptionHandler proxyToServerExHandler, HttpFiltersSource filtersSource, FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer, boolean transparent, @@ -269,6 +271,7 @@ private DefaultHttpProxyServer(ServerGroup serverGroup, this.proxyAuthenticator = proxyAuthenticator; this.chainProxyManager = chainProxyManager; this.mitmManagerFactory = mitmManagerFactory; + this.clientToProxyExHandler = clientToProxyExHandler; this.proxyToServerExHandler = proxyToServerExHandler; this.filtersSource = filtersSource; this.unrecoverableFailureHttpResponseComposer = unrecoverableFailureHttpResponseComposer; @@ -405,6 +408,7 @@ public HttpProxyServerBootstrap clone() { proxyAuthenticator, chainProxyManager, mitmManagerFactory, + clientToProxyExHandler, proxyToServerExHandler, filtersSource, unrecoverableFailureHttpResponseComposer, @@ -584,7 +588,11 @@ protected MitmManager getMitmManager(Channel channel) { return null; } - protected ProxyToServerExHandler getProxyToServerExHandler() { + protected ExceptionHandler getClientToProxyExHandler() { + return clientToProxyExHandler; + } + + protected ExceptionHandler getProxyToServerExHandler() { return proxyToServerExHandler; } @@ -630,7 +638,8 @@ private static class DefaultHttpProxyServerBootstrap implements HttpProxyServerB private ProxyAuthenticator proxyAuthenticator = null; private ChainedProxyManager chainProxyManager = null; private MitmManagerFactory mitmManagerFactory = null; - private ProxyToServerExHandler proxyToServerExHandler = null; + private ExceptionHandler clientToProxyExHandler = null; + private ExceptionHandler proxyToServerExHandler = null; private HttpFiltersSource filtersSource = new HttpFiltersSourceAdapter(); private FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer = new BadGatewayFailureHttpResponseComposer(); private boolean transparent = false; @@ -662,7 +671,8 @@ private DefaultHttpProxyServerBootstrap( ProxyAuthenticator proxyAuthenticator, ChainedProxyManager chainProxyManager, MitmManagerFactory mitmManagerFactory, - ProxyToServerExHandler proxyToServerExHandler, + ExceptionHandler clientToProxyExHandler, + ExceptionHandler proxyToServerExHandler, HttpFiltersSource filtersSource, FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer, boolean transparent, int idleConnectionTimeout, @@ -685,6 +695,7 @@ private DefaultHttpProxyServerBootstrap( this.proxyAuthenticator = proxyAuthenticator; this.chainProxyManager = chainProxyManager; this.mitmManagerFactory = mitmManagerFactory; + this.clientToProxyExHandler = clientToProxyExHandler; this.proxyToServerExHandler = proxyToServerExHandler; this.filtersSource = filtersSource; this.unrecoverableFailureHttpResponseComposer = unrecoverableFailureHttpResponseComposer; @@ -821,11 +832,18 @@ public HttpProxyServerBootstrap withManInTheMiddle( @Override public HttpProxyServerBootstrap withProxyToServerExHandler( - ProxyToServerExHandler proxyToServerExHandler) { + ExceptionHandler proxyToServerExHandler) { this.proxyToServerExHandler = proxyToServerExHandler; return this; } + @Override + public HttpProxyServerBootstrap withClientToProxyExHandler( + ExceptionHandler clientToProxyExHandler) { + this.clientToProxyExHandler = clientToProxyExHandler; + return this; + } + @Override public HttpProxyServerBootstrap withFiltersSource( HttpFiltersSource filtersSource) { @@ -941,7 +959,8 @@ private DefaultHttpProxyServer build() { return new DefaultHttpProxyServer(serverGroup, transportProtocol, determineListenAddress(), sslEngineSource, authenticateSslClients, - proxyAuthenticator, chainProxyManager, mitmManagerFactory, proxyToServerExHandler, + proxyAuthenticator, chainProxyManager, mitmManagerFactory, + clientToProxyExHandler, proxyToServerExHandler, filtersSource, unrecoverableFailureHttpResponseComposer, transparent, idleConnectionTimeout, activityTrackers, connectTimeout, serverResolver, readThrottleBytesPerSecond, writeThrottleBytesPerSecond, diff --git a/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java b/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java index f7d158d68..c98c1be42 100644 --- a/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java +++ b/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java @@ -39,7 +39,7 @@ import org.littleshoot.proxy.FullFlowContext; import org.littleshoot.proxy.HttpFilters; import org.littleshoot.proxy.MitmManager; -import org.littleshoot.proxy.ProxyToServerExHandler; +import org.littleshoot.proxy.ExceptionHandler; import org.littleshoot.proxy.TransportProtocol; import org.littleshoot.proxy.UnknownTransportProtocolException; @@ -440,8 +440,9 @@ protected void exceptionCaught(Throwable cause) { LOG.info("An executor rejected a read or write operation on the ProxyToServerConnection (this is normal if the proxy is shutting down). Message: " + cause.getMessage()); LOG.debug("A RejectedExecutionException occurred on ProxyToServerConnection", cause); } else { - ProxyToServerExHandler exHandler = proxyServer.getProxyToServerExHandler(); + ExceptionHandler exHandler = proxyServer.getProxyToServerExHandler(); if (exHandler != null) { + LOG.debug("Custom exception handler is used to process the cause"); exHandler.handle(cause); } else { LOG.error("Caught an exception on ProxyToServerConnection", cause); diff --git a/src/test/java/org/littleshoot/proxy/CustomClientToProxyExHandlerTest.java b/src/test/java/org/littleshoot/proxy/CustomClientToProxyExHandlerTest.java new file mode 100644 index 000000000..3f07896b8 --- /dev/null +++ b/src/test/java/org/littleshoot/proxy/CustomClientToProxyExHandlerTest.java @@ -0,0 +1,51 @@ +package org.littleshoot.proxy; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.HttpRequest; +import org.apache.http.NoHttpResponseException; +import org.junit.Assert; +import org.junit.Test; +import org.littleshoot.proxy.extras.SelfSignedMitmManagerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class CustomClientToProxyExHandlerTest extends AbstractProxyTest { + + private final List customExHandlerEntered = new ArrayList<>(); + + private static final String EXCEPTION_MESSAGE = "Error occurred in client to proxy connection"; + + @Override + protected void setUp() { + this.proxyServer = bootstrapProxy() + .withPort(0) + .withManInTheMiddle(new SelfSignedMitmManagerFactory()) + .withClientToProxyExHandler(new ExceptionHandler() { + @Override + public void handle(Throwable cause) { + customExHandlerEntered.add(cause); + } + }) + .withFiltersSource(new HttpFiltersSourceAdapter() { + @Override + public HttpFilters filterRequest(HttpRequest originalRequest, + ChannelHandlerContext ctx) { + throw new RuntimeException(EXCEPTION_MESSAGE); + } + }) + .start(); + } + + @Test + public void testCustomClientToProxyExHandler() throws Exception { + try { + httpGetWithApacheClient(webHost, DEFAULT_RESOURCE, true, true); + } catch (NoHttpResponseException e) { + // expected + } + Assert.assertFalse("Custom ex handler was not called", customExHandlerEntered.isEmpty()); + Assert.assertEquals("Incorrect exception was passed to custom ex handles", + customExHandlerEntered.get(0).getMessage(), EXCEPTION_MESSAGE); + } +} diff --git a/src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java b/src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java index a7432a1a3..0a791acda 100644 --- a/src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java +++ b/src/test/java/org/littleshoot/proxy/CustomProxyToServerExHandlerTest.java @@ -9,7 +9,7 @@ public class CustomProxyToServerExHandlerTest extends MitmWithBadServerAuthenticationTCPChainedProxyTest { - private List customExHandlerEntered = new ArrayList<>(); + private final List customExHandlerEntered = new ArrayList<>(); @Override protected void setUp() { @@ -20,7 +20,7 @@ protected void setUp() { .withChainProxyManager(chainedProxyManager()) .plusActivityTracker(DOWNSTREAM_TRACKER) .withManInTheMiddle(new SelfSignedMitmManagerFactory()) - .withProxyToServerExHandler(new ProxyToServerExHandler() { + .withProxyToServerExHandler(new ExceptionHandler() { @Override public void handle(Throwable cause) { customExHandlerEntered.add(cause); @@ -35,7 +35,7 @@ protected void tearDown() throws Exception { } @Test - public void testCustomExHandler() throws Exception { + public void testCustomProxyToServerExHandler() throws Exception { super.testSimpleGetRequestOverHTTPS(); Assert.assertFalse("Custom ex handler was not called", customExHandlerEntered.isEmpty()); Assert.assertEquals("Incorrect exception was passed to custom ex handles", From c9dbe41884a88ca952da46d7324af8300d6df661 Mon Sep 17 00:00:00 2001 From: Slava Fomin Date: Tue, 20 Jun 2017 20:08:55 +0300 Subject: [PATCH 4/5] Fixes java docs --- src/main/java/org/littleshoot/proxy/ExceptionHandler.java | 3 ++- .../org/littleshoot/proxy/HttpProxyServerBootstrap.java | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/littleshoot/proxy/ExceptionHandler.java b/src/main/java/org/littleshoot/proxy/ExceptionHandler.java index 0912f1a5c..de2761bed 100644 --- a/src/main/java/org/littleshoot/proxy/ExceptionHandler.java +++ b/src/main/java/org/littleshoot/proxy/ExceptionHandler.java @@ -3,7 +3,8 @@ public interface ExceptionHandler { /** - * Handles proxy to server error + * Handles proxy exception + * * @param cause error cause */ void handle(Throwable cause); diff --git a/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java b/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java index 30f451e7f..7eb838673 100644 --- a/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java +++ b/src/main/java/org/littleshoot/proxy/HttpProxyServerBootstrap.java @@ -183,7 +183,7 @@ HttpProxyServerBootstrap withManInTheMiddle( /** *

- * Specify an {@link ExceptionHandler} to handle proxy to server errors + * Specify an {@link ExceptionHandler} to handle client to proxy errors *

* *

@@ -191,7 +191,7 @@ HttpProxyServerBootstrap withManInTheMiddle( *

* * @param clientToProxyExHandler - * @return + * @return exception handler */ HttpProxyServerBootstrap withClientToProxyExHandler( ExceptionHandler clientToProxyExHandler); @@ -206,7 +206,7 @@ HttpProxyServerBootstrap withClientToProxyExHandler( *

* * @param proxyToServerExHandler - * @return + * @return exception handler */ HttpProxyServerBootstrap withProxyToServerExHandler( ExceptionHandler proxyToServerExHandler); From 1f7253ff6042d3608491147d0e8efd6d2d1ee7fd Mon Sep 17 00:00:00 2001 From: Slava Fomin Date: Tue, 20 Jun 2017 22:31:47 +0300 Subject: [PATCH 5/5] Fixes after code review --- pom.xml | 2 +- src/main/java/org/littleshoot/proxy/ExceptionHandler.java | 4 ++-- .../org/littleshoot/proxy/impl/ClientToProxyConnection.java | 2 +- .../org/littleshoot/proxy/impl/ProxyToServerConnection.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index e895f4e6c..69eb55325 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.littleshoot littleproxy jar - 1.1.3.2-VGS-SNAPSHOT + 1.1.3.3-VGS-SNAPSHOT LittleProxy LittleProxy is a high performance HTTP proxy written in Java and using the Netty networking framework. diff --git a/src/main/java/org/littleshoot/proxy/ExceptionHandler.java b/src/main/java/org/littleshoot/proxy/ExceptionHandler.java index de2761bed..41fc38bdd 100644 --- a/src/main/java/org/littleshoot/proxy/ExceptionHandler.java +++ b/src/main/java/org/littleshoot/proxy/ExceptionHandler.java @@ -3,8 +3,8 @@ public interface ExceptionHandler { /** - * Handles proxy exception - * + * Handles proxy exceptions + * * @param cause error cause */ void handle(Throwable cause); diff --git a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java index b53dc9a74..afef50a11 100644 --- a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java +++ b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java @@ -758,7 +758,7 @@ protected void exceptionCaught(Throwable cause) { } else { ExceptionHandler exHandler = proxyServer.getClientToProxyExHandler(); if (exHandler != null) { - LOG.debug("Custom exception handler is used to process the cause"); + LOG.debug("Custom exception handler '" + exHandler.toString() + "' invoked", cause); exHandler.handle(cause); } else { LOG.error("Caught an exception on ClientToProxyConnection", cause); diff --git a/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java b/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java index c98c1be42..3bd22224a 100644 --- a/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java +++ b/src/main/java/org/littleshoot/proxy/impl/ProxyToServerConnection.java @@ -442,7 +442,7 @@ protected void exceptionCaught(Throwable cause) { } else { ExceptionHandler exHandler = proxyServer.getProxyToServerExHandler(); if (exHandler != null) { - LOG.debug("Custom exception handler is used to process the cause"); + LOG.debug("Custom exception handler '" + exHandler.toString() + "' invoked", cause); exHandler.handle(cause); } else { LOG.error("Caught an exception on ProxyToServerConnection", cause);