summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2011-09-06 23:25:28 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2011-09-06 23:25:28 +0000
commit623ad7714ed80140644dcbad304da9f438e6ea57 (patch)
tree22dea30bfd71a033cda7d3d44461ce531a661ae7
parented28873b8fc96feea6ecebe36849b6c04861f387 (diff)
Add test for http chunked encoding over relayd http protocol.
-rw-r--r--regress/usr.sbin/relayd/args-http-chunked.pl26
-rw-r--r--regress/usr.sbin/relayd/funcs.pl88
2 files changed, 106 insertions, 8 deletions
diff --git a/regress/usr.sbin/relayd/args-http-chunked.pl b/regress/usr.sbin/relayd/args-http-chunked.pl
new file mode 100644
index 00000000000..5bb2f56be9c
--- /dev/null
+++ b/regress/usr.sbin/relayd/args-http-chunked.pl
@@ -0,0 +1,26 @@
+# test chunked http 1.1 connection over http relay
+
+use strict;
+use warnings;
+
+my @lengths = ([ 251, 10000, 10 ], 1, [2, 3]);
+our %args = (
+ client => {
+ func => \&http_client,
+ lengths => \@lengths,
+ },
+ relayd => {
+ protocol => [ "http",
+ "request header log foo",
+ "response header log Transfer-Encoding",
+ ],
+ loggrep => "log 'Transfer-Encoding: chunked'",
+ },
+ server => {
+ func => \&http_server,
+ },
+ lengths => \@lengths,
+ md5 => "bc3a3f39af35fe5b1687903da2b00c7f",
+);
+
+1;
diff --git a/regress/usr.sbin/relayd/funcs.pl b/regress/usr.sbin/relayd/funcs.pl
index 4c12ef875b0..106376b1386 100644
--- a/regress/usr.sbin/relayd/funcs.pl
+++ b/regress/usr.sbin/relayd/funcs.pl
@@ -1,4 +1,4 @@
-# $OpenBSD: funcs.pl,v 1.4 2011/09/02 21:05:41 bluhm Exp $
+# $OpenBSD: funcs.pl,v 1.5 2011/09/06 23:25:27 bluhm Exp $
# Copyright (c) 2010,2011 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -90,9 +90,10 @@ sub http_client {
my $method = $self->{method} || "GET";
foreach my $len (@lengths) {
+ my $path = ref($len) eq 'ARRAY' ? join("/", @$len) : $len;
{
local $\ = "\r\n";
- print "$method /$len HTTP/$vers";
+ print "$method /$path HTTP/$vers";
print "Host: foo.bar";
print "Content-Length: $len"
if $vers eq "1.1" && $method eq "PUT";
@@ -101,6 +102,7 @@ sub http_client {
write_char($self, $len) if $method eq "PUT";
IO::Handle::flush(\*STDOUT);
+ my $chunked = 0;
{
local $\ = "\n";
local $/ = "\r\n";
@@ -117,10 +119,56 @@ sub http_client {
$1 == $len or die ref($self),
" bad content length $1";
}
+ if (/^Transfer-Encoding: chunked$/) {
+ $chunked = 1;
+ }
}
}
- read_char($self, $vers eq "1.1" ? $len : undef)
- if $method eq "GET";
+ if ($chunked) {
+ read_chunked($self);
+ } else {
+ read_char($self, $vers eq "1.1" ? $len : undef)
+ if $method eq "GET";
+ }
+ }
+}
+
+sub read_chunked {
+ my $self = shift;
+
+ for (;;) {
+ my $len;
+ {
+ local $\ = "\n";
+ local $/ = "\r\n";
+ local $_ = <STDIN>;
+ defined or die ref($self), " missing chunk size";
+ chomp;
+ print STDERR;
+ /^[[:xdigit:]]+$/
+ or die ref($self), " chunk size not hex: $_";
+ $len = hex;
+ }
+ last unless $len > 0;
+ read_char($self, $len);
+ {
+ local $\ = "\n";
+ local $/ = "\r\n";
+ local $_ = <STDIN>;
+ defined or die ref($self), " missing chunk data end";
+ chomp;
+ /^$/ or die ref($self), " no chunk data end: $_";
+ }
+ }
+ {
+ local $\ = "\n";
+ local $/ = "\r\n";
+ while (<STDIN>) {
+ chomp;
+ last if /^$/;
+ print STDERR;
+ }
+ defined or die ref($self), " missing chunk trailer";
}
}
@@ -185,7 +233,8 @@ sub http_server {
or die ref($self), " http request not ok";
$method =~ /^(GET|PUT)$/
or die ref($self), " unknown method: $method";
- ($len) = $url =~ /(\d+)$/;
+ ($len, my @chunks) = $url =~ /(\d+)/g;
+ $len = [ $len, @chunks ] if @chunks;
while (<STDIN>) {
chomp;
last if /^$/;
@@ -202,13 +251,36 @@ sub http_server {
{
local $\ = "\r\n";
print "HTTP/$vers 200 OK";
- print "Content-Length: $len"
- if $vers eq "1.1" && $method eq "GET";
+ if (ref($len) eq 'ARRAY') {
+ print "Transfer-Encoding: chunked"
+ if $vers eq "1.1";
+ } else {
+ print "Content-Length: $len"
+ if $vers eq "1.1" && $method eq "GET";
+ }
print "";
}
- write_char($self, $len) if $method eq "GET";
+ if (ref($len) eq 'ARRAY') {
+ write_chunked($self, @$len);
+ } else {
+ write_char($self, $len) if $method eq "GET";
+ }
IO::Handle::flush(\*STDOUT);
} while ($vers eq "1.1");
}
+sub write_chunked {
+ my $self = shift;
+ my @chunks = @_;
+
+ foreach my $len (@chunks) {
+ printf "%x\r\n", $len;
+ write_char($self, $len);
+ print "\r\n";
+ }
+ print "0\r\n";
+ print "X-Chunk-Trailer: @chunks\r\n";
+ print "\r\n";
+}
+
1;