Test request target for SSL over proxy.
tarao
9 years ago
7 | 7 | use Plack::Request; |
8 | 8 | use Test::Requires qw(Plack::Request HTTP::Body), 'HTTP::Proxy'; |
9 | 9 | |
10 | plan tests => 9*3*2; | |
10 | plan tests => (10*2 + 8)*3; | |
11 | 11 | |
12 | 12 | my $verbose = 1; |
13 | 13 | { |
65 | 65 | my $env = shift; |
66 | 66 | |
67 | 67 | my $req = Plack::Request->new($env); |
68 | is $req->header('X-Foo'), "ppp" if $env->{REQUEST_URI} eq '/foo'; | |
68 | is $req->path, '/foo'; | |
69 | is $req->header('X-Foo'), "ppp"; | |
69 | 70 | like $req->header('User-Agent'), qr/\A Furl::HTTP /xms; |
70 | 71 | my $content = "Hello, foo"; |
71 | 72 | return [ 200, |
76 | 77 | }); |
77 | 78 | |
78 | 79 | sub client (%) { |
79 | my (%url) = @_; | |
80 | my (%args) = @_; | |
80 | 81 | for (1..3) { # run some times for testing keep-alive. |
81 | my $furl = Furl::HTTP->new(proxy => $url{proxy}); | |
82 | my $furl = Furl::HTTP->new(proxy => $args{proxy}); | |
82 | 83 | my ( undef, $code, $msg, $headers, $content ) = |
83 | 84 | $furl->request( |
84 | url => $url{request}, | |
85 | url => $args{request}, | |
85 | 86 | headers => [ "X-Foo" => "ppp" ] |
86 | 87 | ); |
87 | 88 | is $code, 200, "request()"; |
88 | 89 | is $msg, "OK"; |
89 | 90 | is Furl::HTTP::_header_get($headers, 'Content-Length'), 10; |
90 | is Furl::HTTP::_header_get($headers, 'Via'), "1.0 $via"; | |
91 | is Furl::HTTP::_header_get($headers, 'Via'), $args{via}; | |
91 | 92 | is $content, 'Hello, foo' |
92 | 93 | or do{ require Devel::Peek; Devel::Peek::Dump($content) }; |
93 | 94 | } |
112 | 113 | client( |
113 | 114 | proxy => "http://127.0.0.1:$proxy_port", |
114 | 115 | request => "http://127.0.0.1:$httpd_port/foo", |
116 | via => '1.0 VIA!VIA!VIA!', | |
115 | 117 | ); |
116 | 118 | }, |
117 | 119 | server => sub { # proxy server |
131 | 133 | client( |
132 | 134 | proxy => "http://127.0.0.1:$proxy_port", |
133 | 135 | request => "http://127.0.0.1/foo", # default port |
136 | via => '1.0 VIA!VIA!VIA!', | |
134 | 137 | ); |
135 | 138 | }, |
136 | 139 | server => sub { # proxy server |
141 | 144 | $proxy->start(); |
142 | 145 | }, |
143 | 146 | ); |
147 | ||
148 | # SSL over proxy | |
149 | ||
150 | test_tcp( | |
151 | client => sub { | |
152 | # emulate CONNECT for SSL proxying without a real SSL connection | |
153 | no warnings 'redefine'; | |
154 | local *Furl::HTTP::connect_ssl_over_proxy = sub { | |
155 | my ($self, $proxy_host, $proxy_port, $host, $port, $timeout_at, $proxy_authorization) = @_; | |
156 | my $sock = $self->connect($proxy_host, $proxy_port, $timeout_at); | |
157 | my $p = "CONNECT $host:$port HTTP/1.0\015\012Server: $host\015\012"; | |
158 | $p .= "\015\012"; | |
159 | $self->write_all($sock, $p, $timeout_at) or fail; | |
160 | ||
161 | # read the entire response of CONNECT method | |
162 | my $buf = ''; | |
163 | while ($buf !~ qr!(?:\015\012){2}!) { | |
164 | my $read = $self->read_timeout( | |
165 | $sock, \$buf, $self->{bufsize}, length($buf), $timeout_at | |
166 | ); | |
167 | defined $read or fail; | |
168 | $read != 0 or fail; | |
169 | } | |
170 | ||
171 | $sock; | |
172 | }; | |
173 | ||
174 | my $proxy_port = shift; | |
175 | my $httpd_port = $httpd->port; | |
176 | client( | |
177 | proxy => "http://127.0.0.1:$proxy_port", | |
178 | request => "https://127.0.0.1:$httpd_port/foo", | |
179 | # no via since the request goes directly to the origin server | |
180 | ); | |
181 | }, | |
182 | server => sub { # proxy server | |
183 | my $proxy_port = shift; | |
184 | my $proxy = Test::HTTP::Proxy->new(port => $proxy_port, via => $via); | |
185 | $proxy->start(); | |
186 | }, | |
187 | ); |