Parse multiple HTTP at once

Instead of relying on the global protocol loop to call _ParseHeaders
once for each header, extract as much as possible from the current
buffer.

This saves memory, avoids useless operations on the socket and various
processing steps, and fixes #10245.

Also improve the handling of 0-size requests to make sure they terminate
properly.
This commit is contained in:
Adrien Destugues
2014-07-16 17:34:31 +02:00
parent 8f367d30c8
commit 3528905be6
+15 -14
View File
@@ -653,7 +653,7 @@ BHttpRequest::_MakeRequest()
if (index != B_ERROR) if (index != B_ERROR)
bytesTotal = atoi(fHeaders.HeaderAt(index).Value()); bytesTotal = atoi(fHeaders.HeaderAt(index).Value());
else else
bytesTotal = 0; bytesTotal = -1;
} }
} }
@@ -731,7 +731,7 @@ BHttpRequest::_MakeRequest()
} }
} }
if (bytesRead > 0) { if (bytesRead >= 0) {
bytesReceived += bytesRead; bytesReceived += bytesRead;
if (fListener != NULL) { if (fListener != NULL) {
@@ -749,15 +749,15 @@ BHttpRequest::_MakeRequest()
size); size);
bytesUnpacked += size; bytesUnpacked += size;
} }
} else { } else if (bytesRead > 0) {
fListener->DataReceived(this, inputTempBuffer, fListener->DataReceived(this, inputTempBuffer,
bytesReceived - bytesRead, bytesRead); bytesReceived - bytesRead, bytesRead);
} }
fListener->DownloadProgress(this, bytesReceived, fListener->DownloadProgress(this, bytesReceived,
bytesTotal); std::max((ssize_t)0, bytesTotal));
} }
if (bytesTotal > 0 && bytesReceived >= bytesTotal) { if (bytesTotal >= 0 && bytesReceived >= bytesTotal) {
receiveEnd = true; receiveEnd = true;
if (decompress) { if (decompress) {
@@ -854,17 +854,18 @@ void
BHttpRequest::_ParseHeaders() BHttpRequest::_ParseHeaders()
{ {
BString currentHeader; BString currentHeader;
if (_GetLine(currentHeader) == B_ERROR) while (_GetLine(currentHeader) != B_ERROR)
return; {
// An empty line means the end of the header section
if (currentHeader.Length() == 0) {
fRequestStatus = kRequestHeadersReceived;
return;
}
// An empty line means the end of the header section _EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_IN, "%s",
if (currentHeader.Length() == 0) { currentHeader.String());
fRequestStatus = kRequestHeadersReceived; fHeaders.AddHeader(currentHeader.String());
return;
} }
_EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_IN, "%s", currentHeader.String());
fHeaders.AddHeader(currentHeader.String());
} }