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:
James Turner
2016-03-22 20:06:22 +00:00
parent 2438dd8a08
commit 714a6ac47d
3 changed files with 25 additions and 2 deletions

View File

@@ -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)) {

View File

@@ -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
{

View File

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