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