comparison h2_limit_req.t @ 876:a6abbfed42c0

Tests: split HTTP/2 tests, HTTP2 package introduced.
author Andrey Zelenkov <zelenkov@nginx.com>
date Wed, 23 Mar 2016 17:23:08 +0300
parents
children 8c3fa5a94743
comparison
equal deleted inserted replaced
875:c380b4b7e2e4 876:a6abbfed42c0
1 #!/usr/bin/perl
2
3 # (C) Sergey Kandaurov
4 # (C) Nginx, Inc.
5
6 # Tests for HTTP/2 protocol with limit_req.
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 use Test::Nginx::HTTP2 qw/ :DEFAULT :frame /;
20
21 ###############################################################################
22
23 select STDERR; $| = 1;
24 select STDOUT; $| = 1;
25
26 my $t = Test::Nginx->new()->has(qw/http http_v2 proxy rewrite limit_req/)
27 ->plan(6);
28
29 # Some systems may have also a bug in not treating zero writev iovcnt as EINVAL
30
31 $t->todo_alerts();
32
33 $t->write_file_expand('nginx.conf', <<'EOF');
34
35 %%TEST_GLOBALS%%
36
37 daemon off;
38
39 events {
40 }
41
42 http {
43 %%TEST_GLOBALS_HTTP%%
44
45 limit_req_zone $binary_remote_addr zone=req:1m rate=1r/s;
46
47 server {
48 listen 127.0.0.1:8080 http2;
49 listen 127.0.0.1:8081;
50 server_name localhost;
51
52 location / { }
53 location /limit_req {
54 limit_req zone=req burst=2;
55 alias %%TESTDIR%%/t.html;
56 }
57 location /proxy_limit_req/ {
58 add_header X-Body $request_body;
59 add_header X-Body-File $request_body_file;
60 client_body_in_file_only on;
61 proxy_pass http://127.0.0.1:8081/;
62 limit_req zone=req burst=2;
63 }
64 }
65 }
66
67 EOF
68
69 $t->write_file('index.html', '');
70 $t->write_file('t.html', 'SEE-THIS');
71 $t->run();
72
73 ###############################################################################
74
75 # request body delayed in limit_req
76
77 my $sess = new_session();
78 my $sid = new_stream($sess, { path => '/proxy_limit_req/', body_more => 1 });
79 h2_body($sess, 'TEST');
80 my $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]);
81
82 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
83 is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST',
84 'request body - limit req');
85
86 # request body delayed in limit_req - with an empty DATA frame
87
88 $sess = new_session();
89 $sid = new_stream($sess, { path => '/proxy_limit_req/', body_more => 1 });
90 h2_body($sess, '');
91 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]);
92
93 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
94 is($frame->{headers}->{':status'}, 200, 'request body - limit req - empty');
95
96 # predict send windows
97
98 $sid = new_stream($sess);
99 my ($maxwin) = sort {$a <=> $b} $sess->{streams}{$sid}, $sess->{conn_window};
100
101 SKIP: {
102 skip 'leaves coredump', 1 unless $t->has_version('1.9.7');
103 skip 'not enough window', 1 if $maxwin < 5;
104
105 $sess = new_session();
106 $sid = new_stream($sess, { path => '/proxy_limit_req/', body => 'TEST2' });
107 select undef, undef, undef, 1.1;
108 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]);
109
110 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
111 is(read_body_file($frame->{headers}->{'x-body-file'}), 'TEST2',
112 'request body - limit req 2');
113
114 }
115
116 # partial request body data frame received (to be discarded) within request
117 # delayed in limit_req, the rest of data frame is received after response
118
119 $sess = new_session();
120
121 SKIP: {
122 skip 'not enough window', 1 if $maxwin < 4;
123
124 TODO: {
125 todo_skip 'use-after-free', 1 unless $ENV{TEST_NGINX_UNSAFE}
126 or $t->has_version('1.9.12');
127
128 $sid = new_stream($sess, { path => '/limit_req', body => 'TEST', split => [61],
129 split_delay => 1.1 });
130 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]);
131
132 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
133 is($frame->{headers}->{':status'}, '200', 'discard body - limit req - limited');
134
135 }
136
137 }
138
139 $sid = new_stream($sess, { path => '/' });
140 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]);
141
142 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
143 is($frame->{headers}->{':status'}, '200', 'discard body - limit req - next');
144
145 # ditto, but instead of receiving the rest of data frame, connection is closed
146 # 'http request already closed while closing request' alert can be produced
147
148 SKIP: {
149 skip 'not enough window', 1 if $maxwin < 4;
150
151 TODO: {
152 todo_skip 'use-after-free', 1 unless $ENV{TEST_NGINX_UNSAFE}
153 or $t->has_version('1.9.12');
154
155 $sess = new_session();
156 $sid = new_stream($sess, { path => '/limit_req', body => 'TEST', split => [61],
157 abort => 1 });
158 $frames = h2_read($sess, all => [{ sid => $sid, fin => 1 }]);
159
160 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
161 is($frame->{headers}->{':status'}, '200', 'discard body - limit req - eof');
162
163 select undef, undef, undef, 1.1;
164 undef $sess;
165
166 }
167
168 }
169
170 ###############################################################################
171
172 sub read_body_file {
173 my ($path) = @_;
174 open FILE, $path or return "$!";
175 local $/;
176 my $content = <FILE>;
177 close FILE;
178 return $content;
179 }
180
181 ###############################################################################