Fix for libCurl pipelining and connection count.

This commit is contained in:
James Turner 2016-02-24 23:35:54 +02:00
parent ce245059b8
commit 5c9f5361bd
4 changed files with 51 additions and 3 deletions

View 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

View 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);

View File

@ -557,6 +557,8 @@ 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");
@ -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

View 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