Disable HTTP pipelining if the connection closes.
Don’t keep attempting to pipeline if the next server sets Close on its response, since this just generates needless overhead.
This commit is contained in:
@@ -651,6 +651,11 @@ private:
|
||||
activeRequest->responseHeadersComplete();
|
||||
_contentDecoder.initWithRequest(activeRequest);
|
||||
|
||||
if (!activeRequest->serverSupportsPipelining()) {
|
||||
SG_LOG(SG_IO, SG_DEBUG, _connectionId << " disabling pipelining since server does not support it");
|
||||
_maxPipelineLength = 1;
|
||||
}
|
||||
|
||||
if (chunkedTransfer) {
|
||||
setState(STATE_GETTING_CHUNKED);
|
||||
} else if (noMessageBody || (bodyTransferSize == 0)) {
|
||||
|
||||
@@ -39,7 +39,8 @@ Request::Request(const std::string& url, const std::string method):
|
||||
_responseLength(0),
|
||||
_receivedBodyBytes(0),
|
||||
_ready_state(UNSENT),
|
||||
_willClose(false)
|
||||
_willClose(false),
|
||||
_connectionCloseHeader(false)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -147,7 +148,10 @@ void Request::responseStart(const std::string& r)
|
||||
void Request::responseHeader(const std::string& key, const std::string& value)
|
||||
{
|
||||
if( key == "connection" ) {
|
||||
_willClose = (value.find("close") != std::string::npos);
|
||||
_connectionCloseHeader = (value.find("close") != std::string::npos);
|
||||
// track willClose seperately because other conditions (abort, for
|
||||
// example) can also set it
|
||||
_willClose = _connectionCloseHeader;
|
||||
} else if (key == "content-length") {
|
||||
int sz = strutils::to_int(value);
|
||||
setResponseLength(sz);
|
||||
@@ -380,6 +384,12 @@ bool Request::closeAfterComplete() const
|
||||
return _willClose || (_responseVersion != HTTP_1_1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Request::serverSupportsPipelining() const
|
||||
{
|
||||
return (_responseVersion == HTTP_1_1) && !_connectionCloseHeader;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool Request::isComplete() const
|
||||
{
|
||||
|
||||
@@ -207,6 +207,13 @@ public:
|
||||
bool closeAfterComplete() const;
|
||||
bool isComplete() const;
|
||||
|
||||
/**
|
||||
* Check if the server response indicates pipelining should be continued.
|
||||
* Currently tests that HTTP_1_1 is explicitly supported, and that the
|
||||
* server/proxy did not request Connection: close
|
||||
*/
|
||||
bool serverSupportsPipelining() const;
|
||||
|
||||
protected:
|
||||
Request(const std::string& url, const std::string method = "GET");
|
||||
|
||||
@@ -253,6 +260,7 @@ private:
|
||||
|
||||
ReadyState _ready_state;
|
||||
bool _willClose;
|
||||
bool _connectionCloseHeader;
|
||||
};
|
||||
|
||||
typedef SGSharedPtr<Request> Request_ptr;
|
||||
|
||||
Reference in New Issue
Block a user