getContentLengthLong() == -1 oznacza, że w dostępnych metadanych nie ma znanej długości treści. Kontynuuj czytanie strumienia i pokazuj odebrane bajty lub nieokreślony postęp; nie traktuj tego jako pustej odpowiedzi i nie przydzielaj bufora o ujemnym rozmiarze.

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;
    }
}

Połączenie jest już skonfigurowane, a output należy do wywołującego. Zachowaj limity czasu połączenia i odczytu oraz ewentualny limit rozmiaru aplikacji wokół tej pętli. Błąd wejścia/wyjścia to nieudane pobieranie, a nie udane zakończenie z mniejszą liczbą bajtów.

Porównuj długości na tej samej warstwie. Kodowanie chunked w HTTP/1.1 może zastąpić Content-Length i jest dekodowane przez implementację HTTP. Proxy może je ponownie zramować. Dekompresja również może sprawić, że zdekodowana liczba bajtów aplikacji będzie różna od zakodowanego Content-Length.

Jeśli występują zarówno Transfer-Encoding, jak i Content-Length, nie wybieraj wygodnej liczby: ramowanie HTTP daje pierwszeństwo kodowaniu transferu i traktuje tę kombinację jako możliwy błąd. Zostaw to parsowanie zgodnej implementacji.

Adres URL FTP przez bramę HTTP wymaga sprawdzenia konkretnego zachowania URLConnection; nie gwarantuje, że każdy dostęp do nagłówka HTTP zachowa się jak przy zwykłym adresie HTTP w każdej JDK. Używaj API długości z wartością long tam, gdzie metadane mają znaczenie, i zweryfikuj gotowy artefakt względem faktycznie wymaganej długości lub sumy kontrolnej. Odczytanie treści nie sprawia, że wcześniej nieobecny nagłówek się pojawi.

Powiązane artykuły