引用:html
https://github.com/adamfisk/LittleProxyjava
攔截和操縱HTTPS流量,LittleProxy使用中間人(MITM)管理器。 LittleProxy的默認實現(SelfSignedMitmManager)具備至關有限的功能集。 爲了更好地控制證書模擬,瀏覽器信任,TLS握手等,請使用LittleProxy兼容的MITM擴展:git
一個LittleProxy MITM擴展,旨在支持包括Android在內的全部Java平臺
支持橢圓曲線加密和自定義信任存儲的LittleProxy MITM擴展github
要過濾HTTP流量,能夠使用HttpFiltersSource(適配器)添加請求和響應過濾器,例如:bootstrap
請參閱org.littleshoot.proxy.HttpFilters的Javadoc來查看您能夠使用的方法。瀏覽器
要啓用aggregator和inflater,必須在HttpFiltersSource#get(Request / Response)BufferSizeInBytes()方法中返回一個大於0的值。 這爲您提供了一個「FullHttp(請求/響應)」,未壓縮過濾器中的完整內容。 不然,你必須本身處理大塊。服務器
這個大小限制適用於每一個鏈接。 例如,要禁止在* .iso或* dmg文件中經過URL進行聚合,您能夠在過濾器源代碼中返回以下所示的過濾器:app
這能夠在應用程序中進行大量的下載,這些應用程序按期處理大小有限的FullHttpResponses來修改其內容,例如HTML。ide
像LittleProxy這樣的代理服務器老是包含一個Web服務器。 若是您在原始請求中得到沒有方案,主機和端口的URI,那麼這是對您的代理的直接請求。 您能夠返回一個HttpFilters實現,它能夠回答HTML內容的響應,或者像這樣在clientToProxyRequest中重定向:this
在回答重定向時,您應該添加一個Connection:close標頭,以免阻止行爲:
<dependency> <groupId>org.littleshoot</groupId> <artifactId>littleproxy</artifactId> <version>1.1.2</version> <exclusions> <exclusion> <artifactId>netty-all</artifactId> <groupId>io.netty</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.19.Final</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.6-jre</version> </dependency>
package com.pc.proxy; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.handler.codec.http.HttpObject; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; import org.littleshoot.proxy.HttpFilters; import org.littleshoot.proxy.HttpFiltersAdapter; import org.littleshoot.proxy.HttpFiltersSourceAdapter; import org.littleshoot.proxy.HttpProxyServerBootstrap; import org.littleshoot.proxy.impl.DefaultHttpProxyServer; public class ProxyServer { public static void main(String[] args) { HttpProxyServerBootstrap bootstrap = DefaultHttpProxyServer.bootstrap(); bootstrap.withPort(8080) .withFiltersSource(new HttpFiltersSourceAdapter() { @Override public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) { return new HttpFiltersAdapter(originalRequest) { @Override public HttpResponse clientToProxyRequest(HttpObject httpObject) { // TODO: implement your filtering here return new AnswerRequestFilter(originalRequest,"test").clientToProxyRequest(httpObject); } @Override public HttpObject serverToProxyResponse(HttpObject httpObject) { // TODO: implement your filtering here return httpObject; } @Override public void proxyToServerConnectionSucceeded(ChannelHandlerContext serverCtx) { ChannelPipeline pipeline = serverCtx.pipeline(); if (pipeline.get("inflater") != null) { pipeline.remove("inflater"); } if (pipeline.get("aggregator") != null) { pipeline.remove("aggregator"); } super.proxyToServerConnectionSucceeded(serverCtx); } }; } @Override public int getMaximumResponseBufferSizeInBytes() { return 10 * 1024 * 1024; } }); bootstrap.start(); } }
package com.pc.proxy; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.*; import org.littleshoot.proxy.HttpFiltersAdapter; import java.io.UnsupportedEncodingException; public class AnswerRequestFilter extends HttpFiltersAdapter { private String answer; public AnswerRequestFilter(HttpRequest originalRequest, String answer) { super(originalRequest, null); this.answer = answer; } public AnswerRequestFilter(HttpRequest originalRequest, ChannelHandlerContext ctx) { super(originalRequest, ctx); } @Override public HttpResponse clientToProxyRequest(HttpObject httpObject){ ByteBuf buffer = null; try { buffer = Unpooled.wrappedBuffer(answer.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buffer); HttpUtil.setContentLength(response, buffer.readableBytes()); // HttpHeaders.setHeader(response, HttpHeaders.Names.CONTENT_TYPE, "text/html"); response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/html"); return response; } }