使用Netty 5.0的MITM:浏览器无法接收完整的http响应

时间:2014-12-05 07:49:00

标签: java proxy netty

我正在使用Netty 5.0构建MITM代理。这基本上是一个教育项目,仅供我自己学习如何构建MITM代理以及如何使用Netty。与此同时,我正在使用WebDriver以编程方式使浏览器使用MITM代理进行测试。

从概念上讲,它对我来说很简单,至少对于HTTP来说(HTTPS需要一些额外的处理,但不应该太难)。以下是我对MITM代理结构的看法。

首先,代理需要两个管道。一个连接浏览器和代理(让我们称之为服务器管道)。另一个将代理连接到Internet(让我们称之为客户端管道)。所以,整体结构将是这样的:
浏览器< ---服务器管道---> MITM代理< ---客户管道--->互联网

其次,服务器管道可以构造如下:

public void initChannel(SocketChannel ch) throws Exception {
    ChannelPipeline p = ch.pipeline();
    p.addLast(SERVER_LOGGING_HANDLER, new LoggingHandler(SERVER_LOGGING_HANDLER, LogLevel.DEBUG))
            .addLast(HTTP_SERVER_CODEC, new HttpServerCodec())
            .addLast(HTTP_CONTENT_AGGREGATOR, new HttpObjectAggregator(MAX_HTTP_CONTENT_LENGTH))
            .addLast(SERVER_HANDLER, new ServerHandler(ch));
}

客户端管道可以构造如下:

protected void initChannel(SocketChannel ch) throws Exception {
    ChannelPipeline p = ch.pipeline();
    p.addLast(CLIENT_LOGGING_HANDLER, new LoggingHandler(CLIENT_LOGGING_HANDLER, LogLevel.DEBUG))
            .addLast(HTTP_CLIENT_CODEC, new HttpClientCodec())
            .addLast(HTTP_CONTENT_AGGREGATOR, new HttpObjectAggregator(MAX_HTTP_CONTENT_LENGTH))
            .addLast(CLIENT_HANDLER, new ClientHandler(ServerHandler.this, ch));
}

在上面的代码中,ServerHandlerClientHandler是我的自定义类。 ClientHandler所做的是致电ServerHandler将其收到的内容写入浏览器。以下是两个类的相关代码:

// ClientHandler
private ServerHandler serverHandler;
@Override
protected void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    log.info("client pipeline handlers: " + ctx.pipeline().names());
    if (msg instanceof FullHttpResponse) {
        FullHttpResponse response = (FullHttpResponse) msg;
        log.info("Received HTTP response:\n{}", response);
        serverHandler.writeResponse(msg);
    } else {
        ... // exception case
    }
}

// ServerHandler
public void writeResponse(HttpObject httpObject) {
    log.info("Is FullHttpResponse? {}", httpObject instanceof FullHttpResponse);
    ChannelHandlerContext context = channel.pipeline().context(this);
    context.writeAndFlush(httpObject);
    log.debug("sent response back to client");
}

我在测试中使用了netty javadoc页面。以下是一些相关的内容:

