Add tests to exercise the recent bug fixes.
authormillert <millert@openbsd.org>
Fri, 1 Dec 2023 16:49:16 +0000 (16:49 +0000)
committermillert <millert@openbsd.org>
Fri, 1 Dec 2023 16:49:16 +0000 (16:49 +0000)
regress/usr.sbin/relayd/args-http-chunked-invalid.pl [new file with mode: 0644]
regress/usr.sbin/relayd/args-http-contentlength-get.pl [new file with mode: 0644]
regress/usr.sbin/relayd/args-http-contentlength-invalid.pl [new file with mode: 0644]
regress/usr.sbin/relayd/args-http-invalid-header1.pl [new file with mode: 0644]
regress/usr.sbin/relayd/args-http-invalid-header2.pl [new file with mode: 0644]

diff --git a/regress/usr.sbin/relayd/args-http-chunked-invalid.pl b/regress/usr.sbin/relayd/args-http-chunked-invalid.pl
new file mode 100644 (file)
index 0000000..ffe0751
--- /dev/null
@@ -0,0 +1,52 @@
+# Test parsing of invalid chunk length values
+# We force multiple connections since relayd will abort the connection
+# when it encounters a bogus chunk size.
+# 
+
+use strict;
+use warnings;
+
+my @lengths = (7, 6, 5, 4, 3, 2);
+my @chunks = ("0x4", "+3", "-0", "foo", "dead beef", "Ff0");
+our %args = (
+    client => {
+       func => sub {
+           my $self = shift;
+           my $chunk = shift(@chunks);
+           $self->{redo} = int(@chunks);
+           print <<"EOF";
+PUT /4/3 HTTP/1.1
+Host: foo.bar
+Transfer-Encoding: chunked
+
+$chunk
+
+EOF
+           foreach (@lengths) {
+               print STDERR "LEN: $_\n";
+           }
+           # relayd does not forward the first chunk if the second one
+           # is invalid.  So do not expect any response.
+           #http_response($self, "without len");
+       },
+       http_vers => ["1.1"],
+       lengths => \@lengths,
+       method => "PUT",
+    },
+    relayd => {
+       protocol => [ "http",
+           "match request header log foo",
+           "match response header log bar",
+       ],
+       loggrep => {
+           qr/, invalid chunk size, PUT/ => 5,
+       },
+    },
+    server => {
+       func => \&http_server,
+       nocheck => 1,
+    },
+    lengths => \@lengths,
+);
+
+1;
diff --git a/regress/usr.sbin/relayd/args-http-contentlength-get.pl b/regress/usr.sbin/relayd/args-http-contentlength-get.pl
new file mode 100644 (file)
index 0000000..01dfa22
--- /dev/null
@@ -0,0 +1,50 @@
+# Test to verify that relayd strips Content-Length and body
+# from GET requests.
+
+use strict;
+use warnings;
+
+my $payload_len = 64;
+our %args = (
+    client => {
+       func => sub {
+           my $self = shift;
+           my @request_stream = split("\n", <<"EOF", -1);
+GET http://foo.bar/$payload_len HTTP/1.1
+Content-Length: $payload_len
+
+foo=bar
+
+EOF
+           pop @request_stream;
+           print map { "$_\r\n" } @request_stream;
+           print STDERR map { ">>> $_\n" } @request_stream;
+           $self->{method} = 'GET';
+           http_response($self, $payload_len);
+       },
+       loggrep => {
+           qr/Content-Length: $payload_len/ => 2,
+           qr/foo=bar/ => 1,
+       },
+       http_vers => ["1.1"],
+       nocheck => 1,
+    },
+    relayd => {
+       protocol => [ "http",
+           "match request path log \"*\"",
+       ],
+       loggrep => {
+           qr/, done, \[http:\/\/foo.bar\/$payload_len\] GET/ => 1,
+       },
+    },
+    server => {
+       func => \&http_server,
+       loggrep => {
+           qr/Content-Length: $payload_len/ => 1,
+           qr/foo=bar/ => 0,
+       },
+       nocheck => 1,
+    },
+);
+
+1;
diff --git a/regress/usr.sbin/relayd/args-http-contentlength-invalid.pl b/regress/usr.sbin/relayd/args-http-contentlength-invalid.pl
new file mode 100644 (file)
index 0000000..5b7ad2d
--- /dev/null
@@ -0,0 +1,40 @@
+# Test that relayd aborts the connection if Content-Length is invalid
+# We test "+0" because it is accepted by strtol(), sscanf(), etc
+# but is not legal according to the RFC.
+
+use strict;
+use warnings;
+
+our %args = (
+    client => {
+       func => sub {
+           my $self = shift;
+           print <<"EOF";
+PUT /1 HTTP/1.1
+Host: www.foo.com
+Content-Length: +0
+
+EOF
+           # no http_response($self, 1);
+       },
+       http_vers => ["1.1"],
+       nocheck => 1,
+       method => "PUT",
+    },
+    relayd => {
+       protocol => [ "http",
+           "match request header log Host",
+       ],
+       loggrep => {
+           qr/, invalid$/ => 1,
+           qr/\[Host: www.foo.com\] PUT/ => 0,
+       },
+    },
+    server => {
+       func => \&http_server,
+       nocheck => 1,
+       noserver => 1,
+    }
+);
+
+1;
diff --git a/regress/usr.sbin/relayd/args-http-invalid-header1.pl b/regress/usr.sbin/relayd/args-http-invalid-header1.pl
new file mode 100644 (file)
index 0000000..c12f21d
--- /dev/null
@@ -0,0 +1,38 @@
+# Test that relayd aborts the connection if a header name has invalid chars
+
+use strict;
+use warnings;
+
+our %args = (
+    client => {
+       func => sub {
+           my $self = shift;
+           print <<"EOF";
+GET /1 HTTP/1.1
+Host: www.foo.com
+X-Header Client: ABC
+
+EOF
+           # no http_response($self, 1);
+       },
+       http_vers => ["1.1"],
+       nocheck => 1,
+       method => "GET",
+    },
+    relayd => {
+       protocol => [ "http",
+           "match request header log Host",
+       ],
+       loggrep => {
+           qr/, malformed$/ => 1,
+           qr/\[Host: www.foo.com\] GET/ => 0,
+       },
+    },
+    server => {
+       func => \&http_server,
+       nocheck => 1,
+       noserver => 1,
+    }
+);
+
+1;
diff --git a/regress/usr.sbin/relayd/args-http-invalid-header2.pl b/regress/usr.sbin/relayd/args-http-invalid-header2.pl
new file mode 100644 (file)
index 0000000..cb9d8b3
--- /dev/null
@@ -0,0 +1,38 @@
+# Test that relayd aborts the connection if a header include a NUL byte
+
+use strict;
+use warnings;
+
+our %args = (
+    client => {
+       func => sub {
+           my $self = shift;
+           print <<"EOF";
+GET /1 HTTP/1.1
+Host: www.foo.com
+X-Header-Client: ABC\0D
+
+EOF
+           # no http_response($self, 1);
+       },
+       http_vers => ["1.1"],
+       nocheck => 1,
+       method => "GET",
+    },
+    relayd => {
+       protocol => [ "http",
+           "match request header log Host",
+       ],
+       loggrep => {
+           qr/, malformed$/ => 1,
+           qr/\[Host: www.foo.com\] GET/ => 0,
+       },
+    },
+    server => {
+       func => \&http_server,
+       nocheck => 1,
+       noserver => 1,
+    }
+);
+
+1;