diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2014-07-10 10:19:07 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2014-07-10 10:19:07 +0000 |
commit | 73ac7722a47d9b9cea265bc7cd8dbfbb379f5c14 (patch) | |
tree | b5c2df1dd6fcffafe16f127e590027c1372d9a77 /regress/usr.sbin | |
parent | 675ce59274a23b6e8ede817c06c34b853f5ceeff (diff) |
Implement non-persistent connections in a cleaner way. Every test
that offers multiple requets per HTTP connection is run twice.
First all requests are run over a single TCP connection. Then for
each requests a separate TCP connection is established. If a
requests during a persistent connection fails, a reconnect is done
as relayd cancels the whole connection. This allows stricter tests
for filters.
OK reyk@
Diffstat (limited to 'regress/usr.sbin')
21 files changed, 145 insertions, 218 deletions
diff --git a/regress/usr.sbin/relayd/Client.pm b/regress/usr.sbin/relayd/Client.pm index 37cfa40b130..97a525ad645 100644 --- a/regress/usr.sbin/relayd/Client.pm +++ b/regress/usr.sbin/relayd/Client.pm @@ -1,4 +1,4 @@ -# $OpenBSD: Client.pm,v 1.6 2014/07/09 16:48:55 reyk Exp $ +# $OpenBSD: Client.pm,v 1.7 2014/07/10 10:19:06 bluhm Exp $ # Copyright (c) 2010-2012 Alexander Bluhm <bluhm@openbsd.org> # @@ -44,10 +44,10 @@ sub new { sub child { my $self = shift; - if ($self->{mreqs}) { - print STDERR "connection per request\n"; - return; - } + # in case we redo the connect, shutdown the old one + shutdown(\*STDOUT, SHUT_WR); + delete $self->{cs}; + $SSL_ERROR = ""; my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6"; my $cs = $iosocket->new( @@ -59,7 +59,6 @@ sub child { ) or die ref($self), " $iosocket socket connect failed: $!,$SSL_ERROR"; print STDERR "connect sock: ",$cs->sockhost()," ",$cs->sockport(),"\n"; print STDERR "connect peer: ",$cs->peerhost()," ",$cs->peerport(),"\n"; - print STDERR "single connection\n"; *STDIN = *STDOUT = $self->{cs} = $cs; } diff --git a/regress/usr.sbin/relayd/Proc.pm b/regress/usr.sbin/relayd/Proc.pm index d4e23869876..11420053489 100644 --- a/regress/usr.sbin/relayd/Proc.pm +++ b/regress/usr.sbin/relayd/Proc.pm @@ -1,4 +1,4 @@ -# $OpenBSD: Proc.pm,v 1.7 2014/05/12 21:30:42 andre Exp $ +# $OpenBSD: Proc.pm,v 1.8 2014/07/10 10:19:06 bluhm Exp $ # Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org> # @@ -101,9 +101,11 @@ sub run { or die ref($self), " dup STDIN failed: $!"; close($reader); - $self->child(); - print STDERR $self->{up}, "\n"; - $self->{func}->($self); + do { + $self->child(); + print STDERR $self->{up}, "\n"; + $self->{func}->($self); + } while ($self->{redo}); print STDERR "Shutdown", "\n"; IO::Handle::flush(\*STDOUT); IO::Handle::flush(\*STDERR); diff --git a/regress/usr.sbin/relayd/Server.pm b/regress/usr.sbin/relayd/Server.pm index 7bb2923f25a..70a492aeb79 100644 --- a/regress/usr.sbin/relayd/Server.pm +++ b/regress/usr.sbin/relayd/Server.pm @@ -1,4 +1,4 @@ -# $OpenBSD: Server.pm,v 1.5 2014/07/09 16:48:55 reyk Exp $ +# $OpenBSD: Server.pm,v 1.6 2014/07/10 10:19:06 bluhm Exp $ # Copyright (c) 2010-2012 Alexander Bluhm <bluhm@openbsd.org> # @@ -58,16 +58,15 @@ sub new { sub child { my $self = shift; - if ($self->{mreqs}) { - print STDERR "connection per request\n"; - return; - } + # in case we redo the accept, shutdown the old one + shutdown(\*STDOUT, SHUT_WR); + delete $self->{as}; + my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6"; my $as = $self->{ls}->accept() or die ref($self), " $iosocket socket accept failed: $!"; print STDERR "accept sock: ",$as->sockhost()," ",$as->sockport(),"\n"; print STDERR "accept peer: ",$as->peerhost()," ",$as->peerport(),"\n"; - print STDERR "single connection\n"; *STDIN = *STDOUT = $self->{as} = $as; } diff --git a/regress/usr.sbin/relayd/args-http-append.pl b/regress/usr.sbin/relayd/args-http-append.pl index bc6727c749a..3fae3331ed8 100644 --- a/regress/usr.sbin/relayd/args-http-append.pl +++ b/regress/usr.sbin/relayd/args-http-append.pl @@ -5,8 +5,9 @@ our %args = ( client => { func => \&http_client, len => 1, - loggrep => { 'X-Server-Append: \d+\.\d+\.\d+\.\d+:\d+$' => 1, - 'Set-Cookie: a=b\;' => 1, + loggrep => { + 'X-Server-Append: \d+\.\d+\.\d+\.\d+:\d+$' => 1, + 'Set-Cookie: a=b\;' => 1, }, }, relayd => { diff --git a/regress/usr.sbin/relayd/args-http-chunked.pl b/regress/usr.sbin/relayd/args-http-chunked.pl index 2fdcb98978e..a6f13bb4e91 100644 --- a/regress/usr.sbin/relayd/args-http-chunked.pl +++ b/regress/usr.sbin/relayd/args-http-chunked.pl @@ -8,7 +8,7 @@ our %args = ( client => { func => \&http_client, lengths => \@lengths, - mreqs => 1, + http_vers => ["1.1"], }, relayd => { protocol => [ "http", @@ -16,13 +16,12 @@ our %args = ( "match response header log Transfer-Encoding", ], loggrep => { - "Transfer-Encoding: chunked" => 2, + "Transfer-Encoding: chunked" => 1, qr/\[\(null\)\]/ => 0, }, }, server => { func => \&http_server, - mreqs => scalar(@lengths), }, lengths => \@lengths, md5 => "bc3a3f39af35fe5b1687903da2b00c7f", diff --git a/regress/usr.sbin/relayd/args-http-contentlength.pl b/regress/usr.sbin/relayd/args-http-contentlength.pl index 17db74b1de7..0ec36d47b8d 100644 --- a/regress/usr.sbin/relayd/args-http-contentlength.pl +++ b/regress/usr.sbin/relayd/args-http-contentlength.pl @@ -8,7 +8,6 @@ our %args = ( client => { func => \&http_client, lengths => \@lengths, - mreqs => 1, }, relayd => { protocol => [ "http", @@ -19,8 +18,8 @@ our %args = ( }, server => { func => \&http_server, - mreqs => scalar(@lengths), }, + lengths => \@lengths, ); 1; diff --git a/regress/usr.sbin/relayd/args-http-expect.pl b/regress/usr.sbin/relayd/args-http-expect.pl index 8a8c7dd39ad..710ed854c45 100644 --- a/regress/usr.sbin/relayd/args-http-expect.pl +++ b/regress/usr.sbin/relayd/args-http-expect.pl @@ -15,7 +15,7 @@ our %args = ( 'pass query log "foo" value "bar"', ], loggrep => { - qr/\[foo: bar\]/ => 1, + qr/\[foo: bar\]/ => 2, qr/\[ok: yes\]/ => 0, }, }, diff --git a/regress/usr.sbin/relayd/args-http-filter-block.pl b/regress/usr.sbin/relayd/args-http-filter-block.pl index a3bf1ec66c2..340853ea25e 100644 --- a/regress/usr.sbin/relayd/args-http-filter-block.pl +++ b/regress/usr.sbin/relayd/args-http-filter-block.pl @@ -6,10 +6,9 @@ use warnings; my @lengths = (1, 2, 0, 3); our %args = ( client => { - func => sub { eval { http_client(@_) }; warn $@ }, + func => \&http_client, loggrep => qr/Client missing http 3 response/, - lengths => \@lengths, - mreqs => 1, + lengths => \@lengths, }, relayd => { protocol => [ "http", @@ -19,9 +18,8 @@ our %args = ( }, server => { func => \&http_server, - lengths => (1, 2, 0), - mreqs => 3, }, + lengths => [1, 2, 0], ); 1; diff --git a/regress/usr.sbin/relayd/args-http-filter-cookie.pl b/regress/usr.sbin/relayd/args-http-filter-cookie.pl index 1bb6cd5c921..3ac271660bb 100644 --- a/regress/usr.sbin/relayd/args-http-filter-cookie.pl +++ b/regress/usr.sbin/relayd/args-http-filter-cookie.pl @@ -9,13 +9,11 @@ our %args = ( client => { func => \&http_client, loggrep => { - qr/Client missing http 1 response/ => 1, - qr/Set-Cookie: a\=b\;/ => 3, + qr/Client missing http 1 response/ => 2, + qr/Set-Cookie: a\=b\;/ => 6, }, cookies => \@cookies, lengths => \@lengths, - httpnok => 1, - mreqs => 1, }, relayd => { protocol => [ "http", @@ -27,9 +25,8 @@ our %args = ( }, server => { func => \&http_server, - mreqs => 3, - nocheck => 1, }, + lengths => [2, 3, 4], ); 1; diff --git a/regress/usr.sbin/relayd/args-http-filter-persistent.pl b/regress/usr.sbin/relayd/args-http-filter-persistent.pl index e16c4f05028..3a8cfdba99b 100644 --- a/regress/usr.sbin/relayd/args-http-filter-persistent.pl +++ b/regress/usr.sbin/relayd/args-http-filter-persistent.pl @@ -6,12 +6,9 @@ use warnings; my @lengths = (251, 16384, 0, 1, 2, 3, 4, 5); our %args = ( client => { - # relayd closes the connection on the first blocked request - func => sub { eval { http_client(@_) }; warn $@ }, + func => \&http_client, lengths => \@lengths, loggrep => qr/Client missing http 2 response/, - mreqs => 1, - httpnok => 1, }, relayd => { protocol => [ "http", @@ -21,10 +18,8 @@ our %args = ( }, server => { func => \&http_server, - mreqs => 7, - nocheck => 1, }, - lengths => [251, 16384, 0, 1], + lengths => [251, 16384, 0, 1, 3, 4, 5], md5 => "bc3a3f39af35fe5b1687903da2b00c7f", ); diff --git a/regress/usr.sbin/relayd/args-http-filter-url-file.pl b/regress/usr.sbin/relayd/args-http-filter-url-file.pl index 363769555e9..06a7545c0f2 100644 --- a/regress/usr.sbin/relayd/args-http-filter-url-file.pl +++ b/regress/usr.sbin/relayd/args-http-filter-url-file.pl @@ -7,14 +7,8 @@ our %args = ( func => \&http_client, lengths => \@lengths, loggrep => { - qr/403 Forbidden/ => 2, - qr/Server: OpenBSD relayd/ => 2, - qr/Connection: close/ => 2, - qr/Content-Length\: 3/ => 0, - qr/Content-Length\: 4/ => 1, + qr/403 Forbidden/ => 4, }, - mreqs => 1, - httpnok => 1, }, relayd => { protocol => [ "http", @@ -23,17 +17,15 @@ our %args = ( 'block request url log file "$curdir/args-http-filter-url-file.in" value "*" label "test_reject_label"', ], loggrep => { - qr/Forbidden/ => 2, - qr/\[test_reject_label\, foo\.bar\/0\]/ => 1, - qr/\[test_reject_label\, foo\.bar\/3\]/ => 1, + qr/Forbidden/ => 4, + qr/\[test_reject_label\, foo\.bar\/0\]/ => 2, + qr/\[test_reject_label\, foo\.bar\/3\]/ => 2, }, }, server => { func => \&http_server, - lengths => (1, 2, 4), - mreqs => 4, - nocheck => 1, }, + lengths => [1, 2, 4, 5], ); 1; diff --git a/regress/usr.sbin/relayd/args-http-persistent.pl b/regress/usr.sbin/relayd/args-http-persistent.pl index 9e38dbb5f14..cd532c1b30b 100644 --- a/regress/usr.sbin/relayd/args-http-persistent.pl +++ b/regress/usr.sbin/relayd/args-http-persistent.pl @@ -8,7 +8,6 @@ our %args = ( client => { func => \&http_client, lengths => \@lengths, - mreqs => 1, }, relayd => { protocol => [ "http", @@ -19,7 +18,6 @@ our %args = ( }, server => { func => \&http_server, - mreqs => scalar(@lengths), }, lengths => \@lengths, md5 => "bc3a3f39af35fe5b1687903da2b00c7f", diff --git a/regress/usr.sbin/relayd/args-http-put.pl b/regress/usr.sbin/relayd/args-http-put.pl index 32a95e25bcd..a498a043517 100644 --- a/regress/usr.sbin/relayd/args-http-put.pl +++ b/regress/usr.sbin/relayd/args-http-put.pl @@ -9,7 +9,6 @@ our %args = ( func => \&http_client, lengths => \@lengths, method => "PUT", - mreqs => 1, }, relayd => { protocol => [ "http", @@ -20,7 +19,6 @@ our %args = ( }, server => { func => \&http_server, - mreqs => scalar(@lengths), }, lengths => \@lengths, md5 => "bc3a3f39af35fe5b1687903da2b00c7f", diff --git a/regress/usr.sbin/relayd/args-https-chunked.pl b/regress/usr.sbin/relayd/args-https-chunked.pl index af66cf4e1d2..eaf506df71e 100644 --- a/regress/usr.sbin/relayd/args-https-chunked.pl +++ b/regress/usr.sbin/relayd/args-https-chunked.pl @@ -8,8 +8,8 @@ our %args = ( client => { func => \&http_client, lengths => \@lengths, + http_vers => ["1.1"], ssl => 1, - mreqs => 1, }, relayd => { protocol => [ "http", @@ -17,7 +17,7 @@ our %args = ( "match response header log Transfer-Encoding", ], loggrep => { - "Transfer-Encoding: chunked" => 2, + "Transfer-Encoding: chunked" => 1, qr/\[\(null\)\]/ => 0, }, forwardssl => 1, @@ -26,7 +26,6 @@ our %args = ( server => { func => \&http_server, ssl => 1, - mreqs => scalar(@lengths), }, lengths => \@lengths, md5 => "bc3a3f39af35fe5b1687903da2b00c7f", diff --git a/regress/usr.sbin/relayd/args-https-contentlength.pl b/regress/usr.sbin/relayd/args-https-contentlength.pl index 611c2877fa9..80f6787e5d8 100644 --- a/regress/usr.sbin/relayd/args-https-contentlength.pl +++ b/regress/usr.sbin/relayd/args-https-contentlength.pl @@ -9,7 +9,6 @@ our %args = ( func => \&http_client, lengths => \@lengths, ssl => 1, - mreqs => 1 }, relayd => { protocol => [ "http", @@ -23,7 +22,6 @@ our %args = ( server => { func => \&http_server, ssl => 1, - mreqs => scalar(@lengths), }, lengths => \@lengths, ); diff --git a/regress/usr.sbin/relayd/args-https-filter-persistent.pl b/regress/usr.sbin/relayd/args-https-filter-persistent.pl index d087182f6e5..61dde49c834 100644 --- a/regress/usr.sbin/relayd/args-https-filter-persistent.pl +++ b/regress/usr.sbin/relayd/args-https-filter-persistent.pl @@ -6,13 +6,10 @@ use warnings; my @lengths = (251, 16384, 0, 1, 2, 3, 4, 5); our %args = ( client => { - # relayd closes the connection on the first blocked request - func => sub { eval { http_client(@_) }; warn $@ }, + func => \&http_client, lengths => \@lengths, loggrep => qr/Client missing http 2 response/, ssl => 1, - mreqs => 1, - httpnok => 1, }, relayd => { protocol => [ "http", @@ -28,10 +25,8 @@ our %args = ( server => { func => \&http_server, ssl => 1, - mreqs => 7, - nocheck => 1, }, - lengths => [251, 16384, 0, 1], + lengths => [251, 16384, 0, 1, 3, 4, 5], md5 => "bc3a3f39af35fe5b1687903da2b00c7f", ); diff --git a/regress/usr.sbin/relayd/args-https-persistent.pl b/regress/usr.sbin/relayd/args-https-persistent.pl index 44ace4ef395..9ca2eaee06c 100644 --- a/regress/usr.sbin/relayd/args-https-persistent.pl +++ b/regress/usr.sbin/relayd/args-https-persistent.pl @@ -9,7 +9,6 @@ our %args = ( func => \&http_client, lengths => \@lengths, ssl => 1, - mreqs => 1, }, relayd => { protocol => [ "http", @@ -23,7 +22,6 @@ our %args = ( server => { func => \&http_server, ssl => 1, - mreqs => scalar(@lengths), }, lengths => \@lengths, md5 => "bc3a3f39af35fe5b1687903da2b00c7f", diff --git a/regress/usr.sbin/relayd/args-https-put.pl b/regress/usr.sbin/relayd/args-https-put.pl index e393dc3210b..1e6973726b2 100644 --- a/regress/usr.sbin/relayd/args-https-put.pl +++ b/regress/usr.sbin/relayd/args-https-put.pl @@ -10,7 +10,6 @@ our %args = ( lengths => \@lengths, method => "PUT", ssl => 1, - mreqs => 1, }, relayd => { protocol => [ "http", @@ -24,7 +23,6 @@ our %args = ( server => { func => \&http_server, ssl => 1, - mreqs => scalar(@lengths), }, lengths => \@lengths, md5 => "bc3a3f39af35fe5b1687903da2b00c7f", diff --git a/regress/usr.sbin/relayd/funcs.pl b/regress/usr.sbin/relayd/funcs.pl index b0cfffca67c..bb0256af641 100644 --- a/regress/usr.sbin/relayd/funcs.pl +++ b/regress/usr.sbin/relayd/funcs.pl @@ -1,4 +1,4 @@ -# $OpenBSD: funcs.pl,v 1.12 2014/07/09 16:48:55 reyk Exp $ +# $OpenBSD: funcs.pl,v 1.13 2014/07/10 10:19:06 bluhm Exp $ # Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org> # @@ -24,7 +24,6 @@ use Socket; use Socket6; use IO::Socket; use IO::Socket::INET6; -use IO::Socket::SSL; sub find_ports { my %args = @_; @@ -45,41 +44,6 @@ sub find_ports { return @ports; } -sub client_connect { - my $self = shift; - - $SSL_ERROR = ""; - my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6"; - my $cs = $iosocket->new( - Proto => "tcp", - Domain => $self->{connectdomain}, - PeerAddr => $self->{connectaddr}, - PeerPort => $self->{connectport}, - SSL_verify_mode => SSL_VERIFY_NONE, - ) or die ref($self), " $iosocket socket connect failed: $!,$SSL_ERROR"; - print STDERR "connect sock: ",$cs->sockhost()," ",$cs->sockport(),"\n"; - print STDERR "connect peer: ",$cs->peerhost()," ",$cs->peerport(),"\n"; - - $self->{stdout} = *STDOUT; - $self->{stdin} = *STDIN; - *STDIN = *STDOUT = $self->{cs} = $cs; -} - -sub client_disconnect { - my $self = shift; - my $cs = $self->{cs}; - - *STDOUT = $self->{stdout}; - *STDIN = $self->{stdin}; - - print STDERR "shutdown sock: ",$cs->sockhost()," ",$cs->sockport(),"\n"; - print STDERR "shutdown peer: ",$cs->peerhost()," ",$cs->peerport(),"\n"; - - IO::Handle::flush(\*STDOUT); - IO::Handle::flush($cs); - $cs->shutdown(SHUT_RDWR); -} - ######################################################################## # Client funcs ######################################################################## @@ -122,75 +86,100 @@ sub write_char { sub http_client { my $self = shift; - my @lengths = @{$self->{lengths} || [ shift // $self->{len} // 251 ]}; - my $vers = $self->{lengths} ? "1.1" : "1.0"; + + unless ($self->{lengths}) { + # only a single http request + my $len = shift // $self->{len} // 251; + my $cookie = $self->{cookie}; + http_request($self, $len, "1.0", $cookie); + return; + } + + $self->{http_vers} ||= ["1.1", "1.0"]; + my $vers = $self->{http_vers}[0]; + my @lengths = @{$self->{redo}{lengths} || $self->{lengths}}; + my @cookies = @{$self->{redo}{cookies} || $self->{cookies} || []}; + while (defined (my $len = shift @lengths)) { + my $cookie = shift @cookies || $self->{cookie}; + eval { http_request($self, $len, $vers, $cookie) }; + warn $@ if $@; + if (@lengths && ($@ || $vers eq "1.0")) { + # reconnect and redo the outstanding requests + $self->{redo} = { + lengths => \@lengths, + cookies => \@cookies, + }; + return; + } + } + delete $self->{redo}; + shift @{$self->{http_vers}}; + if (@{$self->{http_vers}}) { + # run the tests again with other persistence + $self->{redo} = { + lengths => [@{$self->{lengths}}], + cookies => [@{$self->{cookies} || []}], + }; + } +} + +sub http_request { + my ($self, $len, $vers, $cookie) = @_; my $method = $self->{method} || "GET"; my %header = %{$self->{header} || {}}; - my @cookies = $self->{cookies} ? @{$self->{cookies}} : - ($self->{cookie} ? @{$self->{cookie}} : ()); - my $c = 0; - foreach my $len (@lengths) { - my $cookie = ($c < scalar(@cookies) && length($cookies[$c])) ? - $cookies[$c] : ""; - ++$c; - $self->{mreqs} && client_connect($self); - # encode the requested length or chunks into the url - my $path = ref($len) eq 'ARRAY' ? join("/", @$len) : $len; - # overwrite path with custom path - if (defined($self->{path})) { - $path = $self->{path}; - } - my @request = ("$method /$path HTTP/$vers"); - push @request, "Host: foo.bar" unless defined $header{Host}; - push @request, "Content-Length: $len" - if $vers eq "1.1" && $method eq "PUT" && - !defined $header{'Content-Length'}; - push @request, "$_: $header{$_}" foreach sort keys %header; - push @request, "Cookie: $cookie" if $cookie ne ""; - push @request, ""; - print STDERR map { ">>> $_\n" } @request; - print map { "$_\r\n" } @request; - write_char($self, $len) if $method eq "PUT"; - IO::Handle::flush(\*STDOUT); - # XXX client shutdown seems to be broken in relayd - #shutdown(\*STDOUT, SHUT_WR) - # or die ref($self), " shutdown write failed: $!" - # if $vers ne "1.1"; + # encode the requested length or chunks into the url + my $path = ref($len) eq 'ARRAY' ? join("/", @$len) : $len; + # overwrite path with custom path + if (defined($self->{path})) { + $path = $self->{path}; + } + my @request = ("$method /$path HTTP/$vers"); + push @request, "Host: foo.bar" unless defined $header{Host}; + push @request, "Content-Length: $len" + if $vers eq "1.1" && $method eq "PUT" && + !defined $header{'Content-Length'}; + push @request, "$_: $header{$_}" foreach sort keys %header; + push @request, "Cookie: $cookie" if $cookie; + push @request, ""; + print STDERR map { ">>> $_\n" } @request; + print map { "$_\r\n" } @request; + write_char($self, $len) if $method eq "PUT"; + IO::Handle::flush(\*STDOUT); + # XXX client shutdown seems to be broken in relayd + #shutdown(\*STDOUT, SHUT_WR) + # or die ref($self), " shutdown write failed: $!" + # if $vers ne "1.1"; - my $chunked = 0; - { - local $/ = "\r\n"; - local $_ = <STDIN>; - defined - or print STDERR ref($self), - " missing http $len response\n"; - chomp if defined; - print STDERR "<<< $_\n" if defined; - die ref($self), " http response not ok" - if (!defined or !m{^HTTP/$vers 200 OK$}) && - !$self->{httpnok}; - while (<STDIN>) { - chomp; - print STDERR "<<< $_\n"; - last if /^$/; - last if /^X-Chunk-Trailer:.*/; - if (/^Content-Length: (.*)/) { - $1 == $len or die ref($self), - " bad content length $1"; - } - if (/^Transfer-Encoding: chunked$/) { - $chunked = 1; - } + my $chunked = 0; + { + local $/ = "\r\n"; + local $_ = <STDIN>; + defined + or die ref($self), " missing http $len response"; + chomp; + print STDERR "<<< $_\n"; + m{^HTTP/$vers 200 OK$} + or die ref($self), " http response not ok" + unless $self->{httpnok}; + while (<STDIN>) { + chomp; + print STDERR "<<< $_\n"; + last if /^$/; + if (/^Content-Length: (.*)/) { + $1 == $len or die ref($self), + " bad content length $1"; + } + if (/^Transfer-Encoding: chunked$/) { + $chunked = 1; } } - if ($chunked) { - read_chunked($self); - } else { - read_char($self, $vers eq "1.1" ? $len : undef) - if $method eq "GET"; - } - $self->{mreqs} && client_disconnect($self); + } + if ($chunked) { + read_chunked($self); + } else { + read_char($self, $vers eq "1.1" ? $len : undef) + if $method eq "GET"; } } @@ -271,43 +260,13 @@ sub read_char { print STDERR "MD5: ", $ctx->hexdigest, "\n"; } -sub server_accept { - my $self = shift; - my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6"; - my $as = $self->{ls}->accept() - or die ref($self), " $iosocket socket accept failed: $!"; - print STDERR "accept sock: ",$as->sockhost()," ",$as->sockport(),"\n"; - print STDERR "accept peer: ",$as->peerhost()," ",$as->peerport(),"\n"; - - $self->{stdout} = *STDOUT; - $self->{stdin} = *STDIN; - *STDIN = *STDOUT = $self->{as} = $as; -} - -sub server_disconnect { - my $self = shift; - my $as = $self->{as}; - *STDOUT = $self->{stdout}; - *STDIN = $self->{stdin}; - - print STDERR "shutdown sock: ",$as->sockhost()," ",$as->sockport(),"\n"; - print STDERR "shutdown peer: ",$as->peerhost()," ",$as->peerport(),"\n"; - - IO::Handle::flush(\*STDOUT); - IO::Handle::flush($as); -# $as->shutdown(SHUT_RDWR); - IO::Handle::close($as); -} - sub http_server { my $self = shift; my %header = %{$self->{header} || { Server => "Perl/".$^V }}; my $cookie = $self->{cookie} || ""; - my $reqsc = $self->{mreqs} || 0; my($method, $url, $vers); do { - $self->{mreqs} && server_accept($self); my $len; { local $/ = "\r\n"; @@ -330,10 +289,7 @@ sub http_server { $1 == $len or die ref($self), " bad content length $1"; } - if ($cookie eq "" && - /^Cookie: (.*)/) { - $cookie = $1; - } + $cookie ||= $1 if /^Cookie: (.*)/; } } # XXX reading to EOF does not work with relayd @@ -351,24 +307,24 @@ sub http_server { if $vers eq "1.1" && $method eq "GET"; } push @response, "$_: $header{$_} " foreach sort keys %header; - push @response, "Set-Cookie: $cookie" - if $cookie ne ""; + push @response, "Set-Cookie: $cookie" if $cookie; push @response, ""; print STDERR map { ">>> $_\n" } @response; print map { "$_\r\n" } @response; if (ref($len) eq 'ARRAY') { - write_chunked($self, @$len); + if ($vers eq "1.1") { + write_chunked($self, @$len); + } else { + write_char($self, $_) foreach (@$len); + } } else { write_char($self, $len) if $method eq "GET"; } IO::Handle::flush(\*STDOUT); - if ($self->{mreqs}) { - server_disconnect($self); - --$reqsc > 0 or return; - } } while ($vers eq "1.1"); + $self->{redo}-- if $self->{redo}; } sub write_chunked { diff --git a/regress/usr.sbin/relayd/relayd.pl b/regress/usr.sbin/relayd/relayd.pl index de1874b89d8..79d08ad2508 100644 --- a/regress/usr.sbin/relayd/relayd.pl +++ b/regress/usr.sbin/relayd/relayd.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $OpenBSD: relayd.pl,v 1.10 2014/05/12 21:30:42 andre Exp $ +# $OpenBSD: relayd.pl,v 1.11 2014/07/10 10:19:06 bluhm Exp $ # Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org> # @@ -38,12 +38,15 @@ if (@ARGV and -f $ARGV[-1]) { } @ARGV == 1 or usage(); +my $redo = $args{lengths} && @{$args{lengths}}; +$redo = 0 if $args{client}{http_vers}; # run only one persistent connection my($sport, $rport) = find_ports(num => 2); my $s = Server->new( func => \&read_char, listendomain => AF_INET, listenaddr => "127.0.0.1", listenport => $sport, + redo => $redo, %{$args{server}}, ) unless $args{server}{noserver}; my $r = Relayd->new( diff --git a/regress/usr.sbin/relayd/remote.pl b/regress/usr.sbin/relayd/remote.pl index 3925627e00a..2e41529db46 100644 --- a/regress/usr.sbin/relayd/remote.pl +++ b/regress/usr.sbin/relayd/remote.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $OpenBSD: remote.pl,v 1.4 2014/06/22 14:18:01 bluhm Exp $ +# $OpenBSD: remote.pl,v 1.5 2014/07/10 10:19:06 bluhm Exp $ # Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org> # @@ -96,12 +96,15 @@ if ($mode eq "relay") { exit; } +my $redo = $args{lengths} && @{$args{lengths}}; +$redo = 0 if $args{client}{http_vers}; # run only one persistent connection my $s = Server->new( func => \&read_char, %{$args{server}}, listendomain => AF_INET, listenaddr => ($mode eq "auto" ? $ARGV[1] : undef), listenport => ($mode eq "manual" ? $ARGV[0] : undef), + redo => $redo, ) unless $args{server}{noserver}; if ($mode eq "auto") { $r = Remote->new( |