Perl の LWP を使用するクライアントと、Apache を介して Perl の CGI.pm を実行するサーバーとの間で、HTTP 要求と応答を使用して転送される XML を使用して通信を行うクライアント/サーバー システムがあります。さらに、ストリームは、サーバーとすべてのクライアントの両方の証明書で SSL を使用して暗号化されます。
このシステムは、クライアントが非常に大量のデータを定期的に送信する必要があることを除けば、うまく機能します。明らかな解決策は、クライアント側でデータを圧縮して送信し、サーバーで解凍することです。これを自分で実装するのではなく、ここで説明されているように、Apache の mod_deflate の「入力圧縮解除」を使用したいと考えていました。
説明では次のように警告されています。
リクエスト本文を自分で評価する場合は、Content-Length ヘッダーを信用しないでください。Content-Length ヘッダーは、解凍されたデータ ストリームのバイト数ではなく、クライアントからの受信データの長さを反映します。
そのため、圧縮されたデータ サイズに一致する Content-Length 値を指定すると、データが切り捨てられます。これは、mod_deflate がストリームを圧縮解除するためですが、CGI.pm は Content-Length 制限までしか読み取らないためです。
あるいは、それを裏切って Content-Length ヘッダーを圧縮解除されたデータ サイズで上書きしようとすると、LWP は文句を言って値を圧縮された長さにリセットし、同じ問題が発生します。
最後に、修正を行う LWP の部分をハッキングしてみました。元のコードは次のとおりです。
# Set (or override) Content-Length header
my $clen = $request_headers->header('Content-Length');
if (defined($$content_ref) && length($$content_ref)) {
$has_content = length($$content_ref);
if (!defined($clen) || $clen ne $has_content) {
if (defined $clen) {
warn "Content-Length header value was wrong, fixed";
hlist_remove(\@h, 'Content-Length');
}
push(@h, 'Content-Length' => $has_content);
}
}
elsif ($clen) {
warn "Content-Length set when there is no content, fixed";
hlist_remove(\@h, 'Content-Length');
}
そして、プッシュラインを次のように変更しました:
push(@h, 'Content-Length' => $clen);
残念ながら、これにより、コンテンツ (切り捨てられているかどうかにかかわらず) が CGI スクリプトに到達しないという問題が発生します。
誰かがこれを機能させましたか?アップロードする前にファイルを圧縮するが、一般的なリクエストを圧縮しないこれを見つけました。