通过代理出现不完整图片:检查 Netty 的写入完成
当图片经代理传输后不完整时,检查源站是否在异步响应写入完成之前关闭了 Netty 通道。
一张图片在快速的直接连接上正常,但经过较慢的转发代理后却不完整。一个可能的原因是,源站在响应仍在写入时关闭了连接。
Netty 的 I/O 是异步的。从 writeAndFlush 返回并不意味着该操作已经完成。因此,对于仍有排队字节的响应,这种顺序并不安全:
ctx.writeAndFlush(response);
ctx.close();
当 HTTP 交换在最后一条响应消息之后有意关闭时,将关闭动作挂到那次写入的 future 上:
ctx.writeAndFlush(finalResponseMessage)
.addListener(ChannelFutureListener.CLOSE);
该片段假设响应已经正确构建并分帧。对于流式正文,应使用其最后一条消息的完成,而不是头部的写入。对于持久 HTTP 连接,不要仅仅因为一个响应结束就添加关闭。
作为应用程序常规错误处理的一部分,检查 future 的失败。完成包含失败与取消,因此仅凭完成并不能作为浏览器的送达回执。
有用的比较是每条路径上的完整响应长度和写入结果。代理可以改变时序,从而暴露出既有的生命周期错误;它的存在并不能证明其压缩器或缓存丢弃了字节。