Завантаження через Java-проксі, коли getContentLengthLong повертає -1
Обробляйте невідомий Content-Length під час завантаження через проксі, не вважаючи відсутність метаданих розміру порожньою відповіддю.
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 належить викликачеві. Зберігайте тайм-аути з'єднання й читання, а також будь-яке обмеження розміру застосунку навколо цього циклу. Помилка вводу-виводу — це невдале завантаження, а не успішне завершення з меншою кількістю байтів.
Порівнюйте довжини на одному рівні. Chunked-кодування HTTP/1.1 може заміняти Content-Length, і його декодує реалізація HTTP. Проксі може переформатувати його. Розпакування також може зробити декодовану кількість байтів застосунку відмінною від закодованого Content-Length.
Якщо присутні і Transfer-Encoding, і Content-Length, не обирайте зручне число: кадрування HTTP надає перевагу транспортному кодуванню й вважає поєднання можливою помилкою. Залиште цей розбір відповідній реалізації.
URL FTP через HTTP-шлюз потребує перевірки конкретної поведінки URLConnection; він не гарантує, що кожен доступ до заголовка HTTP поводиться як на звичайному HTTP URL у кожній JDK. Використовуйте length API з довгим значенням там, де метадані важливі, і перевіряйте готовий артефакт за справді потрібною довжиною або контрольною сумою. Читання тіла не змушує раніше відсутній заголовок з'явитися.