check_http.t 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #! /usr/bin/perl -w -I ..
  2. #
  3. # Test check_http by having an actual HTTP server running
  4. #
  5. use strict;
  6. use Test::More;
  7. use NPTest;
  8. use FindBin qw($Bin);
  9. use HTTP::Daemon;
  10. use HTTP::Status;
  11. use HTTP::Response;
  12. my $servers = { http => 0 }; # HTTP::Daemon should always be available
  13. eval { require HTTP::Daemon::SSL };
  14. if ($@) {
  15. diag "Cannot load HTTP::Daemon::SSL: $@";
  16. } else {
  17. $servers->{https} = 0;
  18. }
  19. # set a fixed version, so the header size doesn't vary
  20. $HTTP::Daemon::VERSION = "1.00";
  21. my $port_http = 50000 + int(rand(1000));
  22. my $port_https = $port_http + 1;
  23. # Start up both servers
  24. my $pid_https;
  25. my $pid_http = fork();
  26. if ($pid_http) {
  27. # Parent
  28. if (exists $servers->{https}) {
  29. # Fork another server
  30. $pid_https = fork();
  31. if ($pid_https) {
  32. # Parent
  33. } else {
  34. my $d = HTTP::Daemon::SSL->new(
  35. LocalPort => $port_https,
  36. LocalAddr => "127.0.0.1",
  37. SSL_cert_file => "$Bin/certs/server-cert.pem",
  38. SSL_key_file => "$Bin/certs/server-key.pem",
  39. ) || die;
  40. print "Please contact https at: <URL:", $d->url, ">\n";
  41. run_server( $d );
  42. exit;
  43. }
  44. }
  45. # give our webservers some time to startup
  46. sleep(1);
  47. } else {
  48. # Child
  49. #print "child\n";
  50. my $d = HTTP::Daemon->new(
  51. LocalPort => $port_http,
  52. LocalAddr => "127.0.0.1",
  53. ) || die;
  54. print "Please contact http at: <URL:", $d->url, ">\n";
  55. run_server( $d );
  56. exit;
  57. }
  58. # Run the same server on http and https
  59. sub run_server {
  60. my $d = shift;
  61. while (my $c = $d->accept ) {
  62. while (my $r = $c->get_request) {
  63. if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) {
  64. $c->send_basic_header($1);
  65. $c->send_crlf;
  66. } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) {
  67. $c->send_basic_header;
  68. $c->send_crlf;
  69. $c->send_file_response("$Bin/var/$1");
  70. } elsif ($r->method eq "GET" and $r->url->path eq "/slow") {
  71. $c->send_basic_header;
  72. $c->send_crlf;
  73. sleep 1;
  74. $c->send_response("slow");
  75. } elsif ($r->url->path eq "/method") {
  76. if ($r->method eq "DELETE") {
  77. $c->send_error(RC_METHOD_NOT_ALLOWED);
  78. } elsif ($r->method eq "foo") {
  79. $c->send_error(RC_NOT_IMPLEMENTED);
  80. } else {
  81. $c->send_status_line(200, $r->method);
  82. }
  83. } elsif ($r->url->path eq "/postdata") {
  84. $c->send_basic_header;
  85. $c->send_crlf;
  86. $c->send_response($r->method.":".$r->content);
  87. } elsif ($r->url->path eq "/redirect") {
  88. $c->send_redirect( "/redirect2" );
  89. } elsif ($r->url->path eq "/redirect2") {
  90. $c->send_basic_header;
  91. $c->send_crlf;
  92. $c->send_response("redirected");
  93. } else {
  94. $c->send_error(RC_FORBIDDEN);
  95. }
  96. $c->close;
  97. }
  98. }
  99. }
  100. END {
  101. foreach my $pid ($pid_http, $pid_https) {
  102. if ($pid) { print "Killing $pid\n"; kill "INT", $pid }
  103. }
  104. };
  105. if ($ARGV[0] && $ARGV[0] eq "-d") {
  106. sleep 1000;
  107. }
  108. my $common_tests = 47;
  109. if (-x "./check_http") {
  110. plan tests => $common_tests * 2;
  111. } else {
  112. plan skip_all => "No check_http compiled";
  113. }
  114. my $result;
  115. my $command = "./check_http -H 127.0.0.1";
  116. run_common_tests( { command => "$command -p $port_http" } );
  117. SKIP: {
  118. skip "HTTP::Daemon::SSL not installed", $common_tests if ! exists $servers->{https};
  119. run_common_tests( { command => "$command -p $port_https", ssl => 1 } );
  120. }
  121. sub run_common_tests {
  122. my ($opts) = @_;
  123. my $command = $opts->{command};
  124. my $b;
  125. my $add = 0;
  126. if ($opts->{ssl}) {
  127. $command .= " --ssl";
  128. }
  129. $result = NPTest->testCmd( "$command -u /file/root" );
  130. is( $result->return_code, 0, "/file/root");
  131. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - 274 bytes in [\d\.]+ seconds/', "Output correct" );
  132. $result = NPTest->testCmd( "$command -u /file/root -s Root" );
  133. is( $result->return_code, 0, "/file/root search for string");
  134. TODO: {
  135. local $TODO = "Output is different if a string is requested - should this be right?";
  136. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - 274 bytes in [\d\.]+ seconds/', "Output correct" );
  137. }
  138. $b = 177 + $add;
  139. $result = NPTest->testCmd( "$command -u /slow" );
  140. is( $result->return_code, 0, "/file/root");
  141. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct" );
  142. $result->output =~ /in ([\d\.]+) seconds/;
  143. cmp_ok( $1, ">", 1, "Time is > 1 second" );
  144. my $cmd;
  145. $b = 89 + $add;
  146. $cmd = "$command -u /statuscode/200 -e 200";
  147. $result = NPTest->testCmd( $cmd );
  148. is( $result->return_code, 0, $cmd);
  149. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  150. $b = 94 + $add;
  151. $cmd = "$command -u /statuscode/201 -e 201";
  152. $result = NPTest->testCmd( $cmd );
  153. is( $result->return_code, 0, $cmd);
  154. like( $result->output, '/^HTTP OK HTTP/1.1 201 Created - '.$b.' bytes in ([\d\.]+) seconds /', "Output correct: ".$result->output );
  155. $cmd = "$command -u /statuscode/201 -e 200";
  156. $result = NPTest->testCmd( $cmd );
  157. is( $result->return_code, 2, $cmd);
  158. like( $result->output, '/^HTTP CRITICAL - Invalid HTTP response received from host on port \d+: HTTP/1.1 201 Created/', "Output correct: ".$result->output );
  159. $b = 89 + $add;
  160. $cmd = "$command -u /statuscode/200 -e 200,201,202";
  161. $result = NPTest->testCmd( $cmd );
  162. is( $result->return_code, 0, $cmd);
  163. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  164. $b = 94 + $add;
  165. $cmd = "$command -u /statuscode/201 -e 200,201,202";
  166. $result = NPTest->testCmd( $cmd );
  167. is( $result->return_code, 0, $cmd);
  168. like( $result->output, '/^HTTP OK HTTP/1.1 201 Created - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  169. $cmd = "$command -u /statuscode/203 -e 200,201,202";
  170. $result = NPTest->testCmd( $cmd );
  171. is( $result->return_code, 2, $cmd);
  172. like( $result->output, '/^HTTP CRITICAL - Invalid HTTP response received from host on port (\d+): HTTP/1.1 203 Non-Authoritative Information/', "Output correct: ".$result->output );
  173. $b = 19 + $add;
  174. $cmd = "$command -j HEAD -u /method";
  175. $result = NPTest->testCmd( $cmd );
  176. is( $result->return_code, 0, $cmd);
  177. like( $result->output, '/^HTTP OK HTTP/1.1 200 HEAD - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  178. $b = 19 + $add;
  179. $cmd = "$command -j POST -u /method";
  180. $result = NPTest->testCmd( $cmd );
  181. is( $result->return_code, 0, $cmd);
  182. like( $result->output, '/^HTTP OK HTTP/1.1 200 POST - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  183. $b = 18 + $add;
  184. $cmd = "$command -j GET -u /method";
  185. $result = NPTest->testCmd( $cmd );
  186. is( $result->return_code, 0, $cmd);
  187. like( $result->output, '/^HTTP OK HTTP/1.1 200 GET - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  188. $b = 18 + $add;
  189. $cmd = "$command -u /method";
  190. $result = NPTest->testCmd( $cmd );
  191. is( $result->return_code, 0, $cmd);
  192. like( $result->output, '/^HTTP OK HTTP/1.1 200 GET - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  193. $b = 19 + $add;
  194. $cmd = "$command -P foo -u /method";
  195. $result = NPTest->testCmd( $cmd );
  196. is( $result->return_code, 0, $cmd);
  197. like( $result->output, '/^HTTP OK HTTP/1.1 200 POST - '.$b.' bytes in ([\d\.]+) seconds/', "Output correct: ".$result->output );
  198. $cmd = "$command -j DELETE -u /method";
  199. $result = NPTest->testCmd( $cmd );
  200. is( $result->return_code, 1, $cmd);
  201. like( $result->output, '/^HTTP WARNING: HTTP/1.1 405 Method Not Allowed/', "Output correct: ".$result->output );
  202. $cmd = "$command -j foo -u /method";
  203. $result = NPTest->testCmd( $cmd );
  204. is( $result->return_code, 2, $cmd);
  205. like( $result->output, '/^HTTP CRITICAL: HTTP/1.1 501 Not Implemented/', "Output correct: ".$result->output );
  206. $cmd = "$command -P stufftoinclude -u /postdata -s POST:stufftoinclude";
  207. $result = NPTest->testCmd( $cmd );
  208. is( $result->return_code, 0, $cmd);
  209. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - ([\d\.]+) second/', "Output correct: ".$result->output );
  210. $cmd = "$command -j PUT -P stufftoinclude -u /postdata -s PUT:stufftoinclude";
  211. $result = NPTest->testCmd( $cmd );
  212. is( $result->return_code, 0, $cmd);
  213. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - ([\d\.]+) second/', "Output correct: ".$result->output );
  214. # To confirm that the free doesn't segfault
  215. $cmd = "$command -P stufftoinclude -j PUT -u /postdata -s PUT:stufftoinclude";
  216. $result = NPTest->testCmd( $cmd );
  217. is( $result->return_code, 0, $cmd);
  218. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - ([\d\.]+) second/', "Output correct: ".$result->output );
  219. $cmd = "$command -u /redirect";
  220. $result = NPTest->testCmd( $cmd );
  221. is( $result->return_code, 0, $cmd);
  222. like( $result->output, '/^HTTP OK - HTTP/1.1 301 Moved Permanently - [\d\.]+ second/', "Output correct: ".$result->output );
  223. $b = 183 + $add;
  224. $cmd = "$command -f follow -u /redirect";
  225. $result = NPTest->testCmd( $cmd );
  226. is( $result->return_code, 0, $cmd);
  227. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - '.$b.' bytes in [\d\.]+ second/', "Output correct: ".$result->output );
  228. $cmd = "$command -u /redirect -k 'follow: me'";
  229. $result = NPTest->testCmd( $cmd );
  230. is( $result->return_code, 0, $cmd);
  231. like( $result->output, '/^HTTP OK - HTTP/1.1 301 Moved Permanently - [\d\.]+ second/', "Output correct: ".$result->output );
  232. $b = 183 + $add;
  233. $cmd = "$command -f follow -u /redirect -k 'follow: me'";
  234. $result = NPTest->testCmd( $cmd );
  235. is( $result->return_code, 0, $cmd);
  236. like( $result->output, '/^HTTP OK HTTP/1.1 200 OK - '.$b.' bytes in [\d\.]+ second/', "Output correct: ".$result->output );
  237. }