SSL 处理因 netty-all-5.0.0.Alpha2 失败,但正在使用 netty-all-5.0.0.Alpha1
SSL handling failed with netty-all-5.0.0.Alpha2, but was working with netty-all-5.0.0.Alpha1
我有一个用netty构建的中间人代理的宠物项目。最初我使用 netty-all-5.0.0.Alpha1 并设法构建用于 SSL 处理的管道。但是,升级到 netty-all-5.0.0.Alpha2 后,同样的 SSL 处理失败了。基本上,当它工作时,我可以将浏览器配置为使用代理并成功加载 https 页面。现在使用 netty-all-5.0.0.Alpha2,浏览器似乎什么也得不到。
以下是我所拥有的 SSL 处理的详细信息。
// server bootstrap
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p
.addLast(SERVER_LOGGING_HANDLER, new LoggingHandler(SERVER_LOGGING_HANDLER))
.addLast(SERVER_HTTP_REQUEST_DECODER, new HttpRequestDecoder())
.addLast(SERVER_HTTP_RESPONSE_ENCODER, new HttpResponseEncoder())
.addLast(HTTP_CONTENT_AGGREGATOR, new HttpObjectAggregator(MAX_HTTP_CONTENT_LENGTH))
.addLast(SERVER_HANDLER, new ServerHandler(ch, portContextManager) );
}
});
// inside ServerHandler
private static final HttpResponse CONNECT_RESPONSE = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
new HttpResponseStatus(200, "Connection established"));
public void channelRead(ChannelHandlerContext context, Object message) throws Exception {
log.debug("server pipeline handlers: " + context.pipeline().names());
if (message instanceof FullHttpRequest) {
FullHttpRequest request = (FullHttpRequest) message;
if (request.method() == HttpMethod.CONNECT) {
context.write(CONNECT_RESPONSE);
log.debug("responded CONNECT method with {}", CONNECT_RESPONSE);
context.pipeline().remove(SERVER_HTTP_REQUEST_DECODER);
context.pipeline().remove(SERVER_HTTP_RESPONSE_ENCODER);
context.pipeline().addBefore(HTTP_CONTENT_AGGREGATOR, SERVER_SSL_HANDLER, createServerSslHandler());
context.pipeline().addBefore(HTTP_CONTENT_AGGREGATOR, HTTP_SERVER_CODEC, new HttpServerCodec());
return;
}
log.debug("Received HTTP request:\n{}", request);
chain.processRequest(request);
} else {
throw new Exception("Only FullHttpRequest is supported");
}
}
private SslHandler createServerSslHandler() {
try {
SSLContext context = SslContextFactory.createServerSslContext();
SSLEngine engine = context.createSSLEngine();
engine.setUseClientMode(false);
return new SslHandler(engine);
} catch (Exception e) {
log.error("Failed to create SslHandler with exception:", e);
return null;
}
}
对于 netty-all-5.0.0.Alpha2,此后 LoggingHandler 没有任何内容:
2015-03-28 17:46:39.206 [nioEventLoopGroup-1-0] DEBUG SERVER_LOGGING_HANDLER#debug(): [id: 0x1b8d61d1, /0:0:0:0:0:0:0:1:63483 => /0:0:0:0:0:0:0:1:7000] WRITE: 39B
+-------------------------------------------------+
| 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 43 6f 6e |HTTP/1.1 200 Con|
|00000010| 6e 65 63 74 69 6f 6e 20 65 73 74 61 62 6c 69 73 |nection establis|
|00000020| 68 65 64 0d 0a 0d 0a |hed.... |
+--------+-------------------------------------------------+----------------+
那么,在 SSL 处理方面从 5.0.0.Alpha1 到 5.0.0.Alpha2 发生了什么变化?我怎样才能使 SSL 处理再次工作?
更新
我现在设法让它再次工作。我唯一的变化是在响应初始 CONNECT
请求时使用 writeAndFlush()
而不是 write()
。也就是说,现在我有:
context.writeAndFlush(CONNECT_RESPONSE);
不过,我还是想明白为什么。另一件让我感到困惑的事情是我必须删除
中的初始 http 编解码器
context.pipeline().remove(SERVER_HTTP_REQUEST_DECODER);
context.pipeline().remove(SERVER_HTTP_RESPONSE_ENCODER);
并添加一组新的编解码器以使 SSL 处理正常工作。有人可以解释为什么吗?
在 Netty 4 中,write()
操作只是将写入请求放入每个通道的队列中。 flush()
操作实际上告诉 Netty 将每个通道队列中的写请求写入套接字。
在旧版本的 Netty 4 中,SslHandler
有一个错误,它会自动刷新每个写入请求,最近已修复。这可能是您的旧代码不再起作用了。 (我们的错误修复揭示了您代码中隐藏的错误。)
我有一个用netty构建的中间人代理的宠物项目。最初我使用 netty-all-5.0.0.Alpha1 并设法构建用于 SSL 处理的管道。但是,升级到 netty-all-5.0.0.Alpha2 后,同样的 SSL 处理失败了。基本上,当它工作时,我可以将浏览器配置为使用代理并成功加载 https 页面。现在使用 netty-all-5.0.0.Alpha2,浏览器似乎什么也得不到。
以下是我所拥有的 SSL 处理的详细信息。
// server bootstrap
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p
.addLast(SERVER_LOGGING_HANDLER, new LoggingHandler(SERVER_LOGGING_HANDLER))
.addLast(SERVER_HTTP_REQUEST_DECODER, new HttpRequestDecoder())
.addLast(SERVER_HTTP_RESPONSE_ENCODER, new HttpResponseEncoder())
.addLast(HTTP_CONTENT_AGGREGATOR, new HttpObjectAggregator(MAX_HTTP_CONTENT_LENGTH))
.addLast(SERVER_HANDLER, new ServerHandler(ch, portContextManager) );
}
});
// inside ServerHandler
private static final HttpResponse CONNECT_RESPONSE = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
new HttpResponseStatus(200, "Connection established"));
public void channelRead(ChannelHandlerContext context, Object message) throws Exception {
log.debug("server pipeline handlers: " + context.pipeline().names());
if (message instanceof FullHttpRequest) {
FullHttpRequest request = (FullHttpRequest) message;
if (request.method() == HttpMethod.CONNECT) {
context.write(CONNECT_RESPONSE);
log.debug("responded CONNECT method with {}", CONNECT_RESPONSE);
context.pipeline().remove(SERVER_HTTP_REQUEST_DECODER);
context.pipeline().remove(SERVER_HTTP_RESPONSE_ENCODER);
context.pipeline().addBefore(HTTP_CONTENT_AGGREGATOR, SERVER_SSL_HANDLER, createServerSslHandler());
context.pipeline().addBefore(HTTP_CONTENT_AGGREGATOR, HTTP_SERVER_CODEC, new HttpServerCodec());
return;
}
log.debug("Received HTTP request:\n{}", request);
chain.processRequest(request);
} else {
throw new Exception("Only FullHttpRequest is supported");
}
}
private SslHandler createServerSslHandler() {
try {
SSLContext context = SslContextFactory.createServerSslContext();
SSLEngine engine = context.createSSLEngine();
engine.setUseClientMode(false);
return new SslHandler(engine);
} catch (Exception e) {
log.error("Failed to create SslHandler with exception:", e);
return null;
}
}
对于 netty-all-5.0.0.Alpha2,此后 LoggingHandler 没有任何内容:
2015-03-28 17:46:39.206 [nioEventLoopGroup-1-0] DEBUG SERVER_LOGGING_HANDLER#debug(): [id: 0x1b8d61d1, /0:0:0:0:0:0:0:1:63483 => /0:0:0:0:0:0:0:1:7000] WRITE: 39B
+-------------------------------------------------+
| 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 43 6f 6e |HTTP/1.1 200 Con|
|00000010| 6e 65 63 74 69 6f 6e 20 65 73 74 61 62 6c 69 73 |nection establis|
|00000020| 68 65 64 0d 0a 0d 0a |hed.... |
+--------+-------------------------------------------------+----------------+
那么,在 SSL 处理方面从 5.0.0.Alpha1 到 5.0.0.Alpha2 发生了什么变化?我怎样才能使 SSL 处理再次工作?
更新
我现在设法让它再次工作。我唯一的变化是在响应初始 CONNECT
请求时使用 writeAndFlush()
而不是 write()
。也就是说,现在我有:
context.writeAndFlush(CONNECT_RESPONSE);
不过,我还是想明白为什么。另一件让我感到困惑的事情是我必须删除
中的初始 http 编解码器 context.pipeline().remove(SERVER_HTTP_REQUEST_DECODER);
context.pipeline().remove(SERVER_HTTP_RESPONSE_ENCODER);
并添加一组新的编解码器以使 SSL 处理正常工作。有人可以解释为什么吗?
在 Netty 4 中,write()
操作只是将写入请求放入每个通道的队列中。 flush()
操作实际上告诉 Netty 将每个通道队列中的写请求写入套接字。
在旧版本的 Netty 4 中,SslHandler
有一个错误,它会自动刷新每个写入请求,最近已修复。这可能是您的旧代码不再起作用了。 (我们的错误修复揭示了您代码中隐藏的错误。)