diff --git a/simgear/io/HTTPClient.cxx b/simgear/io/HTTPClient.cxx index 26ebcb66..3fec1002 100644 --- a/simgear/io/HTTPClient.cxx +++ b/simgear/io/HTTPClient.cxx @@ -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 diff --git a/simgear/io/HTTPClient.hxx b/simgear/io/HTTPClient.hxx index 5c8d9f6f..69ea0f1d 100644 --- a/simgear/io/HTTPClient.hxx +++ b/simgear/io/HTTPClient.hxx @@ -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); diff --git a/simgear/io/test_HTTP.cxx b/simgear/io/test_HTTP.cxx index 9ed146f9..39a1d27a 100644 --- a/simgear/io/test_HTTP.cxx +++ b/simgear/io/test_HTTP.cxx @@ -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 diff --git a/simgear/io/test_HTTP.hxx b/simgear/io/test_HTTP.hxx index 6d8861ed..9c75e134 100644 --- a/simgear/io/test_HTTP.hxx +++ b/simgear/io/test_HTTP.hxx @@ -174,11 +174,14 @@ template 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