之前的文章理解Https中,介绍了HTTP到HTTPS的演进过程,我们也可以得到一个结论:HTTPS = HTTP + 加密 + 身份认证 + 报文正确性保障。其实也就是在HTTP层和TCP层之间新增一个步骤,通过证书交换通信秘钥并验证客户端服务端身份的合法性(SSL)。所以为了实现HTTPS,必须支持SSL。
为了支持SSL,Java提供了 javax.net.ssl 包,它的SSLContext 和SSLEngine类使得解密和加密相当简单和高效。Netty提供了基于SSLEngine的实现OpenSSL用于支持SSL。OpenSSL工具包比JDK提供的SSLEngine具有更好的性能。
1. SslHandler
Netty通过一个名为SslHandler的ChannelHandler实现HTTPS报文加密和解密的功能,其中SslHandler在内部使用SSLEngine来完成实际的工作,SSLEngine的实现可以是JDK的SSLEngine,也可以是Netty 的OpenSslEngine,这里推荐使用Netty的OpenSslEngine,因为它性能更好,通过SslHandler进行解密和加密的过程如下图所示:
大多数情况下,SslHandler将是ChannelPipeline中的第一个ChannelHandler。这确保了只有在所有其他的ChannelHandler将它们的逻辑应用到数据之后,才会进行加密。
2. HTTP编码器、解码器
Netty为HTTP消息提供了ChannelHandler编码器和解码器:
- HttpRequestEncoder: 编码器,用于客户端,向服务器发送请求
- HttpResponseEecoder: 编码器,用于服务端,向客户端发送响应
- HttpResponseDecoder: 解码器,用于客户端,接收来自服务端的请求
- HttpRequestDecoder:解码器,用于服务端,接收来自客户端的请求
除了独立的编码器、解码器,Netty还提供了编解码器:
- HttpClientCodec: 用于客户端的编解码器,等效于HttpRequestEncoder和HttpResponseDecoder的组合
- HttpServerCodec:用于服务端的编解码器,等效于HttpRequsetDecoder和 HttpResponseEncoder的组合
HttpServerCodec同时实现了ChannelInboundHandler和ChannelOutboundHandler,所以具备服务端编码和解码能力。
3. 聚合器
上述解码器会将每个HTTP消息中生成多个消息对象,如HttpRequest、HttpResponse,HttpContent、LastHttpContent,使用聚合器可以将多个消息体合并为一个FullHttpRequest或者FullHttpResponse消息,便于处理请求和响应。Netty提供了HttpObjectAggregator聚合器完成该工作。