From: James Turner Date: Tue, 22 Mar 2016 20:06:22 +0000 (+0000) Subject: Disable HTTP pipelining if the connection closes. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=714a6ac47dc87f5d8d873644b8dfff05277726ec;p=simgear.git 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. --- diff --git a/simgear/io/HTTPClient.cxx b/simgear/io/HTTPClient.cxx index 39d03679..d42519d8 100644 --- a/simgear/io/HTTPClient.cxx +++ b/simgear/io/HTTPClient.cxx @@ -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)) { diff --git a/simgear/io/HTTPRequest.cxx b/simgear/io/HTTPRequest.cxx index 3050cbf4..c9d82d29 100644 --- a/simgear/io/HTTPRequest.cxx +++ b/simgear/io/HTTPRequest.cxx @@ -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 { diff --git a/simgear/io/HTTPRequest.hxx b/simgear/io/HTTPRequest.hxx index 9182ed37..cc7ffd28 100644 --- a/simgear/io/HTTPRequest.hxx +++ b/simgear/io/HTTPRequest.hxx @@ -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_ptr;