我正在实现一个代理服务器,它在Android应用程序中本地工作,并将所有http调用从应用程序webView重定向到某个安全服务器,它将响应返回,就像它是初始Web资源一样。应将响应返回给webView进行解析和处理。通过反射为webView启用了调用重定向。我正在使用LittleProxy进行代理,我想拦截所有请求的最佳位置是HttpFiltersSourceAdapter
,方法proxyToServerRequest
。所以,我已经实现了这样的代理:
private void startHttpServer() {
HttpProxyServerBootstrap serverBootstrap = DefaultHttpProxyServer.bootstrap().
withManInTheMiddle(new ProxyMitmManager()).
withAddress(new InetSocketAddress("localhost", port)).
withFiltersSource(new HttpFiltersSourceAdapter() {
@Override
public HttpFilters filterRequest(HttpRequest originalRequest) {
return new HttpFiltersAdapter(originalRequest) {
@Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
return super.clientToProxyRequest(httpObject);
}
@Override
public HttpResponse proxyToServerRequest(HttpObject httpObject) {
Log.d(LOG_TAG, "HttpObject type: " + httpObject.getClass().getName());
DefaultHttpRequest req = (DefaultHttpRequest) httpObject;
StringBuilder requestBuilder = new StringBuilder();
requestBuilder.append(this.originalRequest.getMethod().name()).append(" ");
requestBuilder.append(this.originalRequest.getUri()).append(" ");
requestBuilder.append(this.originalRequest.getProtocolVersion().text());
List<Map.Entry<String, String>> headers = req.headers().entries();
Map<String, String> headersMap = new HashMap<>();
for (Map.Entry entry : headers) {
headersMap.put((String) entry.getKey(), (String) entry.getValue());
}
try {
// here I send data to my secure server and get response
my.app.package.HttpResponse httpResponse = sendRequest(requestBuilder.toString(), headersMap);
HttpResponse nettyResponse = new DefaultFullHttpResponse(
new HttpVersion(httpResponse.getHttpVersion(), true),
new HttpResponseStatus(httpResponse.getStatusCode(), httpResponse.getStatusMessage()),
Unpooled.copiedBuffer(httpResponse.getBody()));
return nettyResponse;
} catch (Exception e) {
Errors.log(e);
}
return null;
}
@Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
return super.serverToProxyResponse(httpObject);
}
@Override
public HttpObject proxyToClientResponse(HttpObject httpObject) {
HttpObject object = httpObject;
return super.proxyToClientResponse(httpObject);
}
};
}
});
httpServer = serverBootstrap.start();
}
问题如下 - 当我开始加载数据时,几个请求就可以了,但是在Logcat中我看到了:
D: 16:20:59.601 [LittleProxy-ClientToProxyWorker-0] DEBUG o.l.p.impl.ClientToProxyConnection - (AWAITING_INITIAL) [id: 0x52573ac7, /127.0.0.1:56972 => /127.0.0.1:48654]: Writability changed. Is writable: false
D: 16:20:59.601 [LittleProxy-ClientToProxyWorker-0] DEBUG o.l.p.impl.ClientToProxyConnection - (AWAITING_INITIAL) [id: 0x52573ac7, /127.0.0.1:56972 => /127.0.0.1:48654]: Became saturated
D: 16:20:59.601 [LittleProxy-ClientToProxyWorker-0] DEBUG o.l.p.impl.ProxyToServerConnection - (DISCONNECTED): Stopped reading
E: 16:20:59.609 [LittleProxy-ClientToProxyWorker-0] ERROR o.l.p.impl.ClientToProxyConnection - (AWAITING_INITIAL) [id: 0x52573ac7, /127.0.0.1:56972 => /127.0.0.1:48654]: Caught an exception on ClientToProxyConnection
java.lang.NullPointerException: Attempt to invoke interface method 'io.netty.channel.ChannelConfig io.netty.channel.Channel.config()' on a null object reference
at org.littleshoot.proxy.impl.ProxyConnection.stopReading(ProxyConnection.java:544) ~[na:0.0]
at org.littleshoot.proxy.impl.ClientToProxyConnection.becameSaturated(ClientToProxyConnection.java:663) ~[na:0.0]
at org.littleshoot.proxy.impl.ProxyConnection.channelWritabilityChanged(ProxyConnection.java:627) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:391) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:373) ~[na:0.0]
at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:391) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:373) ~[na:0.0]
at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:391) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:373) ~[na:0.0]
at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:391) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:373) ~[na:0.0]
at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:391) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:373) ~[na:0.0]
at io.netty.channel.DefaultChannelPipeline.fireChannelWritabilityChanged(DefaultChannelPipeline.java:802) ~[na:0.0]
at io.netty.channel.ChannelOutboundBuffer.incrementPendingOutboundBytes(ChannelOutboundBuffer.java:166) ~[na:0.0]
at io.netty.channel.ChannelOutboundBuffer.addMessage(ChannelOutboundBuffer.java:121) ~[na:0.0]
at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:665) ~[na:0.0]
at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1054) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:651) ~[na:0.0]
at io.netty.channel.ChannelOutboundHandlerAdapter.write(ChannelOutboundHandlerAdapter.java:104) ~[na:0.0]
at org.littleshoot.proxy.impl.ProxyConnection$BytesWrittenMonitor.write(ProxyConnection.java:754) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:658) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:716) ~[na:0.0]
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:651) ~[na:0.0]
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:127) ~[na:0.0]
at io.net
因此,我的内容在webView中不可见,并且日志中出现504 Bad gateway
个错误。
如果我删除对我的服务器的http调用,一切正常。有人有想法吗?也许我不应该用proxyToServerRequest
方法向我的服务器发送http请求?如果是这样,我应该在哪里做到这一点?