From e0b30cc6e82113491261c872a371a2fa0b4db3ba Mon Sep 17 00:00:00 2001 From: Ahmet Oeztuerk Date: Thu, 4 Dec 2025 16:52:55 +0100 Subject: append the query string from parsed uri Check the UriUriA object, and if query string exists append it to the new_url. Only appends the query part, fragments are still not appended Function redir parses the new location header value using the uriParseUriA function already, which populates the query field. This field was already being printed, but it was not being appended to the new_url during its construction. Redirection chain of check_curl --onredirect=follow now mimics the chain of check_http --onredirect=follow. Tested on the url: mail.google.com/chat --- plugins/check_curl.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/plugins/check_curl.c b/plugins/check_curl.c index e3e514ff..ca6357a7 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -761,7 +761,7 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config } /* compose new path */ - /* TODO: handle fragments and query part of URL */ + /* TODO: handle fragments of URL */ char *new_url = (char *)calloc(1, DEFAULT_BUFFER_SIZE); if (uri.pathHead) { for (UriPathSegmentA *pathSegment = uri.pathHead; pathSegment; @@ -772,6 +772,25 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config } } + /* missing components have null,null in their UriTextRangeA + * add query parameters if they exist. + */ + if (uri.query.first && uri.query.afterLast){ + // Ensure we have space for '?' + query_str + '\0' ahead of time, instead of calling strncat twice + size_t current_len = strlen(new_url); + size_t remaining_space = DEFAULT_BUFFER_SIZE - current_len - 1; + + const char* query_str = uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE); + size_t query_str_len = strlen(query_str); + + if (remaining_space >= query_str_len + 1) { + strcat(new_url, "?"); + strcat(new_url, query_str); + }else{ + die(STATE_UNKNOWN, _("HTTP UNKNOWN - No space to add query part of size %d to the buffer, buffer has remaining size %d"), query_str_len , current_len ); + } + } + if (working_state.serverPort == new_port && !strncmp(working_state.server_address, new_host, MAX_IPV4_HOSTLENGTH) && (working_state.host_name && -- cgit v1.2.3-74-g34f1 From f7df5579ab1d029eeaad785a6d016884c8f36c7d Mon Sep 17 00:00:00 2001 From: Ahmet Oeztuerk Date: Tue, 9 Dec 2025 00:11:20 +0100 Subject: check_curl add tests for uri field parsing plugins/tests/check_curl.t forks and runs a http(s) server that responds to specific uri endpoints. Added another endpoint under /redirect_with_increment with dynamic redirection points. This endpoint will parse different parts of the uri that come after the path: parameters, query and the fragment. If applicable, seperate elements within each field are parsed into key/value pairs. value is incremented in redirected URI. Tests if check_url redirection logic retains different parts of the url when parsing the uri and building the new redirected URL. Current tests show that it ignores the fragment part. --- plugins/tests/check_curl.t | 194 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 1 deletion(-) diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index 52c5ad1c..bc0101a2 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t @@ -20,6 +20,11 @@ use Test::More; use NPTest; use FindBin qw($Bin); +use URI; +use URI::QueryParam; +use HTTP::Daemon; +use HTTP::Daemon::SSL; + $ENV{'LC_TIME'} = "C"; my $common_tests = 75; @@ -186,6 +191,149 @@ sub run_server { $c->send_response('moved to /redirect2'); } elsif ($r->url->path eq "/redir_timeout") { $c->send_redirect( "/timeout" ); + } elsif ($r->url->path =~ m{^/redirect_with_increment}) { + # ://:@:/;?# + # Find every parameter, query , and fragment keys and increment them + + my $content = ""; + + # Use URI to help with query/fragment; parse path params manually. + my $original_url = $r->url->as_string; + $content .= " original_url: ${original_url}\n"; + my $uri = URI->new($original_url); + $content .= " uri: ${uri}\n"; + + my $path = $uri->path // ''; + my $query = $uri->query // ''; + my $fragment = $uri->fragment // ''; + + $content .= " path: ${path}\n"; + $content .= " query: ${query}\n"; + $content .= " fragment: ${fragment}\n"; + + # Sets and returns the scheme-specific part of the $uri (everything between the scheme and the fragment) as an escaped string. + #my $opaque = $uri->opaque; + #$content .= " opaque: ${opaque}\n"; + + # group 1 is captured: anything that is not '/' : ([^/]*) + # / matches the / directly + # group 2 is captured: anything : (.*) + #my ($before_slash, $after_slash) = $opaque =~ m{^/([^/]*)/(.*)$}; + #$before_slash //= ''; + #$after_slash //= ''; + #$content .= " before_slash: ${before_slash}\n"; + #$content .= " after_slash: ${after_slash}\n"; + + # split the uri part and parameters. uri package cannot do this + # group 1 is captured: anything without a semicolon: ([^;]) + # group 2 is uncaptured: (?:;(.*))? + # (? )? prevents the capture + # in between the ';' matches the first ever semicolon + # group3 is captured: any character stirng : (.*) + my ($before_params, $params) = $uri =~ m{^([^;]*)(?:;(.*))?\?}; + $before_params //= ''; + $params //= ''; + $content .= " before_params: ${before_params}\n"; + $content .= " params: ${params}\n"; + my @parameter_pairs; + if (defined $params && length $params) { + for my $p (split /;/, $params) { + my ($key,$value) = split /=/, $p, 2; + $value //= ''; + push @parameter_pairs, [ $key, $value ]; + $content .= " parameter: ${key} -> ${value}\n"; + } + } + + # query parameters are offered directly from the library + my @query_form = $uri->query_form; + my @query_parameter_pairs; + while (@query_form) { + my $key = shift @query_form; + my $value = shift @query_form; + $value //= ''; # there can be valueless keys + push @query_parameter_pairs, [ $key, $value ]; + $content .= " query: ${key} -> ${value}\n"; + } + + # fragment: try to split into key=value pairs on ';' or '&' if present + my @fragment_pairs; + my $fragment_seperator = ''; + if ($fragment ne '') { + $fragment_seperator = ($fragment =~ /&/ ? '&' : ';'); + for my $f (split /[&;]/, $fragment) { + next unless length $f; + my ($key,$value) = split /=/, $f, 2; + $value //= ''; + push @fragment_pairs, [ $key, $value ]; + $content .= " fragment: ${key} -> ${value}\n"; + } + } + + # helper to increment value + my $increment = sub { + my ($v) = @_; + return $v if !defined $v || $v eq ''; + # numeric integer + if ($v =~ /^-?\d+$/) { + return $v + 1; + } + # otherwise -> increment as if its an ascii character + # sed replacement syntax, but the $& holds the matched character + if (length($v)) { + (my $new_v = $v) =~ s/./chr(ord($&) + 1)/ge; + return $new_v; + } + }; + + # increment values in pairs + for my $pair (@parameter_pairs) { + $pair->[1] = $increment->($pair->[1]); + $content .= " parameter new: " . $pair->[0] . " -> " . $pair->[1] . "\n"; + } + for my $pair (@query_parameter_pairs) { + $pair->[1] = $increment->($pair->[1]); + $content .= " query parameter new: " . $pair->[0] . " -> " . $pair->[1] . "\n"; + } + for my $pair (@fragment_pairs) { + $pair->[1] = $increment->($pair->[1]); + $content .= " fragment new: " . $pair->[0] . " -> " . $pair->[1] . "\n"; + } + + # rebuild strings + my $new_parameter_str = join(';', map { $_->[0] . '=' . $_->[1] } @parameter_pairs); + $content .= " new_parameter_str: ${new_parameter_str}\n"; + + # library can rebuild from an array + my @new_query_form; + for my $p (@query_parameter_pairs) { push @new_query_form, $p->[0], $p->[1] } + + my $new_fragment_str = ''; + if (@fragment_pairs) { + $new_fragment_str = join($fragment_seperator, map { $_->[0] . '=' . $_->[1] } @fragment_pairs); + } + $content .= " new_fragment_str: ${new_fragment_str}\n"; + + # construct new URI using the library + my $new_uri = URI->new(''); + $new_uri->path( $before_params . ($new_parameter_str ? ';' . $new_parameter_str : '') ); + $new_uri->query_form( \@new_query_form ) if @new_query_form; + $new_uri->fragment( $new_fragment_str ) if $new_fragment_str ne ''; + $content .= " new_uri: ${new_uri}\n"; + + # Redirect until fail_count or redirect_count reaches 3 + if ($new_uri =~ /fail_count=3/){ + $c->send_error(HTTP::Status->RC_FORBIDDEN, "fail count reached 3, url path:" . $r->url->path ); + } elsif ($new_uri =~ /redirect_count=3/){ + $c->send_response(HTTP::Response->new( 200, 'OK', undef , $content )); + } elsif ($new_uri =~ /location_redirect_count=3/){ + $c->send_basic_header(302); + $c->send_header("Location", "$new_uri" ); + $c->send_crlf; + $c->send_response("$content \n moved to $new_uri"); + } else { + $c->send_redirect( $new_uri->as_string, 301, $content ); + } } elsif ($r->url->path eq "/timeout") { # Keep $c from being destroyed, but prevent severe leaks unshift @persist, $c; @@ -215,7 +363,7 @@ sub run_server { return($chunk); })); } else { - $c->send_error(HTTP::Status->RC_FORBIDDEN); + $c->send_error(HTTP::Status->RC_FORBIDDEN, "unknown url path:" . $r->url->path ); } $c->close; } @@ -482,6 +630,50 @@ sub run_common_tests { is( $result->return_code, 0, $cmd); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); + # Redirect with increment tests. These are for checking if the url parameters, query parameters and fragment are parsed. + # The server at this point has dynamic redirection. It tries to increment values that it sees in these fields, then redirects. + # It also appends some debug log and writes it into HTTP content, pass the -vvv parameter to see them. + + $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2/path3/path4' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 1, $cmd); + like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count was not present, got redirected to / : ".$result->output ); + + $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 0, $cmd); + like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count went up to 3: ".$result->output ); + + $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;location_redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 0, $cmd); + like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); + + $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;fail_count=2' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 1, $cmd); + like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, early due to fail_count reaching 3: ".$result->output ); + + $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 0, $cmd); + like( $result->output, '/.*;p1=3;p2=cd\?*/', "Output correct, parsed and incremented both parameters p1 and p2 : ".$result->output ); + + $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 0, $cmd); + like( $result->output, '/.*\?qp1=12&qp2=mn*/', "Output correct, parsed and incremented both query parameters qp1 and qp2 : ".$result->output ); + + $cmd = "$command -p $port_http -u '/redirect_with_increment;redirect_count=0;?qp0=0&qp1=1&qp2=2&qp3=3&qp4=4&qp5=5' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 0, $cmd); + like( $result->output, '/.*\?qp0=2&qp1=3&qp2=4&qp3=5&qp4=6&qp5=7*/', "Output correct, parsed and incremented query parameters qp1,qp2,qp3,qp4,qp5 in order : ".$result->output ); + + $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $result = NPTest->testCmd( "$cmd" ); + is( $result->return_code, 0, $cmd); + like( $result->output, '/.*#f1=vguv*/', "Output correct, parsed and incremented fragment f1 : ".$result->output ); + # These tests may block # stickyport - on full urlS port is set back to 80 otherwise $cmd = "$command -f stickyport -u /redir_external -t 5 -s redirected"; -- cgit v1.2.3-74-g34f1 From feeade08178ed4874207c90b43e411d986d10cb9 Mon Sep 17 00:00:00 2001 From: Ahmet Oeztuerk Date: Wed, 10 Dec 2025 17:09:46 +0100 Subject: fix typos --- plugins/tests/check_curl.t | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index bc0101a2..af01c97e 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t @@ -229,7 +229,7 @@ sub run_server { # group 2 is uncaptured: (?:;(.*))? # (? )? prevents the capture # in between the ';' matches the first ever semicolon - # group3 is captured: any character stirng : (.*) + # group3 is captured: any character string : (.*) my ($before_params, $params) = $uri =~ m{^([^;]*)(?:;(.*))?\?}; $before_params //= ''; $params //= ''; @@ -258,9 +258,9 @@ sub run_server { # fragment: try to split into key=value pairs on ';' or '&' if present my @fragment_pairs; - my $fragment_seperator = ''; + my $fragment_separator = ''; if ($fragment ne '') { - $fragment_seperator = ($fragment =~ /&/ ? '&' : ';'); + $fragment_separator = ($fragment =~ /&/ ? '&' : ';'); for my $f (split /[&;]/, $fragment) { next unless length $f; my ($key,$value) = split /=/, $f, 2; @@ -310,7 +310,7 @@ sub run_server { my $new_fragment_str = ''; if (@fragment_pairs) { - $new_fragment_str = join($fragment_seperator, map { $_->[0] . '=' . $_->[1] } @fragment_pairs); + $new_fragment_str = join($fragment_separator, map { $_->[0] . '=' . $_->[1] } @fragment_pairs); } $content .= " new_fragment_str: ${new_fragment_str}\n"; -- cgit v1.2.3-74-g34f1 From 737af667a212f7058143b34770f7f0af70aa8d9b Mon Sep 17 00:00:00 2001 From: Ahmet Oeztuerk Date: Thu, 11 Dec 2025 10:05:25 +0100 Subject: clairfy new check_curl tests use the parameters in the last redirected URI that that server returns HTTP OK to. matches the incrementation count of redirection_count from 0 to 3, as they also get incremented three times alongside it. add comments about what is happening in the test cases, no need to understand the endpoint completely --- plugins/tests/check_curl.t | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index af01c97e..374c74b3 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t @@ -224,12 +224,13 @@ sub run_server { #$content .= " before_slash: ${before_slash}\n"; #$content .= " after_slash: ${after_slash}\n"; - # split the uri part and parameters. uri package cannot do this - # group 1 is captured: anything without a semicolon: ([^;]) - # group 2 is uncaptured: (?:;(.*))? - # (? )? prevents the capture - # in between the ';' matches the first ever semicolon + # split the URI part and parameters. URI package cannot do this + # group 1 is captured: anything without a semicolon: ([^;]*) + # group 2 is uncaptured: (?:;(.*))? + # (?: ... )? prevents capturing the parameter section + # inside group 2, ';' matches the first ever semicolon # group3 is captured: any character string : (.*) + # \? matches an actual ? mark, which starts the query parameters my ($before_params, $params) = $uri =~ m{^([^;]*)(?:;(.*))?\?}; $before_params //= ''; $params //= ''; @@ -639,40 +640,53 @@ sub run_common_tests { is( $result->return_code, 1, $cmd); like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count was not present, got redirected to / : ".$result->output ); + # redirect_count=0 is parsed as a parameter and incremented. When it goes up to 3, the redirection returns HTTP OK $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); - like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count went up to 3: ".$result->output ); + like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count went up to 3, and returned OK: ".$result->output ); + # location_redirect_count=0 goes up to 3, which uses the HTTP 302 style of redirection with 'Location' header $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;location_redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); + # fail_count parameter may also go up to 3, which returns a HTTP 403 $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;fail_count=2' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 1, $cmd); like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, early due to fail_count reaching 3: ".$result->output ); + # redirect_count=0, p1=1 , p2=ab => redirect_count=1, p1=2 , p2=bc => redirect_count=2, p1=3 , p2=cd => redirect_count=3 , p1=4 , p2=de + # Last visited URI returns HTTP OK instead of redirect, and the one before that contains the new_uri in its content $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); - like( $result->output, '/.*;p1=3;p2=cd\?*/', "Output correct, parsed and incremented both parameters p1 and p2 : ".$result->output ); + like( $result->output, '/.*redirect_count=3;p1=4;p2=de\?*/', "Output correct, parsed and incremented both parameters p1 and p2 : ".$result->output ); + like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); + # Same incrementation as before, uses the query parameters that come after the first '?' : qp1 and qp2 $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); - like( $result->output, '/.*\?qp1=12&qp2=mn*/', "Output correct, parsed and incremented both query parameters qp1 and qp2 : ".$result->output ); + like( $result->output, '/.*\?qp1=13&qp2=no*/', "Output correct, parsed and incremented both query parameters qp1 and qp2 : ".$result->output ); + like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); + # Check if the query parameter order is kept intact $cmd = "$command -p $port_http -u '/redirect_with_increment;redirect_count=0;?qp0=0&qp1=1&qp2=2&qp3=3&qp4=4&qp5=5' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); - like( $result->output, '/.*\?qp0=2&qp1=3&qp2=4&qp3=5&qp4=6&qp5=7*/', "Output correct, parsed and incremented query parameters qp1,qp2,qp3,qp4,qp5 in order : ".$result->output ); + like( $result->output, '/.*\?qp0=3&qp1=4&qp2=5&qp3=6&qp4=7&qp5=8*/', "Output correct, parsed and incremented query parameters qp1,qp2,qp3,qp4,qp5 in order : ".$result->output ); + like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); + # The fragment is a single item, and it should be kept during redirections as well. + # Increase the chars in strings. 'test' => 'uftu' => 'vguv' => 'whvw' $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); - like( $result->output, '/.*#f1=vguv*/', "Output correct, parsed and incremented fragment f1 : ".$result->output ); + like( $result->output, '/.*#f1=whvw*/', "Output correct, parsed and incremented fragment f1 : ".$result->output ); + like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); # These tests may block # stickyport - on full urlS port is set back to 80 otherwise -- cgit v1.2.3-74-g34f1 From f8db90c206e777a21ff69a301406a11ca627034c Mon Sep 17 00:00:00 2001 From: Ahmet Oeztuerk Date: Fri, 12 Dec 2025 11:16:09 +0100 Subject: check_curl redirection test improvements previously, the fragment was sent in the request from client, and the server would parse and increment its value. the incremented value would be set in the redirected URI. this does not work as fragments are meaningless to servers and clients like check_curl strip them in their GET request. rewrite the fragment handling . if client sends a URI parameter with 'fragment' as its key, the server will set its value for its redirected URI. it will come up both as a parameter and the fragment at the end. use this new logic to rewrite the fragment redirection test. remove -p $http_port argument on tests for this endpoint, which was making https tests fail. correct the common test count from 75 to 95, as there are 20 total test assertions in the 8 times it uses the new endpoint. remove unused code on that endpoint as well --- plugins/tests/check_curl.t | 66 ++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index 374c74b3..248eb4c5 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t @@ -27,7 +27,7 @@ use HTTP::Daemon::SSL; $ENV{'LC_TIME'} = "C"; -my $common_tests = 75; +my $common_tests = 95; my $ssl_only_tests = 8; # Check that all dependent modules are available eval "use HTTP::Daemon 6.01;"; @@ -211,19 +211,6 @@ sub run_server { $content .= " query: ${query}\n"; $content .= " fragment: ${fragment}\n"; - # Sets and returns the scheme-specific part of the $uri (everything between the scheme and the fragment) as an escaped string. - #my $opaque = $uri->opaque; - #$content .= " opaque: ${opaque}\n"; - - # group 1 is captured: anything that is not '/' : ([^/]*) - # / matches the / directly - # group 2 is captured: anything : (.*) - #my ($before_slash, $after_slash) = $opaque =~ m{^/([^/]*)/(.*)$}; - #$before_slash //= ''; - #$after_slash //= ''; - #$content .= " before_slash: ${before_slash}\n"; - #$content .= " after_slash: ${after_slash}\n"; - # split the URI part and parameters. URI package cannot do this # group 1 is captured: anything without a semicolon: ([^;]*) # group 2 is uncaptured: (?:;(.*))? @@ -257,20 +244,6 @@ sub run_server { $content .= " query: ${key} -> ${value}\n"; } - # fragment: try to split into key=value pairs on ';' or '&' if present - my @fragment_pairs; - my $fragment_separator = ''; - if ($fragment ne '') { - $fragment_separator = ($fragment =~ /&/ ? '&' : ';'); - for my $f (split /[&;]/, $fragment) { - next unless length $f; - my ($key,$value) = split /=/, $f, 2; - $value //= ''; - push @fragment_pairs, [ $key, $value ]; - $content .= " fragment: ${key} -> ${value}\n"; - } - } - # helper to increment value my $increment = sub { my ($v) = @_; @@ -296,10 +269,6 @@ sub run_server { $pair->[1] = $increment->($pair->[1]); $content .= " query parameter new: " . $pair->[0] . " -> " . $pair->[1] . "\n"; } - for my $pair (@fragment_pairs) { - $pair->[1] = $increment->($pair->[1]); - $content .= " fragment new: " . $pair->[0] . " -> " . $pair->[1] . "\n"; - } # rebuild strings my $new_parameter_str = join(';', map { $_->[0] . '=' . $_->[1] } @parameter_pairs); @@ -309,9 +278,13 @@ sub run_server { my @new_query_form; for my $p (@query_parameter_pairs) { push @new_query_form, $p->[0], $p->[1] } - my $new_fragment_str = ''; - if (@fragment_pairs) { - $new_fragment_str = join($fragment_separator, map { $_->[0] . '=' . $_->[1] } @fragment_pairs); + my $new_fragment_str = ''; + for my $pair (@parameter_pairs) { + my $key = $pair->[0]; + my $value = $pair->[1]; + if ($key eq "fragment") { + $new_fragment_str = $value + } } $content .= " new_fragment_str: ${new_fragment_str}\n"; @@ -635,57 +608,58 @@ sub run_common_tests { # The server at this point has dynamic redirection. It tries to increment values that it sees in these fields, then redirects. # It also appends some debug log and writes it into HTTP content, pass the -vvv parameter to see them. - $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2/path3/path4' --onredirect=follow -vvv"; + $cmd = "$command -u '/redirect_with_increment/path1/path2/path3/path4' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 1, $cmd); like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count was not present, got redirected to / : ".$result->output ); # redirect_count=0 is parsed as a parameter and incremented. When it goes up to 3, the redirection returns HTTP OK - $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, redirect_count went up to 3, and returned OK: ".$result->output ); # location_redirect_count=0 goes up to 3, which uses the HTTP 302 style of redirection with 'Location' header - $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;location_redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $cmd = "$command -u '/redirect_with_increment/path1/path2;location_redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); # fail_count parameter may also go up to 3, which returns a HTTP 403 - $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;fail_count=2' --onredirect=follow -vvv"; + $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;fail_count=2' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 1, $cmd); like( $result->output, '/.*HTTP/1.1 403 Forbidden - \d+ bytes in [\d\.]+ second.*/', "Output correct, early due to fail_count reaching 3: ".$result->output ); # redirect_count=0, p1=1 , p2=ab => redirect_count=1, p1=2 , p2=bc => redirect_count=2, p1=3 , p2=cd => redirect_count=3 , p1=4 , p2=de # Last visited URI returns HTTP OK instead of redirect, and the one before that contains the new_uri in its content - $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); like( $result->output, '/.*redirect_count=3;p1=4;p2=de\?*/', "Output correct, parsed and incremented both parameters p1 and p2 : ".$result->output ); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); # Same incrementation as before, uses the query parameters that come after the first '?' : qp1 and qp2 - $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); like( $result->output, '/.*\?qp1=13&qp2=no*/', "Output correct, parsed and incremented both query parameters qp1 and qp2 : ".$result->output ); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); # Check if the query parameter order is kept intact - $cmd = "$command -p $port_http -u '/redirect_with_increment;redirect_count=0;?qp0=0&qp1=1&qp2=2&qp3=3&qp4=4&qp5=5' --onredirect=follow -vvv"; + $cmd = "$command -u '/redirect_with_increment;redirect_count=0;?qp0=0&qp1=1&qp2=2&qp3=3&qp4=4&qp5=5' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); like( $result->output, '/.*\?qp0=3&qp1=4&qp2=5&qp3=6&qp4=7&qp5=8*/', "Output correct, parsed and incremented query parameters qp1,qp2,qp3,qp4,qp5 in order : ".$result->output ); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); - # The fragment is a single item, and it should be kept during redirections as well. - # Increase the chars in strings. 'test' => 'uftu' => 'vguv' => 'whvw' - $cmd = "$command -p $port_http -u '/redirect_with_increment/path1/path2;redirect_count=0;p1=1;p2=ab?qp1=10&qp2=kl#f1=test' --onredirect=follow -vvv"; + # The fragment is passed as another parameter. + # During the server redirects the fragment will be set to its value, if such a key is present. + # 'ebiil' => 'fcjjm' => 'gdkkn' => 'hello' + $cmd = "$command -u '/redirect_with_increment/path1/path2;redirect_count=0;fragment=ebiil?qp1=0' --onredirect=follow -vvv"; $result = NPTest->testCmd( "$cmd" ); is( $result->return_code, 0, $cmd); - like( $result->output, '/.*#f1=whvw*/', "Output correct, parsed and incremented fragment f1 : ".$result->output ); + like( $result->output, '/.*redirect_count=3;fragment=hello\?qp1=3#hello*/', "Output correct, fragments are specified by server and followed by check_curl: ".$result->output ); like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct, location_redirect_count went up to 3: ".$result->output ); # These tests may block -- cgit v1.2.3-74-g34f1