getContentLengthLong() == -1 означава, че в наличните метаданни няма известна дължина на съдържанието. Продължете да четете потока и показвайте получените байтове или неопределен напредък; не го третирайте като празен отговор и не заделяйте буфер с отрицателен размер.

long expected = connection.getContentLengthLong();
long received = 0;
byte[] buffer = new byte[8192];
try (InputStream input = connection.getInputStream()) {
    int count;
    while ((count = input.read(buffer)) != -1) {
        output.write(buffer, 0, count);
        received += count;
    }
}

Връзката вече е конфигурирана и output принадлежи на извикващия. Запазете таймаутите за връзка и четене и всяко ограничение за размер на приложението около този цикъл. I/O грешка е неуспешно изтегляне, а не успешно завършване с по-малко байтове.

Сравнявайте дължините на едно и също ниво. Chunked кодирането на HTTP/1.1 може да замени Content-Length и се декодира от HTTP реализацията. Прокси може да го преформулира. Декомпресията също може да направи декодирания брой байтове на приложението различен от кодирания Content-Length.

Ако присъстват и Transfer-Encoding, и Content-Length, не избирайте удобно число: HTTP рамкирането дава приоритет на трансферното кодиране и третира комбинацията като възможна грешка. Оставете този анализ на съответстваща реализация.

FTP URL през HTTP шлюз изисква проверка на конкретното поведение на URLConnection; той не гарантира, че всеки достъп до HTTP заглавка се държи както при обикновен HTTP URL във всяка JDK. Използвайте length API с дълга стойност там, където метаданните са важни, и валидирайте готовия артефакт спрямо действително изискваната дължина или контролна сума. Четенето на тялото не прави предварително отсъстваща заглавка видима.

Подобни статии