У меня есть система клиент / сервер, которая осуществляет связь с использованием XML, передаваемого с использованием HTTP-запросов и ответов, с клиентом с использованием LWP Perl и сервером, на котором выполняется CGI.pm в Perl через Apache. Кроме того, поток шифруется с использованием SSL с сертификатами как для сервера, так и для всех клиентов.
Эта система работает хорошо, за исключением того, что периодически клиенту необходимо отправлять действительно большие объемы данных. Очевидным решением будет сжатие данных на стороне клиента, их передача и распаковка на сервере. Вместо того, чтобы реализовывать это самостоятельно, я надеялся использовать «декомпрессию ввода» Apache mod_deflate, как описано здесь .
Описание предупреждает:
Если вы оцениваете тело запроса самостоятельно, не доверяйте заголовку Content-Length! Заголовок Content-Length отражает длину входящих данных от клиента, а не количество байтов потока распакованных данных.
Так что, если я предоставлю значение Content-Length, соответствующее размеру сжатых данных, данные будут обрезаны. Это происходит потому, что mod_deflate распаковывает поток, но CGI.pm читает только до предела длины содержимого.
В качестве альтернативы, если я попытаюсь перехитрить его и переопределить заголовок 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-скрипт.
Кто-нибудь сделал эту работу? Я нашел this , который выполняет сжатие файла перед загрузкой, но не сжимает общий запрос.