HttpServerCodec和HttpObjectAggregator如何解析Http协议

本文介绍了Netty中HttpServerCodec与HttpObjectAggregator如何解析Http协议。HttpServerCodec包含HttpRequestDecoder和HttpResponseEncoder,用于HTTP请求和响应的解码和编码。HttpRequestDecoder解析HTTP请求,HttpObjectDecoder处理ByteBuf,转换成HttpMessages和HttpContents。HttpObjectAggregator用于聚合多个HttpContent对象,避免内存消耗。ReplayingDecoder允许在非阻塞I/O范式中实现阻塞解码器。文章深入探讨了这些组件的工作原理和实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、首先开始看HttpServerCodec

可以看到他继承了ChannelHandlerAppender,并且创建了一个HttpRequestDecode和一个HttpResponseEncoder。

Appender内部有一个Entry的list按顺序存放这两个编码解码器

ps:在initchannelhandler时,添加的是HttpServerCode,查看addLast方法代码,也没有发现将这两个编码解码器add在pipeline里面了,是不是在处理是有判断handler是否是一个appender,是的话依次调用list<entry>里的handler。

针对上面的问题,先留着,先看看httprequestencode的代码

 

2、HttpRequestDecode的处理

对于http的request请求,协议如下

对于基于tcp的协议,底层拿到的字节流需要按照上层的协议格式去解析字节流。

再来看一下HttpRequestDecode的类层次图

 

2.1 HttpRequestDecoder类

比较简单,就是调用父类的构造方法,然后增加了以下方法

2.2 HttpObjectDecoder类

比较复杂,看一下官方api的解释

public abstract class HttpObjectDecoder extends ByteToMessageDecoder

Decodes ByteBufs into HttpMessages and HttpContents.

将bytebuf编码成为HttpMessages和HttpContents对象

Parameters that prevents excessive memory consumption

防止过多内存消耗的参数

Name

Meaning

maxInitialLineLength

The maximum length of the initial line (e.g. "GET / HTTP/1.0" or "HTTP/1.0 200 OK") If the length of the initial line exceeds this value, a TooLongFrameException will be raised.

maxHeaderSize

The maximum length of all headers. If the sum of the length of each header exceeds this value, a TooLongFrameException will be raised.

maxChunkSize

The maximum length of the content or each chunk. If the content length (or the length of each chunk) exceeds this value, the content or chunk will be split into multiple HttpContents whose length is maxChunkSize at maximum.

maxInittialLineLength 初始行例如:"GET / HTTP/1.0" or "HTTP/1.0 200 OK"的最大长度

maxHeaderSize 所有headers的长度

maxChunkSize content或者一个chunk的最大长度

Chunked Content

If the content of an HTTP message is greater than maxChunkSize or the transfer encoding of the HTTP message is

如果一个http消息的content(内容)大于maxChunkSize或者chunked(http消息传输的编码)

'chunked', this decoder generates one HttpMessage instance and its following HttpContents per single HTTP

这个解码器生成一个HttpMessage 实例,在一个http消息里它可能伴随多个HttpContent,为了避免过多的内存消耗

message to avoid excessive memory consumption. For example, the following HTTP message:

 GET / HTTP/1.1  Transfer-Encoding: chunked   1a  abcdefghijklmnopqrstuvwxyz  10  1234567890abcdef  0  Content-MD5: ...  [blank line] 

triggers HttpRequestDecoder to generate 3 objects:

引发HttpRequestDecoder生成3个对象

  1. An HttpRequest,
  2. The first HttpContent whose content is 'abcdefghijklmnopqrstuvwxyz',
  3. The second LastHttpContent whose conte
Android Netty是一个高性能的网络通信框架,它允许开发者在Android平台上构建基于TCPUDP协议的应用程序。对于HTTP反代服务,Netty可以用来创建一个HTTP代理服务器,它能够接收客户端发送的HTTP请求,然后转发到指定的目标服务器,并将响应返回给客户端。 在Netty中,你可以通过以下几个步骤设置一个基本的HTTP反代理服务: 1. **初始化ServerBootstrap**:首先,你需要创建一个`ServerBootstrap`实例并配置它用于监听HTTP连接。 ```java EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try (ServerBootstrap b = new ServerBootstrap()) { b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { // 创建一个HttpServerCodecHttpObjectAggregator ch.pipeline().addLast(new HttpServerCodec()); ch.pipeline().addLast(new HttpObjectAggregator(8192)); // 自定义handler处理HTTP请求响应 ch.pipeline().addLast(new HttpClientHandler()); } }); } ``` 2. **HttpClientHandler**:这是关键部分,其中包含了转发请求的功能。你可以在这里读取请求、解析URL,建立到目标服务器的连接,发送请求,然后读取并返回响应。 ```java class HttpClientHandler extends ChannelInboundHandlerAdapter { private HttpClient httpClient; @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // 初始化httpClient httpClient = new HttpClient(); } @Override public void channelRead0(ChannelHandlerContext ctx, Object msg) { FullHttpRequest request = (FullHttpRequest) msg; // 转发请求到目标服务器 HttpResponseFuture responseFuture = httpClient.submit(request); responseFuture.whenComplete((response, error) -> { if (error == null) { ByteBuf content = response.content(); // 编码响应并写回给客户端 ByteBuf encodedResponse = encodeResponse(response, content.readableBytes()); ctx.write(encodedResponse); } else { logError("Failed to forward request: {}", error.getMessage()); } }); } // ...编码响应内容等方法... } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值