2010-03-19 13 views
8

Estoy tratando de descomprimir una respuesta HTTP GZIP utilizando GZIPInputStream. Sin embargo siempre tengo la misma excepción cuando trato de leer la secuencia: java.util.zip.ZipException: invalid bit length repeatDescomprimir la respuesta GZIPed HTTP en Java

Mi cabecera de petición HTTP:

GET www.myurl.com HTTP/1.0\r\n 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2) Gecko/20100115 Firefox/3.6\r\n 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n 
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3\r\n 
Accept-Encoding: gzip,deflate\r\n 
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7\r\n 
Keep-Alive: 115\r\n 
Connection: keep-alive\r\n 
X-Requested-With: XMLHttpRequest\r\n 
Cookie: Some Cookies\r\n\r\n 

Al final de la cabecera de respuesta HTTP, me sale path=/Content-Encoding: gzip, seguido de la respuesta gziped .

me trataron 2 códigos Similares para descomprimir:

ACTUALIZACIÓN: En los siguientes códigos, tBytes = (the string after 'path=/Content-Encoding: gzip').getBytes();

GZIPInputStream gzip = new GZIPInputStream (new ByteArrayInputStream (tBytes)); 

StringBuffer szBuffer = new StringBuffer(); 

byte tByte [] = new byte [1024]; 

while (true) 
{ 
    int iLength = gzip.read (tByte, 0, 1024); // <-- Error comes here 

    if (iLength < 0) 
     break; 

    szBuffer.append (new String (tByte, 0, iLength)); 
} 

Y éste que tengo en este foro:

InputStream  gzipStream = new GZIPInputStream (new ByteArrayInputStream (tBytes)); 
Reader   decoder = new InputStreamReader (gzipStream, "UTF-8");//<- I tried ISO-8859-1 and get the same exception 
BufferedReader buffered = new BufferedReader (decoder); 

supongo este es un error de codificacion

Saludos,

bill0ute

Respuesta

9

No mostrar cómo obtener la tBytes que se utiliza para establecer el flujo de gzip aquí:

GZIPInputStream gzip = new GZIPInputStream (new ByteArrayInputStream (tBytes)); 

Una explicación es que son incluida la respuesta HTTP completa en tBytes. En cambio, debe ser solo el contenido después de los encabezados HTTP.

Otra explicación es que la respuesta es chunked.

edit: Usted está tomando los datos después de la línea de codificación de contenido como el cuerpo del mensaje. Sin embargo, de acuerdo con la especificación HTTP 1.1, los campos de encabezado no vienen en un orden particular, por lo que esto es muy peligroso.

Como se explica en esta parte de la HTTP specification, el cuerpo del mensaje de una petición o respuesta no viene después de un campo de encabezado en particular, pero después de la primera línea vacía:

Request (sección 5) y los mensajes de respuesta (sección 6) utilizan el formato de mensaje genérico de RFC 822 [9] para entidades de transferencia (la carga de el mensaje). Ambos tipos de mensaje consisten en una línea de inicio, cero o más campos de encabezado (también conocidos como "encabezados"), una línea vacía (es decir, una línea sin nada anterior al CRLF) que indica el final del encabezado campos, y posiblemente un cuerpo del mensaje.

Todavía no has mostrar exactamente cómo componer tBytes, pero en este momento creo que estás erróneamente incluida la línea de vacío en los datos que intenta descomprimir. El cuerpo del mensaje comienza después de los caracteres CRLF de la línea vacía.

¿Puedo sugerirle que use la biblioteca httpclient para extraer el cuerpo del mensaje?

+0

Hi Wim. Gracias por tu respuesta. He actualizado el mensaje para explicar cómo obtengo tBytes. No creo que la respuesta esté fragmentada porque hay un encabezado Content-Length. Pero no estoy seguro. bill0ute – bill0ute

+0

Hola Wim. Estoy tratando de usar el paquete HttpClient pero no puedo encontrar un Java Doc. Solo obtengo los ejemplos. ¿Podría darme un pequeño ejemplo de conexión a un socket y enviar una solicitud de obtención? Gracias – bill0ute

+0

Eche un vistazo al tutorial, es un ejemplo simple para obtener el cuerpo de respuesta para HTTP GET: http://hc.apache.org/httpclient-3.x/tutorial.html En su caso, querrá procesa 'responseBody' como ahora procesas' tBytes'. –

1

Bueno, existe el problema que puedo ver aquí;

int iLength = gzip.read (tByte, 0, 1024); 

Usa lo siguiente para arreglar eso;

 byte[] buff = new byte[1024]; 
byte[] emptyBuff = new byte[1024]; 
          StringBuffer unGzipRes = new StringBuffer(); 

          int byteCount = 0; 
          while ((byteCount = gzip.read(buff, 0, 1024)) > 0) { 
           // only append the buff elements that 
           // contains data 
           unGzipRes.append(new String(Arrays.copyOf(
             buff, byteCount), "utf-8")); 

           // empty the buff for re-usability and 
           // prevent dirty data attached at the 
           // end of the buff 
           System.arraycopy(emptyBuff, 0, buff, 0, 
             1024); 
          } 
Cuestiones relacionadas