]> git.mxchange.org Git - simgear.git/commitdiff
Disable HTTP pipelining if the connection closes.
authorJames Turner <zakalawe@mac.com>
Tue, 22 Mar 2016 20:06:22 +0000 (20:06 +0000)
committerJames Turner <zakalawe@mac.com>
Tue, 22 Mar 2016 20:06:22 +0000 (20:06 +0000)
Don’t keep attempting to pipeline if the next server sets Close on
its response, since this just generates needless overhead.

simgear/io/HTTPClient.cxx
simgear/io/HTTPRequest.cxx
simgear/io/HTTPRequest.hxx

index 39d0367966cf265347ab23cb44550ad37748eada..d42519d8b9af017c4b1f86da1ce46c934d490116 100644 (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)) {
index 3050cbf4e9594a693f0aeb18e797fdd6783fb04c..c9d82d29bac131c320604cd3139ba8f40f0068a0 100644 (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
 {
index 9182ed3703c6988fbc68bc358085ee47dde3acf1..cc7ffd28dcb2b713f9f9ad0f02b25788ce9109d7 100644 (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;