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:
@@ -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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user