| use strict; |
| use warnings FATAL => 'all'; |
| |
| use Apache::Test; |
| use Apache::TestRequest; |
| use Apache::TestUtil; |
| use HTTP::Response; |
| |
| ## |
| ## mod_remoteip tests |
| ## |
| ## PROXY protocol: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt |
| ## |
| Apache::TestRequest::module("remote_ip"); |
| plan tests => 12, |
| need( |
| need_module('remoteip'), |
| need_min_apache_version('2.4.30') |
| ); |
| |
| sub slurp |
| { |
| my $s = shift; |
| my $r = ""; |
| my $b; |
| while ($s->read($b, 10000) > 0) { |
| $r .= $b; |
| } |
| return $r; |
| } |
| |
| ok(my $sock = Apache::TestRequest::vhost_socket("remote_ip")); |
| |
| # |
| # Test human readable format: TCP4 |
| # |
| my $proxy = "PROXY TCP4 192.168.192.66 192.168.192.77 1111 2222\r\n"; |
| my $url = "GET /index.html HTTP/1.1\r\nConnection: close\r\n"; |
| $url .= "Host: dummy\r\n\r\n"; |
| |
| $sock->print($proxy . $url); |
| $sock->shutdown(1); |
| |
| my $response_data = slurp($sock); |
| my $r = HTTP::Response->parse($response_data); |
| chomp(my $content = $r->content); |
| ok t_cmp($r->code, 200, "PROXY human readable TCP4 protocol check"); |
| ok t_cmp($content, "PROXY-OK", "Content check"); |
| $sock->shutdown(2); |
| |
| # |
| # BAD format test |
| # |
| $proxy = "PROXY FOO 192.168.192.66 192.168.192.77 1111 2222\r\n"; |
| ok ($sock = Apache::TestRequest::vhost_socket("remote_ip")); |
| $sock->print($proxy . $url); |
| $sock->shutdown(1); |
| |
| # In httpd, a bad PROXY format simply results in the connection |
| # being dropped. So ensure we don't get anything that looks |
| # like a response |
| $response_data = slurp($sock); |
| $r = HTTP::Response->parse($response_data); |
| chomp($content = $r->content); |
| ok t_cmp($r->code, undef, "broken PROXY human readable protocol check"); |
| ok t_cmp($content, "", "Content check"); |
| $sock->shutdown(2); |
| |
| # |
| # Test human readable format: TCP6 |
| # |
| $proxy = "PROXY TCP6 2001:DB8::21f:5bff:febf:ce22:8a2e 2001:DB8::12f:8baa:eafc:ce29:6b2e 3333 4444\r\n"; |
| ok ($sock = Apache::TestRequest::vhost_socket("remote_ip")); |
| $sock->print($proxy . $url); |
| $sock->shutdown(1); |
| $response_data = slurp($sock); |
| $r = HTTP::Response->parse($response_data); |
| chomp($content = $r->content); |
| ok t_cmp($r->code, 200, "PROXY human readable TCP6 protocol check"); |
| ok t_cmp($content, "PROXY-OK", "Content check"); |
| $sock->shutdown(2); |
| |
| # Test binary format |
| $proxy = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"; # header |
| $proxy .= "\x21"; # protocol version and command (AF_INET STREAM) |
| $proxy .= "\x11"; # transport protocol and address family (TCP over IPv4) |
| $proxy .= "\x00\x0C"; # 12 bytes coming up |
| $proxy .= "\xC0\xA8\xC0\x42\xC0\xA8\xC0\x4D\x01\xF0\x01\xF1"; # IP addresses and ports |
| ok ($sock = Apache::TestRequest::vhost_socket("remote_ip")); |
| $sock->print($proxy . $url); |
| $sock->shutdown(1); |
| $response_data = slurp($sock); |
| $r = HTTP::Response->parse($response_data); |
| chomp($content = $r->content); |
| ok t_cmp($r->code, 200, "PROXY binary protocol TCP4 check"); |
| ok t_cmp($content, "PROXY-OK", "Content check"); |
| $sock->shutdown(2); |