getContentLengthLong() == -1 significa que não existe um comprimento de conteúdo conhecido nos metadados disponíveis. Continue a ler o fluxo e mostre os bytes recebidos ou um progresso indeterminado; não o trate como resposta vazia e não aloque um buffer de tamanho negativo.

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

A ligação já está configurada e output pertence ao chamador. Mantenha os tempos limite de ligação e leitura e qualquer limite de tamanho da aplicação em torno deste ciclo. Um erro de E/S é um download falhado, não uma conclusão bem-sucedida com menos bytes.

Compare comprimentos na mesma camada. A codificação chunked de HTTP/1.1 pode substituir Content-Length e é descodificada pela implementação HTTP. Um proxy pode reenquadrá-la. A descompressão também pode fazer com que a contagem de bytes descodificados da aplicação difira de um Content-Length codificado.

Se aparecerem Transfer-Encoding e Content-Length em conjunto, não escolha um número conveniente: o enquadramento HTTP dá precedência à codificação de transferência e trata a combinação como um possível erro. Deixe essa análise para uma implementação conforme.

Um URL FTP através de um gateway HTTP exige verificar o comportamento concreto de URLConnection; não garante que cada acessor de cabeçalho HTTP se comporte como num URL HTTP comum em todas as JDK. Use a API de comprimento com valor longo onde os metadados importam e valide o artefacto concluído face ao comprimento ou à soma de verificação realmente exigidos. Ler o corpo não faz aparecer um cabeçalho que antes faltava.

Artigos relacionados