using std::stringstream;
using std::vector;
+//#include <iostream>
+//using namespace std;
+
namespace simgear
{
state(STATE_CLOSED),
port(DEFAULT_HTTP_PORT)
{
- setTerminator("\r\n");
+
}
void setServer(const string& h, short p)
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)
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();
virtual void foundTerminator(void)
{
switch (state) {
- case STATE_IDLE:
+ case STATE_SENT_REQUEST:
activeRequest->responseStart(buffer);
state = STATE_GETTING_HEADERS;
buffer.clear();
state = STATE_GETTING_CHUNKED;
break;
+
case STATE_GETTING_TRAILER:
processTrailer();
buffer.clear();
{
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()
{
{
activeRequest->responseComplete();
client->requestFinished(this);
+ //cout << "response complete: " << activeRequest->url() << endl;
bool doClose = activeRequest->closeAfterComplete();
activeRequest = NULL;
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();
}
enum ConnectionState {
STATE_IDLE = 0,
+ STATE_SENT_REQUEST,
STATE_GETTING_HEADERS,
STATE_GETTING_BODY,
STATE_GETTING_CHUNKED,
delete del->second;
_connections.erase(del);
} else {
+ if (it->second->shouldStartNext()) {
+ it->second->startNext();
+ }
+
++it;
}
} // of connecion iteration