perl - habilitar - accept-encoding gzip deflate
Comprimir la solicitud HTTP con LWP, Apache y mod_deflate (3)
Aunque dijiste que no querías hacer la compresión tú mismo, hay muchos módulos perl que te harán las dos cosas, Compress :: Zlib, por ejemplo.
Tengo un truco (con una parte de .net de la compañía) donde me pasan XML como un parámetro separado publicado en, y luego puedo manejarlo como si fuera una cadena en lugar de meramente con cosas como SOAP.
Tengo un sistema cliente / servidor que realiza la comunicación utilizando XML transferido mediante solicitudes HTTP y respuestas con el cliente que utiliza Perl''s LWP y el servidor que ejecuta Perl''s CGI.pm a través de Apache. Además, el flujo se cifra con SSL con certificados tanto para el servidor como para todos los clientes.
Este sistema funciona bien, excepto que periódicamente el cliente necesita enviar grandes cantidades de datos. Una solución obvia sería comprimir los datos del lado del cliente, enviarlos y descomprimirlos en el servidor. En lugar de implementarlo yo mismo, esperaba usar la "Descompresión de entrada" mod_deflate de Apache como se describe aquí .
La descripción advierte:
Si evalúa usted mismo el cuerpo de la solicitud, ¡no confíe en el encabezado Content-Length! El encabezado Content-Length refleja la longitud de los datos entrantes del cliente y no el número de bytes de la secuencia de datos descomprimida.
Entonces, si proporciono un valor de Longitud del contenido que coincida con el tamaño de los datos comprimidos, los datos se truncarán. Esto se debe a que mod_deflate descomprime la secuencia, pero CGI.pm solo lee el límite de longitud del contenido.
Alternativamente, si trato de ser más astuto y anular el encabezado Content-Length con el tamaño de datos descomprimido, LWP se queja y restablece el valor a la longitud comprimida, dejándome con el mismo problema.
Finalmente, intenté hackear la parte de LWP que hace la corrección. El código original es:
# 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'');
}
Y cambié la línea de inserción a:
push(@h, ''Content-Length'' => $clen);
Lamentablemente, esto causa algún problema cuando el contenido (truncado o no) ni siquiera llega a mi script CGI.
¿Alguien ha hecho esto? Encontré esto que comprime en un archivo antes de cargarlo, pero no comprime una solicitud genérica.
No creo que puedas cambiar la longitud del contenido así. Confundiría Apache, porque mod_deflate no sabría la cantidad de datos comprimidos para leer. ¿Qué tal si el cliente agrega un encabezado X-Uncompressed-Length y luego usa una versión modificada de CGI.pm que usa X-Uncompressed-Length (si está presente) en lugar de Content-Length? (En realidad, probablemente no necesite modificar CGI.pm. Simplemente configure $ENV{''CONTENT_LENGTH''}
con el valor apropiado antes de inicializar el objeto CGI o llamar a cualquier función CGI).
O bien, use un módulo de nivel inferior que use la brigada de cubeta para indicar la cantidad de datos que debe leer.
No estoy seguro de si te estoy siguiendo con lo que quieres, pero tengo un módulo personalizado de obtención / publicación, que utilizo para hacer algunas cosas no estándar. El siguiente código leerá cualquier cosa enviada por correo postal o STDIN.
read(STDIN, $query_string, $ENV{''CONTENT_LENGTH''});
En lugar de usar el valor de $ ENV, use su. Espero que esto ayude, y lo siento si no es así.