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();
|
activeRequest->responseHeadersComplete();
|
||||||
_contentDecoder.initWithRequest(activeRequest);
|
_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) {
|
if (chunkedTransfer) {
|
||||||
setState(STATE_GETTING_CHUNKED);
|
setState(STATE_GETTING_CHUNKED);
|
||||||
} else if (noMessageBody || (bodyTransferSize == 0)) {
|
} else if (noMessageBody || (bodyTransferSize == 0)) {
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ Request::Request(const std::string& url, const std::string method):
|
|||||||
_responseLength(0),
|
_responseLength(0),
|
||||||
_receivedBodyBytes(0),
|
_receivedBodyBytes(0),
|
||||||
_ready_state(UNSENT),
|
_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)
|
void Request::responseHeader(const std::string& key, const std::string& value)
|
||||||
{
|
{
|
||||||
if( key == "connection" ) {
|
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") {
|
} else if (key == "content-length") {
|
||||||
int sz = strutils::to_int(value);
|
int sz = strutils::to_int(value);
|
||||||
setResponseLength(sz);
|
setResponseLength(sz);
|
||||||
@@ -380,6 +384,12 @@ bool Request::closeAfterComplete() const
|
|||||||
return _willClose || (_responseVersion != HTTP_1_1);
|
return _willClose || (_responseVersion != HTTP_1_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool Request::serverSupportsPipelining() const
|
||||||
|
{
|
||||||
|
return (_responseVersion == HTTP_1_1) && !_connectionCloseHeader;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool Request::isComplete() const
|
bool Request::isComplete() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -207,6 +207,13 @@ public:
|
|||||||
bool closeAfterComplete() const;
|
bool closeAfterComplete() const;
|
||||||
bool isComplete() 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:
|
protected:
|
||||||
Request(const std::string& url, const std::string method = "GET");
|
Request(const std::string& url, const std::string method = "GET");
|
||||||
|
|
||||||
@@ -253,6 +260,7 @@ private:
|
|||||||
|
|
||||||
ReadyState _ready_state;
|
ReadyState _ready_state;
|
||||||
bool _willClose;
|
bool _willClose;
|
||||||
|
bool _connectionCloseHeader;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SGSharedPtr<Request> Request_ptr;
|
typedef SGSharedPtr<Request> Request_ptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user