BHttpRequest: Treat incomplete downloads as error

When BSocket::Read() returns 0, it was treated as
a finished transfer. This is OK when we don't know
the content length, but when we do, there is no reason
not to bubble up the error. Return B_IO_ERROR in this
case.

Change-Id: I68801dbbb85bcfd2e7aa68fd6a9ded6304e82b19
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3621
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Stephan Aßmus 2021-01-10 17:59:14 +01:00 committed by Adrien Destugues
parent bddb122eb4
commit bc1e082b56
2 changed files with 13 additions and 3 deletions

View File

@ -611,8 +611,20 @@ BHttpRequest::_MakeRequest()
if (bytesRead < 0) { if (bytesRead < 0) {
readError = bytesRead; readError = bytesRead;
break; break;
} else if (bytesRead == 0) } else if (bytesRead == 0) {
// Check if we got the expected number of bytes.
// Exceptions:
// - If the content-length is not known (bytesTotal is 0), for
// example in the case of a chunked transfer, we can't know
// - If the request method is "HEAD" which explicitly asks the
// server to not send any data (only the headers)
if (bytesTotal > 0 && bytesReceived != bytesTotal
&& fRequestMethod != B_HTTP_HEAD) {
readError = B_IO_ERROR;
break;
}
receiveEnd = true; receiveEnd = true;
}
fInputBuffer.AppendData(chunk, bytesRead); fInputBuffer.AppendData(chunk, bytesRead);
} else } else

View File

@ -101,7 +101,6 @@ FetchFileJob::Execute()
} }
do { do {
printf("downloading %s\n", DownloadURL());
BUrlRequest* request = BUrlProtocolRoster::MakeRequest(DownloadURL(), BUrlRequest* request = BUrlProtocolRoster::MakeRequest(DownloadURL(),
this); this);
if (request == NULL) if (request == NULL)
@ -112,7 +111,6 @@ FetchFileJob::Execute()
BHttpRequest* http= dynamic_cast<BHttpRequest*>(request); BHttpRequest* http= dynamic_cast<BHttpRequest*>(request);
if (http != NULL && fTargetFile.GetSize(&currentPosition) == B_OK if (http != NULL && fTargetFile.GetSize(&currentPosition) == B_OK
&& currentPosition > 0) { && currentPosition > 0) {
printf("requesting range start %" B_PRIdOFF "\n", currentPosition);
http->SetRangeStart(currentPosition); http->SetRangeStart(currentPosition);
} }