Idealmente, debe utilizar una biblioteca de alto nivel para manejar estas cosas por usted. De esta forma, cada vez que se lanza una nueva versión de HTTP, el mantenedor de la biblioteca con suerte hace todo el trabajo por usted y solo necesita la versión actualizada de la biblioteca.
Aparte de eso, es un buen ejercicio intentar hacerlo usted mismo.
Supongamos que está leyendo una Respuesta HTTP como una secuencia de bytes desde un socket TCP. Si no hubiera codificación gzip, entonces poner toda la respuesta en una Cadena podría funcionar. Sin embargo, la presencia de un encabezado "Content-Encoding: gzip" significa que el cuerpo de la respuesta será (como usted notó) binario.
Puede identificar el inicio del cuerpo de respuesta como el primer byte después de la primera aparición de la secuencia de cadenas "\ r \ n \ r \ n" (o los 4 bytes 0x0d, 0x0a, 0x0d, 0x0a).
La codificación gzip tiene una cabecera especial, y usted debe probar los 3 primeros bytes del cuerpo para ello:
byte[] buf; // from the HTTP Response stream
// ... insert code here to populate buf from HTTP Response stream
// ...
int bodyLen = 1234; // populate this value from 'Content-length' header
int bodyStart = 123; // index of byte buffer where body starts
if (bodyLen > 4 && buf[bodyStart] == 0x1f && buf[bodyStart + 1] == (byte) 0x8b && buf[bodyStart + 2] == 0x08) {
// gzip compressed body
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
if (bodyStart > 0) bais.skip(bodyStart);
// Decompress the bytes
byte[] decompressedBytes = new byte[bodyLen * 4];
int decompressedDataLength = 0;
try {
// note: replace this try-catch with try-with-resources here where possible
GZIPInputStream gzis = new GZIPInputStream(bais);
decompressedDataLength = gzis.read(decompressedBytes);
gzis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
El "no en formato GZIP" error se produce por GZIPInputStream si los primeros 3 bytes no lo hacen haga coincidir los valores mágicos del encabezado GZIP, por lo que probarlos ayudará a resolver su problema en particular.
También hay una suma de comprobación CRC dentro del formato GZIP; sin embargo, si eso falta o es incorrecto, debería aparecer un error diferente.
Estoy tratando de analizar una respuesta HTTP donde el cuerpo de la respuesta se comprime con GZip. Sin embargo, toda la respuesta simplemente se almacena en una cadena, por lo que parte de la cadena contiene caracteres binarios. ¿Estás diciendo que no es posible convertir esta "cadena GZip" en una cadena de texto? – Matt
@Matt: para empezar, no debe almacenar la respuesta en una cadena. Si es binario, no debería estar en ningún texto, a menos que sea base64. El concepto de "parte de la cadena contiene datos binarios" realmente no funciona. Parece que necesitas cambiar tu enfoque. –
La respuesta se presenta inicialmente como un byte [], así que eso es todo lo que tengo disponible. ¿Podría usar esto? – Matt