]> git.mxchange.org Git - simgear.git/commitdiff
Fix for libCurl pipelining and connection count.
authorJames Turner <zakalawe@mac.com>
Wed, 24 Feb 2016 21:35:54 +0000 (23:35 +0200)
committerJames Turner <zakalawe@mac.com>
Wed, 24 Feb 2016 21:36:25 +0000 (23:36 +0200)
simgear/io/HTTPClient.cxx
simgear/io/HTTPClient.hxx
simgear/io/test_HTTP.cxx
simgear/io/test_HTTP.hxx

index 26ebcb66ebe86617f193f74b68aae113dad0f051..3fec10024617b20c726a4c3da4adc13933a59dec 100644 (file)
@@ -80,6 +80,18 @@ public:
 #if defined(ENABLE_CURL)
     CURLM* curlMulti;
     bool haveActiveRequests;
+
+    void createCurlMulti()
+    {
+        curlMulti = curl_multi_init();
+        // see https://curl.haxx.se/libcurl/c/CURLMOPT_PIPELINING.html
+        // we request HTTP 1.1 pipelining
+        curl_multi_setopt(curlMulti, CURLMOPT_PIPELINING, CURLPIPE_HTTP1);
+        curl_multi_setopt(curlMulti, CURLMOPT_MAX_TOTAL_CONNECTIONS, (long) maxConnections);
+        curl_multi_setopt(curlMulti, CURLMOPT_MAX_PIPELINE_LENGTH,
+                          (long) MAX_INFLIGHT_REQUESTS);
+
+    }
 #else
     NetChannelPoller poller;
 // connections by host (potentially more than one)
@@ -685,7 +697,7 @@ Client::Client() :
       didInitCurlGlobal = true;
     }
 
-    d->curlMulti = curl_multi_init();
+    d->createCurlMulti();
 #endif
 }
 
@@ -704,7 +716,7 @@ void Client::setMaxConnections(unsigned int maxCon)
 
     d->maxConnections = maxCon;
 #if defined(ENABLE_CURL)
-    curl_multi_setopt(d->curlMulti, CURLMOPT_MAXCONNECTS, (long) maxCon);
+    curl_multi_setopt(d->curlMulti, CURLMOPT_MAX_TOTAL_CONNECTIONS, (long) maxCon);
 #endif
 }
 
@@ -818,6 +830,7 @@ void Client::makeRequest(const Request_ptr& r)
     curl_easy_setopt(curlRequest, CURLOPT_HEADERDATA, r.get());
 
     curl_easy_setopt(curlRequest, CURLOPT_USERAGENT, d->userAgent.c_str());
+    curl_easy_setopt(curlRequest, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
 
     if (!d->proxy.empty()) {
       curl_easy_setopt(curlRequest, CURLOPT_PROXY, d->proxy.c_str());
@@ -1119,6 +1132,20 @@ void Client::debugDumpRequests()
 #endif
 }
 
+void Client::clearAllConnections()
+{
+#if defined(ENABLE_CURL)
+    curl_multi_cleanup(d->curlMulti);
+    d->createCurlMulti();
+#else
+    ConnectionDict::iterator it = d->connections.begin();
+    for (; it != d->connections.end(); ++it) {
+        delete it->second;
+    }
+    d->connections.clear();
+#endif
+}
+
 } // of namespace HTTP
 
 } // of namespace simgear
index 5c8d9f6f7269b23e4241c857b27d6d1a1818f995..69ea0f1dc9ba3bae37d60267c22abd5c2f5b4655 100644 (file)
@@ -100,6 +100,8 @@ public:
     uint64_t totalBytesDownloaded() const;
 
     void debugDumpRequests();
+
+    void clearAllConnections();
 private:
     // libCurl callbacks
     static size_t requestWriteCallback(char *ptr, size_t size, size_t nmemb, void *userdata);
index 9ed146f9959f5c21ebe0618403dde650284ad650..39a1d27a228ebeed4922c8d31c5002459159d79e 100644 (file)
@@ -557,7 +557,9 @@ cout << "testing proxy close" << endl;
     cout << "testing HTTP 1.1 pipelining" << endl;
 
     {
-
+        testServer.resetConnectCount();
+        cl.clearAllConnections();
+        
         cl.setProxy("", 80);
         TestRequest* tr = new TestRequest("http://localhost:2000/test1");
         HTTP::Request_ptr own(tr);
@@ -582,6 +584,8 @@ cout << "testing proxy close" << endl;
         COMPARE(tr2->bodyData, string(BODY3));
 
         COMPARE(tr3->bodyData, string(BODY1));
+
+        COMPARE(testServer.connectCount(), 1);
     }
 
 // multiple requests with an HTTP 1.0 server
index 6d8861ed9f8a522e996849be00a9b7bff10207c7..9c75e134b3bd700dc5c9fe927aafe0dcba288d6e 100644 (file)
@@ -174,11 +174,14 @@ template <class T>
 class TestServer : public NetChannel
 {
     simgear::NetChannelPoller _poller;
+    int _connectCount;
 public:
     TestServer()
     {
         Socket::initSockets();
 
+        _connectCount = 0;
+
         open();
         bind(NULL, 2000); // localhost, any port
         listen(16);
@@ -200,12 +203,24 @@ public:
         chan->setHandle(handle);
 
         _poller.addChannel(chan);
+
+        _connectCount++;
     }
 
     void poll()
     {
         _poller.poll();
     }
+
+    void resetConnectCount()
+    {
+        _connectCount = 0;
+    }
+
+    int connectCount()
+    {
+        return _connectCount;
+    }
 };
 
 } // of namespace simgear