diff options
author | Sven Nierlein <sven@consol.de> | 2024-07-29 20:53:32 +0200 |
---|---|---|
committer | Sven Nierlein <sven@nierlein.org> | 2024-07-30 17:13:03 +0200 |
commit | acbfbf3de614f03ea5f9d3942558f1661fc202a4 (patch) | |
tree | c19efcc783679d7f6b3b5686d2111052f3882128 | |
parent | 4ab154d5c3640d7f2cc3180d2f05ac688be7a11b (diff) | |
download | monitoring-plugins-acbfbf3de614f03ea5f9d3942558f1661fc202a4.tar.gz |
check_curl: fix relative redirects on non-standard port
Having a webserver respond with a relative redirect as for ex. in `Location: /path/to.html`
check_curl would use the wrong standard http/https port instead
of crafting the absolute url using the given scheme/hostname and port.
Adding a new test case for this for check_http and check_curl. check_http did
it correct already, so no fix necessary there.
before:
%>./check_curl -H 127.0.0.1 -p 50493 -f follow -u /redirect_rel -s redirected -vvv
**** HEADER ****
HTTP/1.1 302 Found
...
Location: /redirect2
...
* Seen redirect location /redirect2
** scheme: (null)
** host: (null)
** port: (null)
** path: /redirect2
Redirection to http://127.0.0.1:80/redirect2
fixed:
%>./check_curl -H 127.0.0.1 -p 50493 -f follow -u /redirect_rel -s redirected -vvv
**** HEADER ****
HTTP/1.1 302 Found
...
Location: /redirect2
...
* Seen redirect location /redirect2
** scheme: (null)
** host: (null)
** port: (null)
** path: /redirect2
Redirection to http://127.0.0.1:50493/redirect2
Signed-off-by: Sven Nierlein <sven@nierlein.de>
-rw-r--r-- | plugins/check_curl.c | 15 | ||||
-rwxr-xr-x | plugins/tests/check_curl.t | 14 | ||||
-rwxr-xr-x | plugins/tests/check_http.t | 12 |
3 files changed, 32 insertions, 9 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index c54be5e4..01e2770e 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -1285,10 +1285,12 @@ redir (curlhelp_write_curlbuf* header_buf) | |||
1285 | } | 1285 | } |
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | if (!uri_strcmp (uri.scheme, "https")) | 1288 | if (uri.scheme.first) { |
1289 | use_ssl = true; | 1289 | if (!uri_strcmp (uri.scheme, "https")) |
1290 | else | 1290 | use_ssl = true; |
1291 | use_ssl = false; | 1291 | else |
1292 | use_ssl = false; | ||
1293 | } | ||
1292 | 1294 | ||
1293 | /* we do a sloppy test here only, because uriparser would have failed | 1295 | /* we do a sloppy test here only, because uriparser would have failed |
1294 | * above, if the port would be invalid, we just check for MAX_PORT | 1296 | * above, if the port would be invalid, we just check for MAX_PORT |
@@ -1306,10 +1308,13 @@ redir (curlhelp_write_curlbuf* header_buf) | |||
1306 | MAX_PORT, location, display_html ? "</A>" : ""); | 1308 | MAX_PORT, location, display_html ? "</A>" : ""); |
1307 | 1309 | ||
1308 | /* by RFC 7231 relative URLs in Location should be taken relative to | 1310 | /* by RFC 7231 relative URLs in Location should be taken relative to |
1309 | * the original URL, so wy try to form a new absolute URL here | 1311 | * the original URL, so we try to form a new absolute URL here |
1310 | */ | 1312 | */ |
1311 | if (!uri.scheme.first && !uri.hostText.first) { | 1313 | if (!uri.scheme.first && !uri.hostText.first) { |
1312 | new_host = strdup (host_name ? host_name : server_address); | 1314 | new_host = strdup (host_name ? host_name : server_address); |
1315 | new_port = server_port; | ||
1316 | if(use_ssl) | ||
1317 | uri_string (uri.scheme, "https", DEFAULT_BUFFER_SIZE); | ||
1313 | } else { | 1318 | } else { |
1314 | new_host = strdup (uri_string (uri.hostText, buf, DEFAULT_BUFFER_SIZE)); | 1319 | new_host = strdup (uri_string (uri.hostText, buf, DEFAULT_BUFFER_SIZE)); |
1315 | } | 1320 | } |
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index 3c914830..eaa9f518 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t | |||
@@ -21,7 +21,7 @@ use FindBin qw($Bin); | |||
21 | 21 | ||
22 | $ENV{'LC_TIME'} = "C"; | 22 | $ENV{'LC_TIME'} = "C"; |
23 | 23 | ||
24 | my $common_tests = 73; | 24 | my $common_tests = 75; |
25 | my $ssl_only_tests = 8; | 25 | my $ssl_only_tests = 8; |
26 | # Check that all dependent modules are available | 26 | # Check that all dependent modules are available |
27 | eval "use HTTP::Daemon 6.01;"; | 27 | eval "use HTTP::Daemon 6.01;"; |
@@ -178,6 +178,11 @@ sub run_server { | |||
178 | $c->send_basic_header; | 178 | $c->send_basic_header; |
179 | $c->send_crlf; | 179 | $c->send_crlf; |
180 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); | 180 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); |
181 | } elsif ($r->url->path eq "/redirect_rel") { | ||
182 | $c->send_basic_header(302); | ||
183 | $c->send_header("Location", "/redirect2" ); | ||
184 | $c->send_crlf; | ||
185 | $c->send_response('moved to /redirect2'); | ||
181 | } elsif ($r->url->path eq "/redir_timeout") { | 186 | } elsif ($r->url->path eq "/redir_timeout") { |
182 | $c->send_redirect( "/timeout" ); | 187 | $c->send_redirect( "/timeout" ); |
183 | } elsif ($r->url->path eq "/timeout") { | 188 | } elsif ($r->url->path eq "/timeout") { |
@@ -471,9 +476,12 @@ sub run_common_tests { | |||
471 | is( $result->return_code, 0, $cmd); | 476 | is( $result->return_code, 0, $cmd); |
472 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 477 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); |
473 | 478 | ||
474 | # These tests may block | 479 | $cmd = "$command -f follow -u /redirect_rel -s redirected"; |
475 | print "ALRM\n"; | 480 | $result = NPTest->testCmd( $cmd ); |
481 | is( $result->return_code, 0, $cmd); | ||
482 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | ||
476 | 483 | ||
484 | # These tests may block | ||
477 | # stickyport - on full urlS port is set back to 80 otherwise | 485 | # stickyport - on full urlS port is set back to 80 otherwise |
478 | $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected"; | 486 | $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected"; |
479 | eval { | 487 | eval { |
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t index 6078b274..6eaf85b2 100755 --- a/plugins/tests/check_http.t +++ b/plugins/tests/check_http.t | |||
@@ -13,7 +13,7 @@ use IO::Socket::INET; | |||
13 | 13 | ||
14 | $ENV{'LC_TIME'} = "C"; | 14 | $ENV{'LC_TIME'} = "C"; |
15 | 15 | ||
16 | my $common_tests = 71; | 16 | my $common_tests = 73; |
17 | my $virtual_port_tests = 8; | 17 | my $virtual_port_tests = 8; |
18 | my $ssl_only_tests = 12; | 18 | my $ssl_only_tests = 12; |
19 | my $chunked_encoding_special_tests = 1; | 19 | my $chunked_encoding_special_tests = 1; |
@@ -199,6 +199,11 @@ sub run_server { | |||
199 | $c->send_basic_header; | 199 | $c->send_basic_header; |
200 | $c->send_crlf; | 200 | $c->send_crlf; |
201 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); | 201 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); |
202 | } elsif ($r->url->path eq "/redirect_rel") { | ||
203 | $c->send_basic_header(302); | ||
204 | $c->send_header("Location", "/redirect2" ); | ||
205 | $c->send_crlf; | ||
206 | $c->send_response('moved to /redirect2'); | ||
202 | } elsif ($r->url->path eq "/redir_timeout") { | 207 | } elsif ($r->url->path eq "/redir_timeout") { |
203 | $c->send_redirect( "/timeout" ); | 208 | $c->send_redirect( "/timeout" ); |
204 | } elsif ($r->url->path eq "/timeout") { | 209 | } elsif ($r->url->path eq "/timeout") { |
@@ -515,6 +520,11 @@ sub run_common_tests { | |||
515 | is( $result->return_code, 0, $cmd); | 520 | is( $result->return_code, 0, $cmd); |
516 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | 521 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); |
517 | 522 | ||
523 | $cmd = "$command -f follow -u /redirect_rel -s redirected"; | ||
524 | $result = NPTest->testCmd( $cmd ); | ||
525 | is( $result->return_code, 0, $cmd); | ||
526 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | ||
527 | |||
518 | # These tests may block | 528 | # These tests may block |
519 | print "ALRM\n"; | 529 | print "ALRM\n"; |
520 | 530 | ||