画像は高速な直接接続では正常に表示されますが、より遅いフォワードプロキシ経由では不完全になります。考えられる原因の一つは、レスポンスをまだ書き込んでいる最中にオリジンが接続を閉じることです。

Netty の I/O は非同期です。writeAndFlush から戻ったことは、その操作が完了したことを意味しません。そのため、まだキューにバイトが残っているレスポンスに対してこの順序は安全ではありません。

ctx.writeAndFlush(response);
ctx.close();

HTTP 交換を最後のレスポンスメッセージの後に意図的に閉じる場合は、クローズをその書き込みの future に接続します。

ctx.writeAndFlush(finalResponseMessage)
    .addListener(ChannelFutureListener.CLOSE);

この断片は、レスポンスがすでに正しく構築されフレーミングされていることを前提としています。ストリーミングされたボディでは、ヘッダーの書き込みではなく最後のメッセージの完了を使います。持続的な HTTP 接続では、レスポンスが終わったというだけでクローズを追加しないでください。

future の失敗を、アプリケーションの通常のエラー処理の一部として調べます。完了には失敗とキャンセルが含まれるため、完了だけではブラウザからの配信確認にはなりません。

有用な比較は、各経路での完全なレスポンス長と書き込み結果です。プロキシはタイミングを変えて既存のライフサイクルエラーを露呈させることがありますが、その存在はプロキシの圧縮器やキャッシュがバイトを破棄したことを証明しません。

関連記事