X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fio%2FHTTPClient.cxx;h=fb1b812faaeb4d91dcbb5c9a4e0b4f1cfa0c33e5;hb=09b0dd2b2d7d934c1d4059cb2cbd3b4fcbb7872f;hp=ddcae48402472cd0a288646fa3269a423f9546f4;hpb=7525fd5e3ee741ea323df5811647faa5c5763a4b;p=simgear.git diff --git a/simgear/io/HTTPClient.cxx b/simgear/io/HTTPClient.cxx index ddcae484..fb1b812f 100644 --- a/simgear/io/HTTPClient.cxx +++ b/simgear/io/HTTPClient.cxx @@ -25,6 +25,9 @@ using std::string; using std::stringstream; using std::vector; +//#include +//using namespace std; + namespace simgear { @@ -41,7 +44,7 @@ public: state(STATE_CLOSED), port(DEFAULT_HTTP_PORT) { - setTerminator("\r\n"); + } void setServer(const string& h, short p) @@ -65,15 +68,16 @@ public: virtual void handleClose() { + NetChat::handleClose(); + if ((state == STATE_GETTING_BODY) && activeRequest) { // force state here, so responseComplete can avoid closing the // socket again state = STATE_CLOSED; responseComplete(); + } else { + state = STATE_CLOSED; } - - state = STATE_CLOSED; - NetChat::handleClose(); } void queueRequest(const Request_ptr& r) @@ -94,11 +98,12 @@ public: state = STATE_IDLE; } - + activeRequest = r; - state = STATE_IDLE; + state = STATE_SENT_REQUEST; bodyTransferSize = -1; chunkedTransfer = false; + setTerminator("\r\n"); stringstream headerData; string path = r->path(); @@ -141,7 +146,7 @@ public: virtual void foundTerminator(void) { switch (state) { - case STATE_IDLE: + case STATE_SENT_REQUEST: activeRequest->responseStart(buffer); state = STATE_GETTING_HEADERS; buffer.clear(); @@ -165,6 +170,7 @@ public: state = STATE_GETTING_CHUNKED; break; + case STATE_GETTING_TRAILER: processTrailer(); buffer.clear(); @@ -188,6 +194,19 @@ public: { return (state == STATE_SOCKET_ERROR); } + + bool shouldStartNext() const + { + return !activeRequest && !queuedRequests.empty() && + ((state == STATE_CLOSED) || (state == STATE_IDLE)); + } + + void startNext() + { + Request_ptr next = queuedRequests.front(); + queuedRequests.pop_front(); + startRequest(next); + } private: bool connectToHost() { @@ -308,6 +327,7 @@ private: { activeRequest->responseComplete(); client->requestFinished(this); + //cout << "response complete: " << activeRequest->url() << endl; bool doClose = activeRequest->closeAfterComplete(); activeRequest = NULL; @@ -322,10 +342,12 @@ private: setTerminator("\r\n"); - if (!queuedRequests.empty()) { - Request_ptr next = queuedRequests.front(); - queuedRequests.pop_front(); - startRequest(next); + // if we have more requests, and we're idle, can start the next + // request immediately. Note we cannot do this if we're in STATE_CLOSED, + // since NetChannel::close cleans up state after calling handleClose; + // instead we pick up waiting requests in update() + if (!queuedRequests.empty() && (state == STATE_IDLE)) { + startNext(); } else { idleTime.stamp(); } @@ -333,6 +355,7 @@ private: enum ConnectionState { STATE_IDLE = 0, + STATE_SENT_REQUEST, STATE_GETTING_HEADERS, STATE_GETTING_BODY, STATE_GETTING_CHUNKED, @@ -374,6 +397,10 @@ void Client::update() delete del->second; _connections.erase(del); } else { + if (it->second->shouldStartNext()) { + it->second->startNext(); + } + ++it; } } // of connecion iteration