summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenz <12514511+RincewindsHat@users.noreply.github.com>2023-02-06 12:06:10 (GMT)
committerGitHub <noreply@github.com>2023-02-06 12:06:10 (GMT)
commite0dfb0622d19a4b4340dab9a315cb4b649f6f1e4 (patch)
tree21ccc76338be77623013b0cb0ce6f472381340e3
parent843f17918886edd5c8d14e5a9967785c654053c8 (diff)
parent03efbb8e4f736bf2df5d9477dd4191501fe035ea (diff)
downloadmonitoring-plugins-e0dfb06.tar.gz
Merge pull request #1840 from RincewindsHat/check_http_end_chunk_only
check_http: fix for single zero size chunk only
-rw-r--r--plugins/check_http.c8
-rwxr-xr-xplugins/tests/check_http.t70
2 files changed, 76 insertions, 2 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 5fa310f..8dda046 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 d766ac3..6078b27 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -9,12 +9,14 @@ use strict;
9use Test::More; 9use Test::More;
10use NPTest; 10use NPTest;
11use FindBin qw($Bin); 11use FindBin qw($Bin);
12use IO::Socket::INET;
12 13
13$ENV{'LC_TIME'} = "C"; 14$ENV{'LC_TIME'} = "C";
14 15
15my $common_tests = 71; 16my $common_tests = 71;
16my $virtual_port_tests = 8; 17my $virtual_port_tests = 8;
17my $ssl_only_tests = 12; 18my $ssl_only_tests = 12;
19my $chunked_encoding_special_tests = 1;
18# Check that all dependent modules are available 20# Check that all dependent modules are available
19eval "use HTTP::Daemon 6.01;"; 21eval "use HTTP::Daemon 6.01;";
20plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; 22plan 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));
51my $port_https = $port_http + 1; 53my $port_https = $port_http + 1;
52my $port_https_expired = $port_http + 2; 54my $port_https_expired = $port_http + 2;
53my $port_https_clientcert = $port_http + 3; 55my $port_https_clientcert = $port_http + 3;
56my $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
56my @persist; 59my @persist;
@@ -72,6 +75,28 @@ if (!$pid) {
72} 75}
73push @pids, $pid; 76push @pids, $pid;
74 77
78# Fork the hacked HTTP server
79undef $pid;
80$pid = fork;
81defined $pid or die "Failed to fork";
82if (!$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}
98push @pids, $pid;
99
75if (exists $servers->{https}) { 100if (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
235sub 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
210END { 266END {
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") {
222my $result; 278my $result;
223my $command = "./$plugin -H 127.0.0.1"; 279my $command = "./$plugin -H 127.0.0.1";
224 280
281run_chunked_encoding_special_test( {command => "$command -p $port_hacked_http"});
225run_common_tests( { command => "$command -p $port_http" } ); 282run_common_tests( { command => "$command -p $port_http" } );
226SKIP: { 283SKIP: {
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
572sub 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}