Mercurial > hg > nginx-tests
comparison stream_proxy_protocol_ssl.t @ 615:f27fb891503c
Tests: stream proxy protocol tests to ssl backend.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 02 Jul 2015 15:06:39 +0300 |
parents | |
children | cf89559cd558 |
comparison
equal
deleted
inserted
replaced
614:0597ca82c26a | 615:f27fb891503c |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 # (C) Sergey Kandaurov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Tests for stream proxy module with haproxy protocol to ssl backend. | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use Test::More; | |
14 | |
15 use IO::Select; | |
16 use Socket qw/ CR LF CRLF /; | |
17 | |
18 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
19 | |
20 use lib 'lib'; | |
21 use Test::Nginx qw/ :DEFAULT http_end /; | |
22 | |
23 ############################################################################### | |
24 | |
25 select STDERR; $| = 1; | |
26 select STDOUT; $| = 1; | |
27 | |
28 eval { require IO::Socket::SSL; }; | |
29 plan(skip_all => 'IO::Socket::SSL not installed') if $@; | |
30 | |
31 my $t = Test::Nginx->new()->has(qw/stream stream_ssl/)->has_daemon('openssl'); | |
32 | |
33 $t->write_file_expand('nginx.conf', <<'EOF'); | |
34 | |
35 %%TEST_GLOBALS%% | |
36 | |
37 daemon off; | |
38 | |
39 events { | |
40 } | |
41 | |
42 stream { | |
43 proxy_ssl on; | |
44 proxy_protocol on; | |
45 | |
46 server { | |
47 listen 127.0.0.1:8080; | |
48 proxy_pass 127.0.0.1:8081; | |
49 } | |
50 | |
51 server { | |
52 listen 127.0.0.1:8082; | |
53 proxy_pass 127.0.0.1:8083; | |
54 proxy_protocol off; | |
55 } | |
56 } | |
57 | |
58 EOF | |
59 | |
60 $t->write_file('openssl.conf', <<EOF); | |
61 [ req ] | |
62 default_bits = 2048 | |
63 encrypt_key = no | |
64 distinguished_name = req_distinguished_name | |
65 [ req_distinguished_name ] | |
66 EOF | |
67 | |
68 my $d = $t->testdir(); | |
69 | |
70 foreach my $name ('localhost') { | |
71 system('openssl req -x509 -new ' | |
72 . "-config '$d/openssl.conf' -subj '/CN=$name/' " | |
73 . "-out '$d/$name.crt' -keyout '$d/$name.key' " | |
74 . ">>$d/openssl.out 2>&1") == 0 | |
75 or die "Can't create certificate for $name: $!\n"; | |
76 } | |
77 | |
78 $t->run_daemon(\&stream_daemon_ssl, 8081, path => $d, pp => 1); | |
79 $t->run_daemon(\&stream_daemon_ssl, 8083, path => $d, pp => 0); | |
80 $t->try_run('no stream proxy_protocol')->plan(2); | |
81 | |
82 $t->waitforsocket('127.0.0.1:8081'); | |
83 $t->waitforsocket('127.0.0.1:8083'); | |
84 | |
85 ############################################################################### | |
86 | |
87 my %r = pp_get('test'); | |
88 is($r{'data'}, "PROXY TCP4 127.0.0.1 127.0.0.1 $r{'sp'} 8080" . CRLF . 'test', | |
89 'protocol on'); | |
90 | |
91 %r = pp_get('test', '127.0.0.1:8082'); | |
92 is($r{'data'}, 'test', 'protocol off'); | |
93 | |
94 ############################################################################### | |
95 | |
96 sub pp_get { | |
97 my ($data, $peer) = @_; | |
98 | |
99 my $s = http($data, socket => getconn($peer), start => 1); | |
100 my $sockport = $s->sockport; | |
101 $data = http_end($s); | |
102 return ('data' => $data, 'sp' => $sockport); | |
103 } | |
104 | |
105 sub getconn { | |
106 my $peer = shift; | |
107 my $s = IO::Socket::INET->new( | |
108 Proto => 'tcp', | |
109 PeerAddr => $peer || '127.0.0.1:8080' | |
110 ) | |
111 or die "Can't connect to nginx: $!\n"; | |
112 | |
113 return $s; | |
114 } | |
115 | |
116 ############################################################################### | |
117 | |
118 sub stream_daemon_ssl { | |
119 my ($port, %extra) = @_; | |
120 my $d = $extra{path}; | |
121 my $pp = $extra{pp}; | |
122 my $server = IO::Socket::INET->new( | |
123 Proto => 'tcp', | |
124 LocalHost => "127.0.0.1:$port", | |
125 Listen => 5, | |
126 Reuse => 1 | |
127 ) | |
128 or die "Can't create listening socket: $!\n"; | |
129 | |
130 local $SIG{PIPE} = 'IGNORE'; | |
131 | |
132 while (my $client = $server->accept()) { | |
133 my ($buffer, $data) = ('', ''); | |
134 $client->autoflush(1); | |
135 | |
136 log2c("(new connection $client on $port)"); | |
137 | |
138 # read no more than haproxy header of variable length | |
139 | |
140 while ($pp) { | |
141 my $prev = $buffer; | |
142 $client->sysread($buffer, 1) or last; | |
143 $data .= $buffer; | |
144 last if $prev eq CR && $buffer eq LF; | |
145 } | |
146 | |
147 log2i("$client $data"); | |
148 | |
149 # would fail on waitforsocket | |
150 | |
151 eval { | |
152 IO::Socket::SSL->start_SSL($client, | |
153 SSL_server => 1, | |
154 SSL_cert_file => "$d/localhost.crt", | |
155 SSL_key_file => "$d/localhost.key", | |
156 SSL_error_trap => sub { die $_[1] } | |
157 ); | |
158 }; | |
159 next if $@; | |
160 | |
161 $client->sysread($buffer, 65536) or next; | |
162 | |
163 log2i("$client $buffer"); | |
164 | |
165 $data .= $buffer; | |
166 | |
167 log2o("$client $data"); | |
168 | |
169 $client->syswrite($data); | |
170 | |
171 close $client; | |
172 } | |
173 } | |
174 | |
175 sub log2i { Test::Nginx::log_core('|| <<', @_); } | |
176 sub log2o { Test::Nginx::log_core('|| >>', @_); } | |
177 sub log2c { Test::Nginx::log_core('||', @_); } | |
178 | |
179 ############################################################################### |