+ * Specify a {@link RequestTracer} to trace proxy requests + *
+ * + *+ * Default = null + *
+ * + * @param requestTracer + * @return proxy server bootstrap + */ + HttpProxyServerBootstrap withRequestTracer(RequestTracer requestTracer); + /** *
* Specify an {@link GlobalStateHandler} to customize a global state based on channel attributes
diff --git a/src/main/java/org/littleshoot/proxy/RequestTracer.java b/src/main/java/org/littleshoot/proxy/RequestTracer.java
new file mode 100644
index 000000000..68505e293
--- /dev/null
+++ b/src/main/java/org/littleshoot/proxy/RequestTracer.java
@@ -0,0 +1,18 @@
+package org.littleshoot.proxy;
+
+import io.netty.channel.Channel;
+
+public interface RequestTracer {
+
+ /**
+ * Start tracing proxy request
+ * @param channel
+ */
+ void start(Channel channel);
+
+ /**
+ * Request is served. Finish tracing.
+ * @param channel
+ */
+ void finish(Channel channel);
+}
diff --git a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java
index 26161cfa2..a4347e9c7 100644
--- a/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java
+++ b/src/main/java/org/littleshoot/proxy/impl/ClientToProxyConnection.java
@@ -4,7 +4,6 @@
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.DefaultHttpRequest;
import io.netty.handler.codec.http.FullHttpRequest;
@@ -771,17 +770,6 @@ protected void exceptionCaught(Throwable cause) {
}
}
- @Override
- public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
- try {
- if (this.proxyServer.getGlobalStateHandler() != null) {
- this.proxyServer.getGlobalStateHandler().persistToChannel(ctx.channel());
- }
- } finally {
- super.channelRegistered(ctx);
- }
- }
-
/***************************************************************************
* Connection Management
**************************************************************************/
@@ -803,6 +791,10 @@ public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
private void initChannelPipeline(ChannelPipeline pipeline) {
LOG.debug("Configuring ChannelPipeline");
+ if (proxyServer.getRequestTracer() != null) {
+ pipeline.addLast("requestTracerHandler", new RequestTracerHandler(this));
+ }
+
if (proxyServer.getGlobalStateHandler() != null) {
pipeline.addLast("inboundGlobalStateHandler", new InboundGlobalStateHandler(this));
}
diff --git a/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java b/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java
index cc618d48d..32ad0195f 100644
--- a/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java
+++ b/src/main/java/org/littleshoot/proxy/impl/DefaultHttpProxyServer.java
@@ -33,6 +33,7 @@
import org.littleshoot.proxy.MitmManagerFactory;
import org.littleshoot.proxy.ProxyAuthenticator;
import org.littleshoot.proxy.ExceptionHandler;
+import org.littleshoot.proxy.RequestTracer;
import org.littleshoot.proxy.SslEngineSource;
import org.littleshoot.proxy.TransportProtocol;
import org.littleshoot.proxy.UnknownTransportProtocolException;
@@ -114,6 +115,7 @@ public class DefaultHttpProxyServer implements HttpProxyServer {
private final MitmManagerFactory mitmManagerFactory;
private final ExceptionHandler clientToProxyExHandler;
private final ExceptionHandler proxyToServerExHandler;
+ private final RequestTracer requestTracer;
private final GlobalStateHandler globalStateHandler;
private final HttpFiltersSource filtersSource;
private final FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer;
@@ -250,6 +252,7 @@ private DefaultHttpProxyServer(ServerGroup serverGroup,
MitmManagerFactory mitmManagerFactory,
ExceptionHandler clientToProxyExHandler,
ExceptionHandler proxyToServerExHandler,
+ RequestTracer requestTracer,
GlobalStateHandler globalStateHandler,
HttpFiltersSource filtersSource,
FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer,
@@ -276,6 +279,7 @@ private DefaultHttpProxyServer(ServerGroup serverGroup,
this.mitmManagerFactory = mitmManagerFactory;
this.clientToProxyExHandler = clientToProxyExHandler;
this.proxyToServerExHandler = proxyToServerExHandler;
+ this.requestTracer = requestTracer;
this.globalStateHandler = globalStateHandler;
this.filtersSource = filtersSource;
this.unrecoverableFailureHttpResponseComposer = unrecoverableFailureHttpResponseComposer;
@@ -414,6 +418,7 @@ public HttpProxyServerBootstrap clone() {
mitmManagerFactory,
clientToProxyExHandler,
proxyToServerExHandler,
+ requestTracer,
globalStateHandler,
filtersSource,
unrecoverableFailureHttpResponseComposer,
@@ -605,6 +610,10 @@ protected GlobalStateHandler getGlobalStateHandler() {
return globalStateHandler;
}
+ protected RequestTracer getRequestTracer() {
+ return requestTracer;
+ }
+
protected SslEngineSource getSslEngineSource() {
return sslEngineSource;
}
@@ -649,6 +658,7 @@ private static class DefaultHttpProxyServerBootstrap implements HttpProxyServerB
private MitmManagerFactory mitmManagerFactory = null;
private ExceptionHandler clientToProxyExHandler = null;
private ExceptionHandler proxyToServerExHandler = null;
+ private RequestTracer requestTracer = null;
private GlobalStateHandler globalStateHandler = null;
private HttpFiltersSource filtersSource = new HttpFiltersSourceAdapter();
private FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer = new DefaultFailureHttpResponseComposer();
@@ -683,6 +693,7 @@ private DefaultHttpProxyServerBootstrap(
MitmManagerFactory mitmManagerFactory,
ExceptionHandler clientToProxyExHandler,
ExceptionHandler proxyToServerExHandler,
+ RequestTracer requestTracer,
GlobalStateHandler globalStateHandler,
HttpFiltersSource filtersSource,
FailureHttpResponseComposer unrecoverableFailureHttpResponseComposer,
@@ -708,6 +719,7 @@ private DefaultHttpProxyServerBootstrap(
this.mitmManagerFactory = mitmManagerFactory;
this.clientToProxyExHandler = clientToProxyExHandler;
this.proxyToServerExHandler = proxyToServerExHandler;
+ this.requestTracer = requestTracer;
this.globalStateHandler = globalStateHandler;
this.filtersSource = filtersSource;
this.unrecoverableFailureHttpResponseComposer = unrecoverableFailureHttpResponseComposer;
@@ -856,6 +868,13 @@ public HttpProxyServerBootstrap withClientToProxyExHandler(
return this;
}
+ @Override
+ public HttpProxyServerBootstrap withRequestTracer(
+ RequestTracer requestTracer) {
+ this.requestTracer = requestTracer;
+ return this;
+ }
+
@Override
public HttpProxyServerBootstrap withCustomGlobalState(
GlobalStateHandler globalStateHandler) {
@@ -863,7 +882,6 @@ public HttpProxyServerBootstrap withCustomGlobalState(
return this;
}
-
@Override
public HttpProxyServerBootstrap withFiltersSource(
HttpFiltersSource filtersSource) {
@@ -980,7 +998,7 @@ private DefaultHttpProxyServer build() {
transportProtocol, determineListenAddress(),
sslEngineSource, authenticateSslClients,
proxyAuthenticator, chainProxyManager, mitmManagerFactory,
- clientToProxyExHandler, proxyToServerExHandler, globalStateHandler,
+ clientToProxyExHandler, proxyToServerExHandler, requestTracer, globalStateHandler,
filtersSource, unrecoverableFailureHttpResponseComposer, transparent,
idleConnectionTimeout, activityTrackers, connectTimeout,
serverResolver, readThrottleBytesPerSecond, writeThrottleBytesPerSecond,
diff --git a/src/main/java/org/littleshoot/proxy/impl/ProxyConnection.java b/src/main/java/org/littleshoot/proxy/impl/ProxyConnection.java
index 5c68a8d96..fc2d89b6e 100644
--- a/src/main/java/org/littleshoot/proxy/impl/ProxyConnection.java
+++ b/src/main/java/org/littleshoot/proxy/impl/ProxyConnection.java
@@ -743,6 +743,41 @@ public void channelRead(ChannelHandlerContext ctx, Object msg)
protected abstract void responseRead(HttpResponse httpResponse);
}
+ @Sharable
+ protected class RequestTracerHandler extends ChannelDuplexHandler {
+
+ private final ProxyConnection