]> git.mxchange.org Git - simgear.git/blobdiff - simgear/io/test_HTTP.cxx
Fix VS2010 lack of fminf
[simgear.git] / simgear / io / test_HTTP.cxx
index fc2fe869bf91e7da3909a4af6fd8efbba18c43d3..1849434d55d59f6d3d032810bedc9376343f67dc 100644 (file)
@@ -22,6 +22,14 @@ using std::stringstream;
 using namespace simgear;
 
 const char* BODY1 = "The quick brown fox jumps over a lazy dog.";
+const char* BODY3 = "Cras ut neque nulla. Duis ut velit neque, sit amet "
+"pharetra risus. In est ligula, lacinia vitae congue in, sollicitudin at "
+"libero. Mauris pharetra pretium elit, nec placerat dui semper et. Maecenas "
+"magna magna, placerat sed luctus ac, commodo et ligula. Mauris at purus et "
+"nisl molestie auctor placerat at quam. Donec sapien magna, venenatis sed "
+"iaculis id, fringilla vel arcu. Duis sed neque nisi. Cras a arcu sit amet "
+"risus ultrices varius. Integer sagittis euismod dui id varius. Cras vel "
+"justo gravida metus.";
 
 const unsigned int body2Size = 8 * 1024;
 char body2[body2Size];
@@ -29,7 +37,7 @@ char body2[body2Size];
 #define COMPARE(a, b) \
     if ((a) != (b))  { \
         cerr << "failed:" << #a << " != " << #b << endl; \
-        cerr << "\tgot:" << a << endl; \
+        cerr << "\tgot:'" << a << "'" << endl; \
         exit(1); \
     }
 
@@ -45,52 +53,30 @@ public:
     bool complete;
     bool failed;
     string bodyData;
-    
+
     TestRequest(const std::string& url, const std::string method = "GET") : 
         HTTP::Request(url, method),
         complete(false)
     {
+
     }
     
-    std::map<string, string> sendHeaders;
     std::map<string, string> headers;
 protected:
-    string_list requestHeaders() const
-    {
-        string_list r;
-        std::map<string, string>::const_iterator it;
-        for (it = sendHeaders.begin(); it != sendHeaders.end(); ++it) {
-            r.push_back(it->first);
-        }
-        return r;
-    }
-    
-    string header(const string& name) const
-    {
-        std::map<string, string>::const_iterator it = sendHeaders.find(name);
-        if (it == sendHeaders.end()) {
-            return string();
-        }
-        
-        return it->second;
-    }
     
-    virtual void responseHeadersComplete()
-    {
-    }
-    
-    virtual void responseComplete()
+    virtual void onDone()
     {
         complete = true;
     }  
     
-    virtual void failure()
+    virtual void onFail()
     {
         failed = true;
     }
     
     virtual void gotBodyData(const char* s, int n)
     {
+      //std::cout << "got body data:'" << string(s, n) << "'" <<std::endl;
         bodyData += string(s, n);
     }
     
@@ -107,6 +93,7 @@ public:
     {
         STATE_IDLE = 0,
         STATE_HEADERS,
+        STATE_CLOSING,
         STATE_REQUEST_BODY
     };
     
@@ -114,6 +101,7 @@ public:
     {
         state = STATE_IDLE;
         setTerminator("\r\n");
+        
     }
     
     virtual void collectIncomingData(const char* s, int n)
@@ -134,7 +122,7 @@ public:
             method = line[0];
             path = line[1];
             
-            int queryPos = path.find('?'); 
+            string::size_type queryPos = path.find('?');
             if (queryPos != string::npos) {
                 parseArgs(path.substr(queryPos + 1));
                 path = path.substr(0, queryPos);
@@ -151,8 +139,8 @@ public:
                 return;
             }
             
-            int colonPos = buffer.find(':');
-            if (colonPos < 0) {
+            string::size_type colonPos = buffer.find(':');
+            if (colonPos == string::npos) {
                 cerr << "malformed HTTP response header:" << buffer << endl;
                 buffer.clear();
                 return;
@@ -163,9 +151,10 @@ public:
             requestHeaders[key] = value;
             buffer.clear();
         } else if (state == STATE_REQUEST_BODY) {
-            cerr << "done getting requst body";
             receivedBody();
             setTerminator("\r\n");
+        } else if (state == STATE_CLOSING) {
+          // ignore!
         }
     }  
     