EventFiringWebDriver driver = null;
try {
    driver = getChromeDriver(proxyAddr); // get a ChromeDriver with the given proxyAddr as proxy
    driver.get("http://netty.io/5.0/api/io/netty/channel/ChannelPipeline.html");
    ...
} catch (Exception e) {
...

从代理日志中,我可以看到它能够按预期处理代理。但是,在最后一步,即将javadoc页面内容发送到浏览器,似乎有些东西被打破了。具体来说,FullHttpResponse的内容长度超过10KB,但只有不到1KB的数据被发送到浏览器(Chrome)。由于浏览器没有收到整个内容,它只是在地址栏中等待“数据”。

以下是可能有助于理解问题的日志(我从LoggingHandler中删除了大部分格式化的输出,只保留了一些):

2014-12-04 22:58:19.428 [Test worker] DEBUG MultithreadEventLoopGroup:debug(): -Dio.netty.eventLoopThreads: 16
2014-12-04 22:58:19.440 [Test worker] DEBUG NioEventLoop:debug(): -Dio.netty.noKeySetOptimization: false
2014-12-04 22:58:19.440 [Test worker] DEBUG NioEventLoop:debug(): -Dio.netty.selectorAutoRebuildThreshold: 512
2014-12-04 22:58:19.448 [Test worker] INFO  ProxyServer:start(): Starting proxy server.
2014-12-04 22:58:19.453 [Test worker] INFO  ProxyServer:initPorts(): Binding port 10001
2014-12-04 22:58:19.460 [Test worker] DEBUG DefaultChannelId:debug(): -Dio.netty.machineId: b8:e8:56:45:4f:e8:00:00 (auto-detected)
2014-12-04 22:58:19.461 [Test worker] DEBUG DefaultChannelId:debug(): -Dio.netty.processId: 47735 (auto-detected)
2014-12-04 22:58:19.463 [Test worker] DEBUG ThreadLocalRandom:debug(): -Dio.netty.initialSeedUniquifier: 0x0ee5184323c884e4
2014-12-04 22:58:19.469 [Test worker] DEBUG ChannelOutboundBuffer:debug(): -Dio.netty.threadLocalDirectBufferSize: 65536
2014-12-04 22:58:19.489 [Test worker] DEBUG PlatformDependent:debug(): UID: 83297
2014-12-04 22:58:19.490 [Test worker] DEBUG PlatformDependent:debug(): Java version: 7
2014-12-04 22:58:19.490 [Test worker] DEBUG PlatformDependent:debug(): -Dio.netty.noUnsafe: false
2014-12-04 22:58:19.491 [Test worker] DEBUG PlatformDependent0:debug(): java.nio.ByteBuffer.cleaner: available
2014-12-04 22:58:19.492 [Test worker] DEBUG PlatformDependent0:debug(): java.nio.Buffer.address: available
2014-12-04 22:58:19.492 [Test worker] DEBUG PlatformDependent0:debug(): sun.misc.Unsafe.theUnsafe: available
2014-12-04 22:58:19.493 [Test worker] DEBUG PlatformDependent0:debug(): sun.misc.Unsafe.copyMemory: available
2014-12-04 22:58:19.494 [Test worker] DEBUG PlatformDependent0:debug(): java.nio.Bits.unaligned: true
2014-12-04 22:58:19.494 [Test worker] DEBUG PlatformDependent:debug(): sun.misc.Unsafe: available
2014-12-04 22:58:19.495 [Test worker] DEBUG PlatformDependent:debug(): -Dio.netty.noJavassist: false
2014-12-04 22:58:19.564 [Test worker] DEBUG PlatformDependent:debug(): Javassist: available
2014-12-04 22:58:19.564 [Test worker] DEBUG PlatformDependent:debug(): -Dio.netty.noPreferDirect: false
2014-12-04 22:58:19.568 [Test worker] DEBUG NetUtil:debug(): Loopback interface: lo0
2014-12-04 22:58:19.568 [Test worker] DEBUG NetUtil:debug(): Loopback address: /fe80:0:0:0:0:0:0:1%1 (primary)
2014-12-04 22:58:19.569 [Test worker] DEBUG NetUtil:debug(): Loopback address: /0:0:0:0:0:0:0:1
2014-12-04 22:58:19.569 [Test worker] DEBUG NetUtil:debug(): Loopback address: /127.0.0.1
2014-12-04 22:58:19.576 [Test worker] INFO  ProxyServer:initPorts(): is 10001 bound? true
2014-12-04 22:58:19.576 [Test worker] INFO  ProxyServer:initPorts(): Binding port 10002
2014-12-04 22:58:19.578 [Test worker] INFO  ProxyServer:initPorts(): is 10002 bound? true

Starting ChromeDriver (v2.9.248307) on port 44495
2014-12-04 22:58:22.581 [nioEventLoopGroup-3-1] DEBUG ResourceLeakDetector:debug(): -Dio.netty.leakDetectionLevel: simple
2014-12-04 22:58:22.599 [nioEventLoopGroup-3-1] DEBUG JavassistTypeParameterMatcherGenerator:debug(): Generated: io.netty.util.internal.__matchers__.io.netty.handler.codec.http.HttpObjectMatcher
2014-12-04 22:58:22.604 [nioEventLoopGroup-3-1] DEBUG SERVER_LOGGING_HANDLER:debug(): [id: 0xad3d76c2, /0:0:0:0:0:0:0:1:57916 => /0:0:0:0:0:0:0:1:10001] REGISTERED
2014-12-04 22:58:22.605 [nioEventLoopGroup-3-1] DEBUG SERVER_LOGGING_HANDLER:debug(): [id: 0xad3d76c2, /0:0:0:0:0:0:0:1:57916 => /0:0:0:0:0:0:0:1:10001] ACTIVE
2014-12-04 22:58:22.606 [nioEventLoopGroup-3-1] DEBUG SERVER_LOGGING_HANDLER:debug(): [id: 0xad3d76c2, /0:0:0:0:0:0:0:1:57916 => /0:0:0:0:0:0:0:1:10001] RECEIVED: 413B
2014-12-04 22:58:22.615 [nioEventLoopGroup-3-1] INFO  ServerHandler:channelRead(): server pipeline handlers: [SERVER_LOGGING_HANDLER, HttpRequestDecoder#0, HttpResponseEncoder#0, HTTP_CONTENT_AGGREGATOR, SERVER_HANDLER, DefaultChannelPipeline$TailHandler#0]
2014-12-04 22:58:22.616 [nioEventLoopGroup-3-1] INFO  ServerHandler:handleInternetTraffic(): Received full request:
DefaultFullHttpRequest, decodeResult: success)
GET http://netty.io/5.0/api/io/netty/channel/ChannelPipeline.html HTTP/1.1
Host: netty.io
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Content-Length: 0
2014-12-04 22:58:22.616 [nioEventLoopGroup-3-1] DEBUG ServerHandler:sendToInternet(): uri: http://netty.io/5.0/api/io/netty/channel/ChannelPipeline.html
2014-12-04 22:58:22.680 [nioEventLoopGroup-4-1] INFO  ClientHandler:<init>(): Constructing new ClientHandler...
2014-12-04 22:58:22.682 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032] REGISTERED
2014-12-04 22:58:22.682 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032] CONNECT: netty.io/104.28.8.44:80
2014-12-04 22:58:22.699 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] ACTIVE
2014-12-04 22:58:22.699 [nioEventLoopGroup-4-1] INFO  ClientHandler:write(): Write outbound message.
2014-12-04 22:58:22.700 [nioEventLoopGroup-3-1] DEBUG SERVER_LOGGING_HANDLER:debug(): [id: 0xad3d76c2, /0:0:0:0:0:0:0:1:57916 => /0:0:0:0:0:0:0:1:10001] FLUSH
2014-12-04 22:58:22.702 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] WRITE: 432B
2014-12-04 22:58:22.702 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] FLUSH
2014-12-04 22:58:22.879 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d |HTTP/1.1 200 OK.|
|00000010| 0a 44 61 74 65 3a 20 46 72 69 2c 20 30 35 20 44 |.Date: Fri, 05 D|
|00000020| 65 63 20 32 30 31 34 20 30 36 3a 35 38 3a 32 32 |ec 2014 06:58:22|
|00000030| 20 47 4d 54 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 | GMT..Content-Ty|
|00000040| 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c 3b 20 63 |pe: text/html; c|
|00000050| 68 61 72 73 65 74 3d 75 74 66 2d 38 0d 0a 54 72 |harset=utf-8..Tr|
|00000060| 61 6e 73 66 65 72 2d 45 6e 63 6f 64 69 6e 67 3a |ansfer-Encoding:|
|00000070| 20 63 68 75 6e 6b 65 64 0d 0a 43 6f 6e 6e 65 63 | chunked..Connec|
|00000080| 74 69 6f 6e 3a 20 6b 65 65 70 2d 61 6c 69 76 65 |tion: keep-alive|
|00000090| 0d 0a 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 5f 5f |..Set-Cookie: __|
|000000a0| 63 66 64 75 69 64 3d 64 65 65 37 66 34 65 33 30 |cfduid=dee7f4e30|
|000000b0| 64 33 30 65 31 63 64 37 33 33 30 63 63 33 35 65 |d30e1cd7330cc35e|
|000000c0| 38 65 30 66 38 63 37 36 31 34 31 37 37 36 32 37 |8e0f8c7614177627|
|000000d0| 30 32 3b 20 65 78 70 69 72 65 73 3d 53 61 74 2c |02; expires=Sat,|
|000000e0| 20 30 35 2d 44 65 63 2d 31 35 20 30 36 3a 35 38 | 05-Dec-15 06:58|
|000000f0| 3a 32 32 20 47 4d 54 3b 20 70 61 74 68 3d 2f 3b |:22 GMT; path=/;|
|00000100| 20 64 6f 6d 61 69 6e 3d 2e 6e 65 74 74 79 2e 69 | domain=.netty.i|
|00000110| 6f 3b 20 48 74 74 70 4f 6e 6c 79 0d 0a 4c 61 73 |o; HttpOnly..Las|
|00000120| 74 2d 4d 6f 64 69 66 69 65 64 3a 20 54 68 75 2c |t-Modified: Thu,|
|00000130| 20 30 34 20 44 65 63 20 32 30 31 34 20 31 32 3a | 04 Dec 2014 12:|
|00000140| 31 32 3a 33 36 20 47 4d 54 0d 0a 45 78 70 69 72 |12:36 GMT..Expir|
|00000150| 65 73 3a 20 46 72 69 2c 20 30 35 20 44 65 63 20 |es: Fri, 05 Dec |
|00000160| 32 30 31 34 20 30 37 3a 30 38 3a 32 32 20 47 4d |2014 07:08:22 GM|
|00000170| 54 0d 0a 43 61 63 68 65 2d 43 6f 6e 74 72 6f 6c |T..Cache-Control|
|00000180| 3a 20 6d 61 78 2d 61 67 65 3d 36 30 30 0d 0a 56 |: max-age=600..V|
|00000190| 61 72 79 3a 20 41 63 63 65 70 74 2d 45 6e 63 6f |ary: Accept-Enco|
|000001a0| 64 69 6e 67 0d 0a 53 65 72 76 65 72 3a 20 63 6c |ding..Server: cl|
|000001b0| 6f 75 64 66 6c 61 72 65 2d 6e 67 69 6e 78 0d 0a |oudflare-nginx..|
|000001c0| 43 46 2d 52 41 59 3a 20 31 39 33 65 35 61 64 38 |CF-RAY: 193e5ad8|
|000001d0| 63 33 39 33 30 36 36 33 2d 53 4a 43 0d 0a 43 6f |c3930663-SJC..Co|
|000001e0| 6e 74 65 6e 74 2d 45 6e 63 6f 64 69 6e 67 3a 20 |ntent-Encoding: |
<more>
+--------+-------------------------------------------------+----------------+
2014-12-04 22:58:22.887 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.891 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.894 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.895 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.896 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.897 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.900 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.902 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.904 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.905 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.907 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 1024B
2014-12-04 22:58:22.908 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 569B
2014-12-04 22:58:22.933 [nioEventLoopGroup-4-1] DEBUG CLIENT_LOGGING_HANDLER:debug(): [id: 0xeafd0032, /192.168.1.134:57917 => netty.io/104.28.8.44:80] RECEIVED: 945B
2014-12-04 22:58:22.934 [nioEventLoopGroup-4-1] INFO  ClientHandler:messageReceived(): client pipeline handlers: [CLIENT_LOGGING_HANDLER, HttpClientCodec$Decoder#0, HttpClientCodec$Encoder#0, HTTP_CONTENT_AGGREGATOR, CLIENT_HANDLER, DefaultChannelPipeline$TailHandler#0]
2014-12-04 22:58:22.935 [nioEventLoopGroup-4-1] INFO  ClientHandler:messageReceived(): Received HTTP response:
DefaultFullHttpResponse(decodeResult: success)
HTTP/1.1 200 OK
Date: Fri, 05 Dec 2014 06:58:22 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Set-Cookie: __cfduid=dee7f4e30d30e1cd7330cc35e8e0f8c761417762702; expires=Sat, 05-Dec-15 06:58:22 GMT; path=/; domain=.netty.io; HttpOnly
Last-Modified: Thu, 04 Dec 2014 12:12:36 GMT
Expires: Fri, 05 Dec 2014 07:08:22 GMT
Cache-Control: max-age=600
Vary: Accept-Encoding
Server: cloudflare-nginx
CF-RAY: 193e5ad8c3930663-SJC
Content-Encoding: gzip
Content-Length: 13061
2014-12-04 22:58:22.935 [nioEventLoopGroup-4-1] INFO  ServerHandler:writeResponse(): Is FullHttpResponse? true
2014-12-04 22:58:22.936 [nioEventLoopGroup-4-1] DEBUG ServerHandler:writeResponse(): httpObject size? DefaultFullHttpResponse(decodeResult: success)
HTTP/1.1 200 OK
Date: Fri, 05 Dec 2014 06:58:22 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Set-Cookie: __cfduid=dee7f4e30d30e1cd7330cc35e8e0f8c761417762702; expires=Sat, 05-Dec-15 06:58:22 GMT; path=/; domain=.netty.io; HttpOnly
Last-Modified: Thu, 04 Dec 2014 12:12:36 GMT
Expires: Fri, 05 Dec 2014 07:08:22 GMT
Cache-Control: max-age=600
Vary: Accept-Encoding
Server: cloudflare-nginx
CF-RAY: 193e5ad8c3930663-SJC
Content-Encoding: gzip
Content-Length: 13061
2014-12-04 22:58:22.936 [nioEventLoopGroup-4-1] DEBUG ServerHandler:writeResponse(): sent response back to client
2014-12-04 22:58:22.937 [nioEventLoopGroup-3-1] DEBUG SERVER_LOGGING_HANDLER:debug(): [id: 0xad3d76c2, /0:0:0:0:0:0:0:1:57916 => /0:0:0:0:0:0:0:1:10001] WRITE: 499B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d |HTTP/1.1 200 OK.|
|00000010| 0a 44 61 74 65 3a 20 46 72 69 2c 20 30 35 20 44 |.Date: Fri, 05 D|
|00000020| 65 63 20 32 30 31 34 20 30 36 3a 35 38 3a 32 32 |ec 2014 06:58:22|
|00000030| 20 47 4d 54 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 | GMT..Content-Ty|
|00000040| 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c 3b 20 63 |pe: text/html; c|
|00000050| 68 61 72 73 65 74 3d 75 74 66 2d 38 0d 0a 43 6f |harset=utf-8..Co|
|00000060| 6e 6e 65 63 74 69 6f 6e 3a 20 6b 65 65 70 2d 61 |nnection: keep-a|
|00000070| 6c 69 76 65 0d 0a 53 65 74 2d 43 6f 6f 6b 69 65 |live..Set-Cookie|
|00000080| 3a 20 5f 5f 63 66 64 75 69 64 3d 64 65 65 37 66 |: __cfduid=dee7f|
|00000090| 34 65 33 30 64 33 30 65 31 63 64 37 33 33 30 63 |4e30d30e1cd7330c|
|000000a0| 63 33 35 65 38 65 30 66 38 63 37 36 31 34 31 37 |c35e8e0f8c761417|
|000000b0| 37 36 32 37 30 32 3b 20 65 78 70 69 72 65 73 3d |762702; expires=|
|000000c0| 53 61 74 2c 20 30 35 2d 44 65 63 2d 31 35 20 30 |Sat, 05-Dec-15 0|
|000000d0| 36 3a 35 38 3a 32 32 20 47 4d 54 3b 20 70 61 74 |6:58:22 GMT; pat|
|000000e0| 68 3d 2f 3b 20 64 6f 6d 61 69 6e 3d 2e 6e 65 74 |h=/; domain=.net|
|000000f0| 74 79 2e 69 6f 3b 20 48 74 74 70 4f 6e 6c 79 0d |ty.io; HttpOnly.|
|00000100| 0a 4c 61 73 74 2d 4d 6f 64 69 66 69 65 64 3a 20 |.Last-Modified: |
|00000110| 54 68 75 2c 20 30 34 20 44 65 63 20 32 30 31 34 |Thu, 04 Dec 2014|
|00000120| 20 31 32 3a 31 32 3a 33 36 20 47 4d 54 0d 0a 45 | 12:12:36 GMT..E|
|00000130| 78 70 69 72 65 73 3a 20 46 72 69 2c 20 30 35 20 |xpires: Fri, 05 |
|00000140| 44 65 63 20 32 30 31 34 20 30 37 3a 30 38 3a 32 |Dec 2014 07:08:2|
|00000150| 32 20 47 4d 54 0d 0a 43 61 63 68 65 2d 43 6f 6e |2 GMT..Cache-Con|
|00000160| 74 72 6f 6c 3a 20 6d 61 78 2d 61 67 65 3d 36 30 |trol: max-age=60|
|00000170| 30 0d 0a 56 61 72 79 3a 20 41 63 63 65 70 74 2d |0..Vary: Accept-|
|00000180| 45 6e 63 6f 64 69 6e 67 0d 0a 53 65 72 76 65 72 |Encoding..Server|
|00000190| 3a 20 63 6c 6f 75 64 66 6c 61 72 65 2d 6e 67 69 |: cloudflare-ngi|
|000001a0| 6e 78 0d 0a 43 46 2d 52 41 59 3a 20 31 39 33 65 |nx..CF-RAY: 193e|
|000001b0| 35 61 64 38 63 33 39 33 30 36 36 33 2d 53 4a 43 |5ad8c3930663-SJC|
|000001c0| 0d 0a 43 6f 6e 74 65 6e 74 2d 45 6e 63 6f 64 69 |..Content-Encodi|
|000001d0| 6e 67 3a 20 67 7a 69 70 0d 0a 43 6f 6e 74 65 6e |ng: gzip..Conten|
|000001e0| 74 2d 4c 65 6e 67 74 68 3a 20 31 33 30 36 31 0d |t-Length: 13061.|
|000001f0| 0a 0d 0a                                        |...             |
+--------+-------------------------------------------------+----------------+
2014-12-04 22:58:22.937 [nioEventLoopGroup-3-1] DEBUG SERVER_LOGGING_HANDLER:debug(): [id: 0xad3d76c2, /0:0:0:0:0:0:0:1:57916 => /0:0:0:0:0:0:0:1:10001] FLUSH

日志可能不是那么简单,因为我没有粘贴我的所有代码,但我希望你能找到证据,证明代理能够通过浏览器的请求并在上面的日志中从互联网获得响应。从日志的最后一部分,您可以看到收到的Content-Length是13061,但只有499B数据被发送回浏览器。顺便说一下,之后什么也没发生。我对此结果感到困惑,因为在ServerHandler.writeRespone(HttpObject)方法中,我调用了context.writeAndFlush(httpObject)来发送完整的对象。那么,我在这里错过了什么?

更新
由于客户端管道中有HttpObjectAggregator,ClientHandler总是收到FullHttpResponse,这是从这些日志中确认的(从上面复制):

2014-12-04 22:58:22.935 [nioEventLoopGroup-4-1] INFO  ClientHandler:messageReceived(): Received HTTP response:
DefaultFullHttpResponse(decodeResult: success)

1 个答案:

答案 0 :(得分:2)

看起来你只转发收到的邮件的“标题”部分,而不是正文部分(下一个缓冲区)。

但是当你使用HttpObjectAggregator时,它应该是你从客户端获得的FullHttpResponse,因此被发送到服务器。

在Netty中,HTTP消息分为3部分:

  • 标题部分
  • 身体部位(大块)
  • 大块的结尾(空的)

通常情况下,使用HttpObjectAggregator会将所有这些内容合并为一个简单的完整消息。

你能仔细检查你发回的内容是否真的是一个带有正文内容的FullHttpResponse(每一步)?

您是否还在FullHttpResponse上管理了retain()方法,以便客户端在发送缓冲区之前不释放缓冲区?