comparison stream_ssl_preread.t @ 1034:679cefd5896b

Tests: stream_ssl_preread module tests.
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 15 Sep 2016 14:06:24 +0300
parents
children dd3031bbc705
comparison
equal deleted inserted replaced
1033:45c80276d691 1034:679cefd5896b
1 #!/usr/bin/perl
2
3 # (C) Sergey Kandaurov
4 # (C) Nginx, Inc.
5
6 # Tests for stream_ssl_preread module.
7
8 ###############################################################################
9
10 use warnings;
11 use strict;
12
13 use Test::More;
14
15 BEGIN { use FindBin; chdir($FindBin::Bin); }
16
17 use lib 'lib';
18 use Test::Nginx;
19
20 ###############################################################################
21
22 select STDERR; $| = 1;
23 select STDOUT; $| = 1;
24
25 my $t = Test::Nginx->new()->has(qw/stream stream_map stream_ssl_preread/)
26 ->has(qw/http http_ssl stream_ssl/)->has_daemon('openssl')
27 ->write_file_expand('nginx.conf', <<'EOF');
28
29 %%TEST_GLOBALS%%
30
31 daemon off;
32
33 events {
34 }
35
36 stream {
37 log_format status $status;
38
39 map $ssl_preread_server_name $name {
40 "" 127.0.0.1:8093;
41 default $ssl_preread_server_name;
42 }
43
44 upstream foo {
45 server 127.0.0.1:8091;
46 }
47
48 upstream bar {
49 server 127.0.0.1:8092;
50 }
51
52 ssl_preread on;
53
54 server {
55 listen 127.0.0.1:8080;
56 proxy_pass $name;
57 }
58
59 server {
60 listen 127.0.0.1:8081;
61 proxy_pass $name;
62 ssl_preread off;
63 }
64
65 ssl_certificate_key localhost.key;
66 ssl_certificate localhost.crt;
67
68 server {
69 listen 127.0.0.1:8082 ssl;
70 proxy_pass $name;
71 proxy_ssl on;
72 }
73
74 server {
75 listen 127.0.0.1:8083;
76 proxy_pass $name;
77
78 preread_timeout 2s;
79 preread_buffer_size 42;
80
81 access_log %%TESTDIR%%/status.log status;
82 }
83 }
84
85 http {
86 %%TEST_GLOBALS_HTTP%%
87
88 ssl_certificate_key localhost.key;
89 ssl_certificate localhost.crt;
90
91 server {
92 listen 127.0.0.1:8091 ssl;
93 listen 127.0.0.1:8092 ssl;
94 listen 127.0.0.1:8093 ssl;
95 server_name localhost;
96
97 location / {
98 add_header X-Port $server_port always;
99 }
100 }
101 }
102
103 EOF
104
105 eval { require IO::Socket::SSL; die if $IO::Socket::SSL::VERSION < 1.56; };
106 plan(skip_all => 'IO::Socket::SSL version >= 1.56 required') if $@;
107
108 eval {
109 if (IO::Socket::SSL->can('can_client_sni')) {
110 IO::Socket::SSL->can_client_sni() or die;
111 }
112 };
113 plan(skip_all => 'IO::Socket::SSL with OpenSSL SNI support required') if $@;
114
115 eval {
116 my $ctx = Net::SSLeay::CTX_new() or die;
117 my $ssl = Net::SSLeay::new($ctx) or die;
118 Net::SSLeay::set_tlsext_host_name($ssl, 'example.org') == 1 or die;
119 };
120 plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@;
121
122 $t->plan(9);
123
124 $t->write_file('openssl.conf', <<EOF);
125 [ req ]
126 default_bits = 2048
127 encrypt_key = no
128 distinguished_name = req_distinguished_name
129 [ req_distinguished_name ]
130 EOF
131
132 my $d = $t->testdir();
133
134 foreach my $name ('localhost') {
135 system('openssl req -x509 -new '
136 . "-config '$d/openssl.conf' -subj '/CN=$name/' "
137 . "-out '$d/$name.crt' -keyout '$d/$name.key' "
138 . ">>$d/openssl.out 2>&1") == 0
139 or die "Can't create certificate for $name: $!\n";
140 }
141
142 $t->run();
143
144 ###############################################################################
145
146 my ($p1, $p2, $p3) = (port(8091), port(8092), port(8093));
147
148 like(https_get_host('foo'), qr/$p1/, 'sni');
149 like(https_get_host('foo'), qr/$p1/, 'sni again');
150
151 like(https_get_host('bar'), qr/$p2/, 'sni 2');
152 like(https_get_host('bar'), qr/$p2/, 'sni 2 again');
153
154 # fallback to an empty value for some reason
155
156 like(https_get_host('foo', ''), qr/$p3/, 'no sni');
157 like(https_get_host('foo', 'foo', 8081), qr/$p3/, 'no preread');
158 like(https_get_host('foo', 'foo', 8082), qr/$p3/, 'no handshake');
159
160 is(https_get_host('foo', 'foo', 8083), undef, 'preread buffer full');
161
162 $t->stop();
163
164 is($t->read_file('status.log'), "400\n", 'preread buffer full - log');
165
166 ###############################################################################
167
168 sub get_ssl_socket {
169 my ($host, $port) = @_;
170 my $s;
171
172 eval {
173 local $SIG{ALRM} = sub { die "timeout\n" };
174 local $SIG{PIPE} = sub { die "sigpipe\n" };
175 alarm(2);
176 $s = IO::Socket::SSL->new(
177 Proto => 'tcp',
178 PeerAddr => '127.0.0.1:' . port($port || 8080),
179 SSL_hostname => $host,
180 SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(),
181 SSL_error_trap => sub { die $_[1] }
182 );
183 alarm(0);
184 };
185 alarm(0);
186
187 if ($@) {
188 log_in("died: $@");
189 return undef;
190 }
191
192 return $s;
193 }
194
195 sub https_get_host {
196 my ($host, $sni, $port) = @_;
197 my $s = get_ssl_socket(defined $sni ? $sni : $host, $port) or return;
198
199 return http(<<EOF, socket => $s);
200 GET / HTTP/1.0
201 Host: $host
202
203 EOF
204 }
205
206 ###############################################################################