// -------------------------------------------------------------------------- // // File // Name: testhttpserver.cpp // Purpose: Test code for HTTP server class // Created: 26/3/04 // // -------------------------------------------------------------------------- #include "Box.h" #include #include #include "Test.h" #include "HTTPServer.h" #include "HTTPRequest.h" #include "HTTPResponse.h" #include "ServerControl.h" #include "MemLeakFindOn.h" class TestWebServer : public HTTPServer { public: TestWebServer(); ~TestWebServer(); virtual void Handle(const HTTPRequest &rRequest, HTTPResponse &rResponse); }; // Build a nice HTML response, so this can also be tested neatly in a browser void TestWebServer::Handle(const HTTPRequest &rRequest, HTTPResponse &rResponse) { // Test redirection mechanism if(rRequest.GetRequestURI() == "/redirect") { rResponse.SetAsRedirect("/redirected"); return; } // Set a cookie? if(rRequest.GetRequestURI() == "/set-cookie") { rResponse.SetCookie("SetByServer", "Value1"); } #define DEFAULT_RESPONSE_1 "\nTEST SERVER RESPONSE\n

Test response

\n

URI: " #define DEFAULT_RESPONSE_3 "

\n

Query string: " #define DEFAULT_RESPONSE_4 "

\n

Method: " #define DEFAULT_RESPONSE_5 "

\n

Decoded query:
" #define DEFAULT_RESPONSE_6 "

\n

Content type: " #define DEFAULT_RESPONSE_7 "

\n

Content length: " #define DEFAULT_RESPONSE_8 "

\n

Cookies:
\n" #define DEFAULT_RESPONSE_2 "

\n\n\n" rResponse.SetResponseCode(HTTPResponse::Code_OK); rResponse.SetContentType("text/html"); rResponse.Write(DEFAULT_RESPONSE_1, sizeof(DEFAULT_RESPONSE_1) - 1); const std::string &ruri(rRequest.GetRequestURI()); rResponse.Write(ruri.c_str(), ruri.size()); rResponse.Write(DEFAULT_RESPONSE_3, sizeof(DEFAULT_RESPONSE_3) - 1); const std::string &rquery(rRequest.GetQueryString()); rResponse.Write(rquery.c_str(), rquery.size()); rResponse.Write(DEFAULT_RESPONSE_4, sizeof(DEFAULT_RESPONSE_4) - 1); { const char *m = "????"; switch(rRequest.GetMethod()) { case HTTPRequest::Method_GET: m = "GET "; break; case HTTPRequest::Method_HEAD: m = "HEAD"; break; case HTTPRequest::Method_POST: m = "POST"; break; } rResponse.Write(m, 4); } rResponse.Write(DEFAULT_RESPONSE_5, sizeof(DEFAULT_RESPONSE_5) - 1); { const HTTPRequest::Query_t &rquery(rRequest.GetQuery()); for(HTTPRequest::Query_t::const_iterator i(rquery.begin()); i != rquery.end(); ++i) { rResponse.Write("\nPARAM:", 7); rResponse.Write(i->first.c_str(), i->first.size()); rResponse.Write("=", 1); rResponse.Write(i->second.c_str(), i->second.size()); rResponse.Write("
\n", 4); } } rResponse.Write(DEFAULT_RESPONSE_6, sizeof(DEFAULT_RESPONSE_6) - 1); const std::string &rctype(rRequest.GetContentType()); rResponse.Write(rctype.c_str(), rctype.size()); rResponse.Write(DEFAULT_RESPONSE_7, sizeof(DEFAULT_RESPONSE_7) - 1); { char l[32]; rResponse.Write(l, ::sprintf(l, "%d", rRequest.GetContentLength())); } rResponse.Write(DEFAULT_RESPONSE_8, sizeof(DEFAULT_RESPONSE_8) - 1); const HTTPRequest::CookieJar_t *pcookies = rRequest.GetCookies(); if(pcookies != 0) { HTTPRequest::CookieJar_t::const_iterator i(pcookies->begin()); for(; i != pcookies->end(); ++i) { char t[512]; rResponse.Write(t, ::sprintf(t, "COOKIE:%s=%s
\n", i->first.c_str(), i->second.c_str())); } } rResponse.Write(DEFAULT_RESPONSE_2, sizeof(DEFAULT_RESPONSE_2) - 1); } TestWebServer::TestWebServer() {} TestWebServer::~TestWebServer() {} int test(int argc, const char *argv[]) { if(argc >= 2 && ::strcmp(argv[1], "server") == 0) { // Run a server TestWebServer server; return server.Main("doesnotexist", argc - 1, argv + 1); } // Start the server int pid = LaunchServer("./test server testfiles/httpserver.conf", "testfiles/httpserver.pid"); TEST_THAT(pid != -1 && pid != 0); if(pid > 0) { // Run the request script TEST_THAT(::system("perl testfiles/testrequests.pl") == 0); // Kill it TEST_THAT(KillServer(pid)); TestRemoteProcessMemLeaks("generic-httpserver.memleaks"); } return 0; }