Skip to content

Commit b8323b2

Browse files
committed
Tests: socket leaks with zero available bytes (ticket #2367).
1 parent 9a9ef8e commit b8323b2

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

Diff for: proxy_available.t

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/perl
2+
3+
# (C) Sergey Kandaurov
4+
# (C) Nginx, Inc.
5+
6+
# Tests for http proxy module with available bytes counting.
7+
8+
###############################################################################
9+
10+
use warnings;
11+
use strict;
12+
13+
use Test::More;
14+
15+
use IO::Select;
16+
17+
BEGIN { use FindBin; chdir($FindBin::Bin); }
18+
19+
use lib 'lib';
20+
use Test::Nginx qw/ :DEFAULT http_end /;
21+
22+
###############################################################################
23+
24+
select STDERR; $| = 1;
25+
select STDOUT; $| = 1;
26+
27+
my $t = Test::Nginx->new()->has(qw/http proxy/)->plan(2);
28+
29+
$t->write_file_expand('nginx.conf', <<'EOF');
30+
31+
%%TEST_GLOBALS%%
32+
33+
daemon off;
34+
35+
events {
36+
}
37+
38+
http {
39+
%%TEST_GLOBALS_HTTP%%
40+
41+
server {
42+
listen 127.0.0.1:8080;
43+
server_name localhost;
44+
45+
location /buffered {
46+
proxy_pass http://127.0.0.1:8081;
47+
proxy_buffer_size 512;
48+
}
49+
50+
location /unbuffered {
51+
proxy_pass http://127.0.0.1:8082;
52+
proxy_buffer_size 512;
53+
proxy_buffering off;
54+
}
55+
}
56+
}
57+
58+
EOF
59+
60+
$t->run_daemon(\&http_daemon, port(8081));
61+
$t->run_daemon(\&http_daemon, port(8082));
62+
$t->run();
63+
64+
$t->waitforsocket('127.0.0.1:' . port(8081));
65+
$t->waitforsocket('127.0.0.1:' . port(8082));
66+
67+
###############################################################################
68+
69+
# ticket #2367: socket leaks with EPOLLRDHUP
70+
# due to missing rev->ready reset on rev->available == 0
71+
#
72+
# to reproduce leaks, the first part of the response should fit proxy buffer
73+
74+
my $s = http_get('/buffered', start => 1);
75+
IO::Select->new($s)->can_read(3);
76+
77+
$t->reload();
78+
79+
TODO: {
80+
local $TODO = 'not yet' if $^O eq 'linux' and !$t->has_version('1.23.1');
81+
82+
like(http_end($s), qr/AND-THIS/, 'zero available - buffered');
83+
84+
}
85+
86+
$s = http_get('/unbuffered', start => 1);
87+
IO::Select->new($s)->can_read(3);
88+
89+
$t->stop();
90+
91+
like(http_end($s), qr/AND-THIS/, 'zero available - unbuffered');
92+
93+
$t->todo_alerts() if $^O eq 'linux' and !$t->has_version('1.23.1');
94+
95+
###############################################################################
96+
97+
sub http_daemon {
98+
my ($port) = @_;
99+
100+
my $server = IO::Socket::INET->new(
101+
Proto => 'tcp',
102+
LocalHost => "127.0.0.1:$port",
103+
Listen => 5,
104+
Reuse => 1
105+
)
106+
or die "Can't create listening socket: $!\n";
107+
108+
local $SIG{PIPE} = 'IGNORE';
109+
110+
while (my $client = $server->accept()) {
111+
$client->autoflush(1);
112+
113+
my $headers = '';
114+
my $uri = '';
115+
116+
while (<$client>) {
117+
$headers .= $_;
118+
last if (/^\x0d?\x0a?$/);
119+
}
120+
121+
next if $headers eq '';
122+
123+
my $r = <<EOF;
124+
HTTP/1.1 200 OK
125+
Connection: close
126+
127+
EOF
128+
129+
$r = $r . 'x' x (512 - length($r));
130+
print $client $r;
131+
132+
select undef, undef, undef, 1.1;
133+
print $client 'AND-THIS';
134+
}
135+
}
136+
137+
###############################################################################

0 commit comments

Comments
 (0)