Mercurial > hg > nginx-tests
comparison stream_proxy_protocol_ipv6.t @ 625:0016fe31be13
Tests: fixed connection handling in stream_proxy_protocol_ipv6.t.
Inapplicable http proxying was replaced with stream proxying.
Backend connection close is postponed until all client data is read.
author | Andrey Zelenkov <zelenkov@nginx.com> |
---|---|
date | Mon, 06 Jul 2015 17:47:22 +0300 |
parents | 2d9f5f439598 |
children | 824754da4afc |
comparison
equal
deleted
inserted
replaced
624:1dd0e909fe94 | 625:0016fe31be13 |
---|---|
10 use warnings; | 10 use warnings; |
11 use strict; | 11 use strict; |
12 | 12 |
13 use Test::More; | 13 use Test::More; |
14 | 14 |
15 use IO::Select; | |
16 use Socket qw/ $CRLF /; | |
17 | |
15 BEGIN { use FindBin; chdir($FindBin::Bin); } | 18 BEGIN { use FindBin; chdir($FindBin::Bin); } |
16 | 19 |
17 use lib 'lib'; | 20 use lib 'lib'; |
18 use Test::Nginx; | 21 use Test::Nginx; |
19 | 22 |
20 ############################################################################### | 23 ############################################################################### |
21 | 24 |
22 select STDERR; $| = 1; | 25 select STDERR; $| = 1; |
23 select STDOUT; $| = 1; | 26 select STDOUT; $| = 1; |
24 | 27 |
25 my $t = Test::Nginx->new()->has(qw/http proxy stream ipv6/) | 28 my $t = Test::Nginx->new()->has(qw/stream ipv6/) |
26 ->write_file_expand('nginx.conf', <<'EOF'); | 29 ->write_file_expand('nginx.conf', <<'EOF'); |
27 | 30 |
28 %%TEST_GLOBALS%% | 31 %%TEST_GLOBALS%% |
29 | 32 |
30 daemon off; | 33 daemon off; |
31 | 34 |
32 events { | 35 events { |
33 } | 36 } |
34 | 37 |
35 http { | 38 stream { |
36 %%TEST_GLOBALS_HTTP%% | 39 server { |
40 listen 127.0.0.1:8080; | |
41 proxy_pass [::1]:8080; | |
42 } | |
37 | 43 |
38 server { | 44 server { |
39 listen 127.0.0.1:8080; | 45 listen 127.0.0.1:8081; |
40 server_name localhost; | 46 proxy_pass [::1]:8081; |
41 | |
42 location /on { | |
43 proxy_pass http://[::1]:8080; | |
44 } | |
45 | |
46 location /off { | |
47 proxy_pass http://[::1]:8081; | |
48 } | |
49 } | 47 } |
50 } | |
51 | |
52 stream { | |
53 proxy_protocol on; | |
54 | 48 |
55 server { | 49 server { |
56 listen [::1]:8080; | 50 listen [::1]:8080; |
57 proxy_pass 127.0.0.1:8082; | 51 proxy_pass 127.0.0.1:8082; |
52 proxy_protocol on; | |
58 } | 53 } |
59 | 54 |
60 server { | 55 server { |
61 listen [::1]:8081; | 56 listen [::1]:8081; |
62 proxy_pass 127.0.0.1:8082; | 57 proxy_pass 127.0.0.1:8082; |
63 proxy_protocol off; | |
64 } | 58 } |
65 } | 59 } |
66 | 60 |
67 EOF | 61 EOF |
68 | 62 |
70 $t->try_run('no inet6 support or stream proxy_protocol')->plan(2); | 64 $t->try_run('no inet6 support or stream proxy_protocol')->plan(2); |
71 $t->waitforsocket('127.0.0.1:8082'); | 65 $t->waitforsocket('127.0.0.1:8082'); |
72 | 66 |
73 ############################################################################### | 67 ############################################################################### |
74 | 68 |
75 like(http_get('/on'), qr/PROXY TCP6 ::1 ::1 [0-9]+ 8080/, 'protocol on'); | 69 like(stream_get('close'), qr/PROXY TCP6 ::1 ::1 \d+ 8080$CRLF/, 'protocol on'); |
76 unlike(http_get('/off'), qr/PROXY/, 'protocol off'); | 70 unlike(stream_get('close', '127.0.0.1:8081'), qr/PROXY/, 'protocol off'); |
71 | |
72 ############################################################################### | |
73 | |
74 sub stream_get { | |
75 my ($data, $peer) = @_; | |
76 | |
77 my $s = stream_connect($peer); | |
78 stream_write($s, $data); | |
79 | |
80 $data = ''; | |
81 while (my $buf = stream_read($s)) { | |
82 $data .= $buf; | |
83 } | |
84 | |
85 return $data; | |
86 } | |
87 | |
88 sub stream_connect { | |
89 my $peer = shift; | |
90 my $s = IO::Socket::INET->new( | |
91 Proto => 'tcp', | |
92 PeerAddr => $peer || '127.0.0.1:8080' | |
93 ) | |
94 or die "Can't connect to nginx: $!\n"; | |
95 | |
96 return $s; | |
97 } | |
98 | |
99 sub stream_write { | |
100 my ($s, $message) = @_; | |
101 | |
102 local $SIG{PIPE} = 'IGNORE'; | |
103 | |
104 $s->blocking(0); | |
105 while (IO::Select->new($s)->can_write(1.5)) { | |
106 my $n = $s->syswrite($message); | |
107 last unless $n; | |
108 $message = substr($message, $n); | |
109 last unless length $message; | |
110 } | |
111 | |
112 if (length $message) { | |
113 $s->close(); | |
114 } | |
115 } | |
116 | |
117 sub stream_read { | |
118 my ($s) = @_; | |
119 my ($buf); | |
120 | |
121 $s->blocking(0); | |
122 if (IO::Select->new($s)->can_read(3)) { | |
123 $s->sysread($buf, 1024); | |
124 }; | |
125 | |
126 log_in($buf); | |
127 return $buf; | |
128 } | |
77 | 129 |
78 ############################################################################### | 130 ############################################################################### |
79 | 131 |
80 sub stream_daemon { | 132 sub stream_daemon { |
81 my $d = shift; | |
82 my $server = IO::Socket::INET->new( | 133 my $server = IO::Socket::INET->new( |
83 Proto => 'tcp', | 134 Proto => 'tcp', |
84 LocalHost => '127.0.0.1:8082', | 135 LocalHost => '127.0.0.1:8082', |
85 Listen => 5, | 136 Listen => 5, |
86 Reuse => 1 | 137 Reuse => 1 |
87 ) | 138 ) |
88 or die "Can't create listening socket: $!\n"; | 139 or die "Can't create listening socket: $!\n"; |
89 | 140 |
141 my $sel = IO::Select->new($server); | |
142 | |
90 local $SIG{PIPE} = 'IGNORE'; | 143 local $SIG{PIPE} = 'IGNORE'; |
91 | 144 |
92 while (my $client = $server->accept()) { | 145 while (my @ready = $sel->can_read) { |
93 $client->autoflush(1); | 146 foreach my $fh (@ready) { |
147 if ($server == $fh) { | |
148 my $new = $fh->accept; | |
149 $new->autoflush(1); | |
150 $sel->add($new); | |
94 | 151 |
95 log2c("(new connection $client)"); | 152 } elsif (stream_handle_client($fh)) { |
153 $sel->remove($fh); | |
154 $fh->close; | |
155 } | |
156 } | |
157 } | |
158 } | |
96 | 159 |
97 $client->sysread(my $buffer, 65536) or next; | 160 sub stream_handle_client { |
161 my ($client) = @_; | |
98 | 162 |
99 log2i("$client $buffer"); | 163 log2c("(new connection $client)"); |
100 | 164 |
101 $buffer =~ /(.*?)\x0d\x0a?/ms; | 165 $client->sysread(my $buffer, 65536) or return 1; |
102 $buffer = $1; | |
103 | 166 |
104 log2o("$client $buffer"); | 167 log2i("$client $buffer"); |
105 | 168 |
106 $client->syswrite($buffer); | 169 log2o("$client $buffer"); |
107 | 170 |
108 close $client; | 171 $client->syswrite($buffer); |
109 } | 172 |
173 return $buffer =~ /close/; | |
110 } | 174 } |
111 | 175 |
112 sub log2i { Test::Nginx::log_core('|| <<', @_); } | 176 sub log2i { Test::Nginx::log_core('|| <<', @_); } |
113 sub log2o { Test::Nginx::log_core('|| >>', @_); } | 177 sub log2o { Test::Nginx::log_core('|| >>', @_); } |
114 sub log2c { Test::Nginx::log_core('||', @_); } | 178 sub log2c { Test::Nginx::log_core('||', @_); } |