В идеале вы должны использовать высокоуровневую библиотеку, чтобы справиться с этим. Таким образом, всякий раз, когда выпускается новая версия HTTP, администратор библиотеки, надеюсь, сделает всю тяжелую работу за вас, и вам просто потребуется обновленная версия библиотеки.
Кстати, это хорошее упражнение - попробовать сделать это самостоятельно.
Предположим, вы читаете HTTP-ответ в виде потока байтов из сокета TCP. Если бы не было кодировки gzip, то помещение всего ответа в строку могло бы сработать. Однако наличие заголовка « Content-Encoding: gzip » означает, что тело ответа будет (как вы заметили) двоичным.
Вы можете идентифицировать начало тела ответа как первый байт, следующий за первым появлением последовательности строк "\ r \ n \ r \ n" (или 4 байта 0x0d, 0x0a, 0x0d, 0x0a).
Кодировка gzip имеет специальный заголовок, и для этого вам следует проверить первые 3 байта тела:
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();
}
}
Ошибка «Не в формате GZIP» генерируется GZIPInputStream, если первые 3 байта не соответствуют значениям магического заголовка GZIP, поэтому их проверка поможет решить вашу конкретную проблему.
Существует также контрольная сумма CRC в формате GZIP, однако, если она отсутствует или неверна, вы должны увидеть другую ошибку.