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);