@@ -173,8 +162,8 @@ public:
     {
         string_list argv = strutils::split(argData, "&");
         for (unsigned int a=0; a<argv.size(); ++a) {
-            int eqPos = argv[a].find('=');
-            if (eqPos < 0) {
+            string::size_type eqPos = argv[a].find('=');
+            if (eqPos == string::npos) {
                 cerr << "malformed HTTP argument:" << argv[a] << endl;
                 continue;
             }
@@ -197,6 +186,14 @@ public:
             d << "\r\n"; // final CRLF to terminate the headers
             d << contentStr;
             push(d.str().c_str());
+        } else if (path == "/testLorem") {
+            string contentStr(BODY3);
+            stringstream d;
+            d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
+            d << "Content-Length:" << contentStr.size() << "\r\n";
+            d << "\r\n"; // final CRLF to terminate the headers
+            d << contentStr;
+            push(d.str().c_str());
         } else if (path == "/test_zero_length_content") {
             string contentStr;
             stringstream d;
@@ -257,12 +254,15 @@ public:
             sendBody2();
         } else if (strutils::starts_with(path, "/test_1_0")) {
             string contentStr(BODY1);
+            if (strutils::ends_with(path, "/B")) {
+                contentStr = BODY3;
+            }
             stringstream d;
             d << "HTTP/1.0 " << 200 << " " << reasonForCode(200) << "\r\n";
             d << "\r\n"; // final CRLF to terminate the headers
             d << contentStr;
             push(d.str().c_str());
-            closeWhenDone();
+            closeAfterSending();
         } else if (path == "/test_close") {
             string contentStr(BODY1);
             stringstream d;
@@ -271,7 +271,7 @@ public:
             d << "\r\n"; // final CRLF to terminate the headers
             d << contentStr;
             push(d.str().c_str());
-            closeWhenDone();
+            closeAfterSending();
         } else if (path == "/test_args") {
             if ((args["foo"] != "abc") || (args["bar"] != "1234") || (args["username"] != "johndoe")) {
                 sendErrorResponse(400, true, "bad arguments");
@@ -300,6 +300,12 @@ public:
         }
     }
     
+    void closeAfterSending()
+    {
+      state = STATE_CLOSING;
+      closeWhenDone();
+    }
+  
     void receivedBody()
     {
         state = STATE_IDLE;
@@ -369,12 +375,15 @@ public:
 
 class TestServer : public NetChannel
 {
+    simgear::NetChannelPoller _poller;
 public:   
     TestServer()
     {
         open();
         bind(NULL, 2000); // localhost, any port
         listen(5);
+        
+        _poller.addChannel(this);
     }
     
     virtual ~TestServer()
@@ -390,14 +399,25 @@ public:
         //cout << "did accept from " << addr.getHost() << ":" << addr.getPort() << endl;
         TestServerChannel* chan = new TestServerChannel();
         chan->setHandle(handle);
+        
+        _poller.addChannel(chan);
+    }
+    
+    void poll()
+    {
+        _poller.poll();
     }
 };
 
+TestServer testServer;
+
 void waitForComplete(HTTP::Client* cl, TestRequest* tr)
 {
     SGTimeStamp start(SGTimeStamp::now());
     while (start.elapsedMSec() <  1000) {
         cl->update();
+        testServer.poll();
+        
         if (tr->complete) {
             return;
         }
@@ -412,6 +432,8 @@ void waitForFailed(HTTP::Client* cl, TestRequest* tr)
     SGTimeStamp start(SGTimeStamp::now());
     while (start.elapsedMSec() <  1000) {
         cl->update();
+        testServer.poll();
+        
         if (tr->failed) {
             return;
         }
@@ -423,10 +445,11 @@ void waitForFailed(HTTP::Client* cl, TestRequest* tr)
 
 int main(int argc, char* argv[])
 {
-    TestServer s;
     
     HTTP::Client cl;
-
+    // force all requests to use the same connection for this test
+    cl.setMaxConnections(1); 
+    
 // test URL parsing
     TestRequest* tr1 = new TestRequest("http://localhost.woo.zar:2000/test1?foo=bar");
     COMPARE(tr1->scheme(), "http");
@@ -456,6 +479,19 @@ int main(int argc, char* argv[])
         COMPARE(tr->bodyData, string(BODY1));
     }
     
+    {
+      TestRequest* tr = new TestRequest("http://localhost:2000/testLorem");
+      HTTP::Request_ptr own(tr);
+      cl.makeRequest(tr);
+      
+      waitForComplete(&cl, tr);
+      COMPARE(tr->responseCode(), 200);
+      COMPARE(tr->responseReason(), string("OK"));
+      COMPARE(tr->responseLength(), strlen(BODY3));
+      COMPARE(tr->responseBytesReceived(), strlen(BODY3));
+      COMPARE(tr->bodyData, string(BODY3));
+    }
+  
     {
         TestRequest* tr = new TestRequest("http://localhost:2000/test_args?foo=abc&bar=1234&username=johndoe");
         HTTP::Request_ptr own(tr);
@@ -469,8 +505,8 @@ int main(int argc, char* argv[])
     {
         TestRequest* tr = new TestRequest("http://localhost:2000/test_headers");
         HTTP::Request_ptr own(tr);
-        tr->sendHeaders["X-Foo"] = "Bar";
-        tr->sendHeaders["X-AnotherHeader"] = "A longer value";
+        tr->requestHeader("X-Foo") = "Bar";
+        tr->requestHeader("X-AnotherHeader") = "A longer value";
         cl.makeRequest(tr);
 
         waitForComplete(&cl, tr);
@@ -590,14 +626,17 @@ int main(int argc, char* argv[])
     }
     
 // pipelining
+    cout << "testing HTTP 1.1 pipelineing" << endl;
+  
     {
+                                
         cl.setProxy("", 80);
         TestRequest* tr = new TestRequest("http://localhost:2000/test1");
         HTTP::Request_ptr own(tr);
         cl.makeRequest(tr);
         
         
-        TestRequest* tr2 = new TestRequest("http://localhost:2000/test1");
+        TestRequest* tr2 = new TestRequest("http://localhost:2000/testLorem");
         HTTP::Request_ptr own2(tr2);
         cl.makeRequest(tr2);
         
@@ -609,7 +648,11 @@ int main(int argc, char* argv[])
         VERIFY(tr->complete);
         VERIFY(tr2->complete);
         COMPARE(tr->bodyData, string(BODY1));
-        COMPARE(tr2->bodyData, string(BODY1));
+      
+        COMPARE(tr2->responseLength(), strlen(BODY3));
+        COMPARE(tr2->responseBytesReceived(), strlen(BODY3));
+        COMPARE(tr2->bodyData, string(BODY3));
+      
         COMPARE(tr3->bodyData, string(BODY1));
     }
     
@@ -633,8 +676,14 @@ int main(int argc, char* argv[])
         waitForComplete(&cl, tr3);
         VERIFY(tr->complete);
         VERIFY(tr2->complete);
+        
+        COMPARE(tr->responseLength(), strlen(BODY1));
+        COMPARE(tr->responseBytesReceived(), strlen(BODY1));
         COMPARE(tr->bodyData, string(BODY1));
-        COMPARE(tr2->bodyData, string(BODY1));
+      
+        COMPARE(tr2->responseLength(), strlen(BODY3));
+        COMPARE(tr2->responseBytesReceived(), strlen(BODY3));
+        COMPARE(tr2->bodyData, string(BODY3));
         COMPARE(tr3->bodyData, string(BODY1));
     }
     
@@ -642,6 +691,8 @@ int main(int argc, char* argv[])
     {
         cout << "POST" << endl;
         TestRequest* tr = new TestRequest("http://localhost:2000/test_post?foo=abc&bar=1234&username=johndoe", "POST");
+        tr->setBodyData("", "application/x-www-form-urlencoded");
+        
         HTTP::Request_ptr own(tr);
         cl.makeRequest(tr);
         waitForComplete(&cl, tr);