From f84dac822a8bb7dd04e9fee3c555622e0f17bed9 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 26 Feb 2016 00:10:34 +0200 Subject: [PATCH] Fix a nasty bug in non-libCurl HTTP pipelining. - when requests were closely overlapped, but not submitted at the same time, connection state could get corrupted. --- simgear/io/HTTPClient.cxx | 6 ++-- simgear/io/test_HTTP.cxx | 62 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/simgear/io/HTTPClient.cxx b/simgear/io/HTTPClient.cxx index 93ad3612..6ec17c49 100644 --- a/simgear/io/HTTPClient.cxx +++ b/simgear/io/HTTPClient.cxx @@ -68,7 +68,7 @@ namespace HTTP extern const int DEFAULT_HTTP_PORT = 80; const char* CONTENT_TYPE_URL_ENCODED = "application/x-www-form-urlencoded"; -const unsigned int MAX_INFLIGHT_REQUESTS = 32; +const unsigned int MAX_INFLIGHT_REQUESTS = 4; class Connection; typedef std::multimap ConnectionDict; @@ -377,7 +377,9 @@ public: // successfully sent, remove from queue, and maybe send the next queuedRequests.pop_front(); sentRequests.push_back(r); - state = STATE_WAITING_FOR_RESPONSE; + if (state == STATE_IDLE) { + state = STATE_WAITING_FOR_RESPONSE; + } // pipelining, let's maybe send the next request right away tryStartNextRequest(); diff --git a/simgear/io/test_HTTP.cxx b/simgear/io/test_HTTP.cxx index 39a1d27a..2f90b442 100644 --- a/simgear/io/test_HTTP.cxx +++ b/simgear/io/test_HTTP.cxx @@ -86,7 +86,7 @@ protected: virtual void gotBodyData(const char* s, int n) { - //std::cout << "got body data:'" << string(s, n) << "'" < testServer; @@ -666,6 +698,34 @@ cout << "testing proxy close" << endl; COMPARE(tr->responseBytesReceived(), 0); } + { + cout << "get-during-response-send" << endl; + //test_get_during_send + + TestRequest* tr = new TestRequest("http://localhost:2000/test_get_during_send"); + HTTP::Request_ptr own(tr); + cl.makeRequest(tr); + + // kick things along + for (int i=0; i<10; ++i) { + SGTimeStamp::sleepForMSec(1); + cl.update(); + testServer.poll(); + + } + + TestRequest* tr2 = new TestRequest("http://localhost:2000/test_get_during_send_2"); + HTTP::Request_ptr own2(tr2); + cl.makeRequest(tr2); + + waitForComplete(&cl, tr2); + COMPARE(tr->responseCode(), 200); + COMPARE(tr->bodyData, string(BODY3)); + COMPARE(tr->responseBytesReceived(), strlen(BODY3)); + COMPARE(tr2->responseCode(), 200); + COMPARE(tr2->bodyData, string(BODY1)); + COMPARE(tr2->responseBytesReceived(), strlen(BODY1)); + } cout << "all tests passed ok" << endl; return EXIT_SUCCESS; -- 2.39.5