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 リクエストを送信するべきではないでしょうか? もしそうなら、私はこれをどこでやるべきですか?