diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_http.c | 8 | ||||
| -rwxr-xr-x | plugins/tests/check_http.t | 70 |
2 files changed, 76 insertions, 2 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c index 5fa310f5..8dda046f 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
| @@ -1462,7 +1462,13 @@ char *unchunk_content(const char *content) { | |||
| 1462 | memcpy(result + (overall_size - size_of_chunk), start_of_chunk, size_of_chunk); | 1462 | memcpy(result + (overall_size - size_of_chunk), start_of_chunk, size_of_chunk); |
| 1463 | } | 1463 | } |
| 1464 | 1464 | ||
| 1465 | result[overall_size] = '\0'; | 1465 | if (overall_size == 0 && result == NULL) { |
| 1466 | // We might just have received the end chunk without previous content, so result is never allocated | ||
| 1467 | result = calloc(1, sizeof(char)); | ||
| 1468 | // No error handling here, we can only return NULL anyway | ||
| 1469 | } else { | ||
| 1470 | result[overall_size] = '\0'; | ||
| 1471 | } | ||
| 1466 | return result; | 1472 | return result; |
| 1467 | } | 1473 | } |
| 1468 | 1474 | ||
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t index d766ac37..6078b274 100755 --- a/plugins/tests/check_http.t +++ b/plugins/tests/check_http.t | |||
| @@ -9,12 +9,14 @@ use strict; | |||
| 9 | use Test::More; | 9 | use Test::More; |
| 10 | use NPTest; | 10 | use NPTest; |
| 11 | use FindBin qw($Bin); | 11 | use FindBin qw($Bin); |
| 12 | use IO::Socket::INET; | ||
| 12 | 13 | ||
| 13 | $ENV{'LC_TIME'} = "C"; | 14 | $ENV{'LC_TIME'} = "C"; |
| 14 | 15 | ||
| 15 | my $common_tests = 71; | 16 | my $common_tests = 71; |
| 16 | my $virtual_port_tests = 8; | 17 | my $virtual_port_tests = 8; |
| 17 | my $ssl_only_tests = 12; | 18 | my $ssl_only_tests = 12; |
| 19 | my $chunked_encoding_special_tests = 1; | ||
| 18 | # Check that all dependent modules are available | 20 | # Check that all dependent modules are available |
| 19 | eval "use HTTP::Daemon 6.01;"; | 21 | eval "use HTTP::Daemon 6.01;"; |
| 20 | plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; | 22 | plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; |
| @@ -30,7 +32,7 @@ if ($@) { | |||
| 30 | plan skip_all => "Missing required module for test: $@"; | 32 | plan skip_all => "Missing required module for test: $@"; |
| 31 | } else { | 33 | } else { |
| 32 | if (-x "./$plugin") { | 34 | if (-x "./$plugin") { |
| 33 | plan tests => $common_tests * 2 + $ssl_only_tests + $virtual_port_tests; | 35 | plan tests => $common_tests * 2 + $ssl_only_tests + $virtual_port_tests + $chunked_encoding_special_tests; |
| 34 | } else { | 36 | } else { |
| 35 | plan skip_all => "No $plugin compiled"; | 37 | plan skip_all => "No $plugin compiled"; |
| 36 | } | 38 | } |
| @@ -51,6 +53,7 @@ my $port_http = 50000 + int(rand(1000)); | |||
| 51 | my $port_https = $port_http + 1; | 53 | my $port_https = $port_http + 1; |
| 52 | my $port_https_expired = $port_http + 2; | 54 | my $port_https_expired = $port_http + 2; |
| 53 | my $port_https_clientcert = $port_http + 3; | 55 | my $port_https_clientcert = $port_http + 3; |
| 56 | my $port_hacked_http = $port_http + 4; | ||
| 54 | 57 | ||
| 55 | # This array keeps sockets around for implementing timeouts | 58 | # This array keeps sockets around for implementing timeouts |
| 56 | my @persist; | 59 | my @persist; |
| @@ -72,6 +75,28 @@ if (!$pid) { | |||
| 72 | } | 75 | } |
| 73 | push @pids, $pid; | 76 | push @pids, $pid; |
| 74 | 77 | ||
| 78 | # Fork the hacked HTTP server | ||
| 79 | undef $pid; | ||
| 80 | $pid = fork; | ||
| 81 | defined $pid or die "Failed to fork"; | ||
| 82 | if (!$pid) { | ||
| 83 | # this is the fork | ||
| 84 | undef @pids; | ||
| 85 | my $socket = new IO::Socket::INET ( | ||
| 86 | LocalHost => '0.0.0.0', | ||
| 87 | LocalPort => $port_hacked_http, | ||
| 88 | Proto => 'tcp', | ||
| 89 | Listen => 5, | ||
| 90 | Reuse => 1 | ||
| 91 | ); | ||
| 92 | die "cannot create socket $!n" unless $socket; | ||
| 93 | my $local_sock = $socket->sockport(); | ||
| 94 | print "server waiting for client connection on port $local_sock\n"; | ||
| 95 | run_hacked_http_server ( $socket ); | ||
| 96 | die "hacked http server stopped"; | ||
| 97 | } | ||
| 98 | push @pids, $pid; | ||
| 99 | |||
| 75 | if (exists $servers->{https}) { | 100 | if (exists $servers->{https}) { |
| 76 | # Fork a normal HTTPS server | 101 | # Fork a normal HTTPS server |
| 77 | $pid = fork; | 102 | $pid = fork; |
| @@ -207,6 +232,37 @@ sub run_server { | |||
| 207 | } | 232 | } |
| 208 | } | 233 | } |
| 209 | 234 | ||
| 235 | sub run_hacked_http_server { | ||
| 236 | my $socket = shift; | ||
| 237 | |||
| 238 | # auto-flush on socket | ||
| 239 | $| = 1; | ||
| 240 | |||
| 241 | |||
| 242 | while(1) | ||
| 243 | { | ||
| 244 | # waiting for a new client connection | ||
| 245 | my $client_socket = $socket->accept(); | ||
| 246 | |||
| 247 | # get information about a newly connected client | ||
| 248 | my $client_address = $client_socket->peerhost(); | ||
| 249 | my $client_portn = $client_socket->peerport(); | ||
| 250 | print "connection from $client_address:$client_portn"; | ||
| 251 | |||
| 252 | # read up to 1024 characters from the connected client | ||
| 253 | my $data = ""; | ||
| 254 | $client_socket->recv($data, 1024); | ||
| 255 | print "received data: $data"; | ||
| 256 | |||
| 257 | # write response data to the connected client | ||
| 258 | $data = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"; | ||
| 259 | $client_socket->send($data); | ||
| 260 | |||
| 261 | # notify client that response has been sent | ||
| 262 | shutdown($client_socket, 1); | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 210 | END { | 266 | END { |
| 211 | foreach my $pid (@pids) { | 267 | foreach my $pid (@pids) { |
| 212 | if ($pid) { print "Killing $pid\n"; kill "INT", $pid } | 268 | if ($pid) { print "Killing $pid\n"; kill "INT", $pid } |
| @@ -222,6 +278,7 @@ if ($ARGV[0] && $ARGV[0] eq "-d") { | |||
| 222 | my $result; | 278 | my $result; |
| 223 | my $command = "./$plugin -H 127.0.0.1"; | 279 | my $command = "./$plugin -H 127.0.0.1"; |
| 224 | 280 | ||
| 281 | run_chunked_encoding_special_test( {command => "$command -p $port_hacked_http"}); | ||
| 225 | run_common_tests( { command => "$command -p $port_http" } ); | 282 | run_common_tests( { command => "$command -p $port_http" } ); |
| 226 | SKIP: { | 283 | SKIP: { |
| 227 | skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; | 284 | skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; |
| @@ -511,3 +568,14 @@ sub run_common_tests { | |||
| 511 | }; | 568 | }; |
| 512 | is( $@, "", $cmd ); | 569 | is( $@, "", $cmd ); |
| 513 | } | 570 | } |
| 571 | |||
| 572 | sub run_chunked_encoding_special_test { | ||
| 573 | my ($opts) = @_; | ||
| 574 | my $command = $opts->{command}; | ||
| 575 | |||
| 576 | $cmd = "$command -u / -s 'ChunkedEncodingSpecialTest'"; | ||
| 577 | eval { | ||
| 578 | $result = NPTest->testCmd( $cmd, 5 ); | ||
| 579 | }; | ||
| 580 | is( $@, "", $cmd ); | ||
| 581 | } | ||
