summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2009-01-03 04:00:41 +0000
committerChris Wilson <chris+github@qwirx.com>2009-01-03 04:00:41 +0000
commit159752d5a90d0ba8ae3a2f825ab8f4c3e2e05814 (patch)
treef0b01e1bc951f0ce67208347d138016958341d3b
parentb7c52100d6ca16f75d5cfbad30f5d19cea380c6d (diff)
Copy tests for HTTP server.
-rw-r--r--test/httpserver/testfiles/httpserver.conf8
-rwxr-xr-xtest/httpserver/testfiles/testrequests.pl143
-rw-r--r--test/httpserver/testhttpserver.cpp139
3 files changed, 290 insertions, 0 deletions
diff --git a/test/httpserver/testfiles/httpserver.conf b/test/httpserver/testfiles/httpserver.conf
new file mode 100644
index 00000000..1a1c4644
--- /dev/null
+++ b/test/httpserver/testfiles/httpserver.conf
@@ -0,0 +1,8 @@
+
+AddressPrefix = http://localhost:1080
+
+Server
+{
+ PidFile = testfiles/httpserver.pid
+ ListenAddresses = inet:localhost:1080
+}
diff --git a/test/httpserver/testfiles/testrequests.pl b/test/httpserver/testfiles/testrequests.pl
new file mode 100755
index 00000000..1a8118b1
--- /dev/null
+++ b/test/httpserver/testfiles/testrequests.pl
@@ -0,0 +1,143 @@
+#!/usr/bin/perl
+use strict;
+use LWP::UserAgent;
+
+my $url_base = 'http://localhost:1080';
+
+my $ua = LWP::UserAgent->new(env_proxy => 0, keep_alive => 1, timeout => 30);
+
+print "GET request...\n";
+
+my $response1 = $ua->get("$url_base/test-one/34/341s/234?p1=vOne&p2=vTwo");
+exit 1 unless $response1->is_success();
+
+my $content = $response1->content();
+
+check_url($content, '/test-one/34/341s/234');
+check_params($content, 'p1'=>'vOne','p2'=>'vTwo');
+
+print "POST request...\n";
+
+my %post = ('sdfgksjhdfsd'=>'dfvsiufy2e3434','sxciuhwf8723e4'=>'238947829334',
+ '&sfsfsfskfhs'=>'?hdkfjhsjfds','fdsf=sdf2342'=>'3984sajhksda');
+
+my $response2 = $ua->post("$url_base/tdskjhfsjdkhf2943734?p1=vOne&p2=vTwo", \%post);
+
+my $content2 = $response2->content();
+
+check_url($content2, '/tdskjhfsjdkhf2943734');
+check_params($content2, %post);
+
+print "HEAD request...\n";
+
+my $response3 = $ua->head("$url_base/tdskjhfsdfkjhs");
+
+if($response3->content() ne '')
+{
+ print "Content not zero length\n";
+ exit(1);
+}
+
+if($response3->code() != 200)
+{
+ print "Wrong response code\n";
+ exit(1);
+}
+
+print "Redirected GET request...\n";
+
+my $response4 = $ua->get("$url_base/redirect?key=value");
+exit 4 unless $response4->is_success();
+
+my $content4 = $response4->content();
+
+check_url($content4, '/redirected');
+check_params($content4);
+
+print "Cookie tests...\n";
+
+# from examples in specs
+test_cookies('CUSTOMER=WILE_E_COYOTE', 'CUSTOMER=WILE_E_COYOTE');
+test_cookies('CUSTOMER="WILE_E_COYOTE"; C2="pants"', 'CUSTOMER=WILE_E_COYOTE', 'C2=pants');
+test_cookies('CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001', 'CUSTOMER=WILE_E_COYOTE', 'PART_NUMBER=ROCKET_LAUNCHER_0001');
+test_cookies('CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX', 'CUSTOMER=WILE_E_COYOTE', 'PART_NUMBER=ROCKET_LAUNCHER_0001', 'SHIPPING=FEDEX');
+test_cookies('$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"', 'Customer=WILE_E_COYOTE');
+test_cookies('$Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"; Part_Number="Rocket_Launcher_0001"; $Path="/acme" ',
+ 'Customer=WILE_E_COYOTE', 'Part_Number=Rocket_Launcher_0001');
+test_cookies(qq!\$Version="1"; Customer="WILE_E_COYOTE"; \$Path="/acme"; Part_Number="Rocket_Launcher_0001"; \$Path="/acme"; Shipping="FedEx"; \t \$Path="/acme"!,
+ 'Customer=WILE_E_COYOTE', 'Part_Number=Rocket_Launcher_0001', 'Shipping=FedEx');
+
+# test the server setting cookies in the UA
+require HTTP::Cookies;
+$ua->cookie_jar(HTTP::Cookies->new());
+$ua->get("$url_base/set-cookie");
+test_cookies('', 'SetByServer=Value1');
+
+sub test_cookies
+{
+ my ($c_str, @cookies) = @_;
+ test_cookies2($c_str, @cookies);
+ $c_str =~ s/;/,/g;
+ test_cookies2($c_str, @cookies);
+}
+
+sub test_cookies2
+{
+ my ($c_str, @cookies) = @_;
+ my $r;
+ if($c_str ne '')
+ {
+ $r = $ua->get("$url_base/cookie", 'Cookie' => $c_str);
+ }
+ else
+ {
+ $r = $ua->get("$url_base/cookie");
+ }
+ my $c = $r->content();
+ for(@cookies)
+ {
+ unless($c =~ m/COOKIE:$_<br>/)
+ {
+ print "Cookie $_ not found\n";
+ exit(1);
+ }
+ }
+}
+
+
+sub check_url
+{
+ my ($c,$url) = @_;
+ unless($c =~ m~URI:</b> (.+?)</p>~)
+ {
+ print "URI not found\n";
+ exit(1);
+ }
+ if($url ne $1)
+ {
+ print "Wrong URI in content\n";
+ exit(1);
+ }
+}
+
+sub check_params
+{
+ my ($c,%params) = @_;
+
+ while($c =~ m/^PARAM:(.+)=(.+?)<br>/mg)
+ {
+ if($params{$1} ne $2)
+ {
+ print "$1=$2 not found in response\n";
+ exit(1);
+ }
+ delete $params{$1}
+ }
+
+ my @k = keys %params;
+ if($#k != -1)
+ {
+ print "Didn't find all params\n";
+ exit(1);
+ }
+}
diff --git a/test/httpserver/testhttpserver.cpp b/test/httpserver/testhttpserver.cpp
new file mode 100644
index 00000000..6b72748d
--- /dev/null
+++ b/test/httpserver/testhttpserver.cpp
@@ -0,0 +1,139 @@
+// --------------------------------------------------------------------------
+//
+// File
+// Name: testhttpserver.cpp
+// Purpose: Test code for HTTP server class
+// Created: 26/3/04
+//
+// --------------------------------------------------------------------------
+
+#include "Box.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "Test.h"
+#include "HTTPServer.h"
+#include "HTTPRequest.h"
+#include "HTTPResponse.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 "<html>\n<head><title>TEST SERVER RESPONSE</title></head>\n<body><h1>Test response</h1>\n<p><b>URI:</b> "
+ #define DEFAULT_RESPONSE_3 "</p>\n<p><b>Query string:</b> "
+ #define DEFAULT_RESPONSE_4 "</p>\n<p><b>Method:</b> "
+ #define DEFAULT_RESPONSE_5 "</p>\n<p><b>Decoded query:</b><br>"
+ #define DEFAULT_RESPONSE_6 "</p>\n<p><b>Content type:</b> "
+ #define DEFAULT_RESPONSE_7 "</p>\n<p><b>Content length:</b> "
+ #define DEFAULT_RESPONSE_8 "</p>\n<p><b>Cookies:</b><br>\n"
+ #define DEFAULT_RESPONSE_2 "</p>\n</body>\n</html>\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("<br>\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<br>\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;
+}
+