Mercurial > hg > ngx_http_auth_request_module
annotate t/auth-request.t @ 10:2b95417a1715
Auth request: fix body handling again.
Setting r->discard_body is wrong way to go as it causes lingering timer to
be armed on subrequest finalization. Create fake body instead.
This also allows to protect real body file from being closed in case it was
already read. Though it doesn't matter now as we set r->header_only and
relevant code in ngx_http_upstream_send_response() isn't reached.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 24 Mar 2010 07:23:22 +0300 |
parents | 70f3d876b569 |
children |
rev | line source |
---|---|
0 | 1 #!/usr/bin/perl |
2 | |
3 # (C) Maxim Dounin | |
4 | |
5 # Tests for auth request module. | |
6 | |
7 ############################################################################### | |
8 | |
9 use warnings; | |
10 use strict; | |
11 | |
4
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
12 use Socket qw/ CRLF /; |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
13 |
0 | 14 use Test::More; |
15 use Test::Nginx; | |
16 | |
17 ############################################################################### | |
18 | |
19 select STDERR; $| = 1; | |
20 select STDOUT; $| = 1; | |
21 | |
22 my $t = Test::Nginx->new()->has(qw/http rewrite proxy fastcgi auth_basic/) | |
10
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
23 ->plan(18); |
0 | 24 |
25 $t->write_file_expand('nginx.conf', <<'EOF'); | |
26 | |
6
70f3d876b569
Auth request: use test globals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4
diff
changeset
|
27 %%TEST_GLOBALS%% |
70f3d876b569
Auth request: use test globals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4
diff
changeset
|
28 |
0 | 29 master_process off; |
30 daemon off; | |
31 | |
32 events { | |
33 } | |
34 | |
35 http { | |
36 %%TEST_GLOBALS_HTTP%% | |
37 | |
38 server { | |
39 listen 127.0.0.1:8080; | |
40 server_name localhost; | |
41 | |
42 location / { | |
43 return 444; | |
44 } | |
45 | |
46 location /open { | |
47 auth_request /auth-open; | |
48 } | |
49 location = /auth-open { | |
50 return 204; | |
51 } | |
52 | |
53 location /open-static { | |
54 auth_request /auth-open-static; | |
55 } | |
56 location = /auth-open-static { | |
57 # nothing, use static file | |
58 } | |
59 | |
60 location /unauthorized { | |
61 auth_request /auth-unauthorized; | |
62 } | |
63 location = /auth-unauthorized { | |
64 return 401; | |
65 } | |
66 | |
67 location /forbidden { | |
68 auth_request /auth-forbidden; | |
69 } | |
70 location = /auth-forbidden { | |
71 return 403; | |
72 } | |
73 | |
74 location /error { | |
75 auth_request /auth-error; | |
76 } | |
77 location = /auth-error { | |
78 return 404; | |
79 } | |
80 | |
1
dfc5ae42367a
Auth request: support switching off.
Maxim Dounin <mdounin@mdounin.ru>
parents:
0
diff
changeset
|
81 location /off { |
dfc5ae42367a
Auth request: support switching off.
Maxim Dounin <mdounin@mdounin.ru>
parents:
0
diff
changeset
|
82 auth_request off; |
dfc5ae42367a
Auth request: support switching off.
Maxim Dounin <mdounin@mdounin.ru>
parents:
0
diff
changeset
|
83 } |
dfc5ae42367a
Auth request: support switching off.
Maxim Dounin <mdounin@mdounin.ru>
parents:
0
diff
changeset
|
84 |
0 | 85 location /proxy { |
86 auth_request /auth-proxy; | |
87 } | |
88 location = /auth-proxy { | |
89 proxy_pass http://127.0.0.1:8080/auth-basic; | |
4
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
90 proxy_pass_request_body off; |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
91 proxy_set_header Content-Length ""; |
0 | 92 } |
93 location = /auth-basic { | |
94 auth_basic "restricted"; | |
95 auth_basic_user_file %%TESTDIR%%/htpasswd; | |
96 } | |
97 | |
10
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
98 location = /proxy-double { |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
99 proxy_pass http://127.0.0.1:8080/auth-error; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
100 proxy_intercept_errors on; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
101 error_page 404 = /proxy-double-fallback; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
102 client_body_buffer_size 4k; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
103 } |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
104 location = /proxy-double-fallback { |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
105 auth_request /auth-proxy-double; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
106 proxy_pass http://127.0.0.1:8080/auth-open; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
107 } |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
108 location = /auth-proxy-double { |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
109 proxy_pass http://127.0.0.1:8080/auth-open; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
110 proxy_pass_request_body off; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
111 proxy_set_header Content-Length ""; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
112 } |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
113 |
0 | 114 location /fastcgi { |
115 auth_request /auth-fastcgi; | |
116 } | |
117 location = /auth-fastcgi { | |
118 fastcgi_pass 127.0.0.1:8081; | |
4
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
119 fastcgi_pass_request_body off; |
0 | 120 } |
121 } | |
122 } | |
123 | |
124 EOF | |
125 | |
126 $t->write_file('htpasswd', 'user:zz1T8N4tWvmbE' . "\n"); | |
127 $t->write_file('auth-basic', 'INVISIBLE'); | |
128 $t->write_file('auth-open-static', 'INVISIBLE'); | |
129 $t->run(); | |
130 | |
131 ############################################################################### | |
132 | |
133 pass('runs'); | |
134 | |
135 like(http_get('/open'), qr/ 404 /, 'auth open'); | |
136 like(http_get('/unauthorized'), qr/ 401 /, 'auth unauthorized'); | |
137 like(http_get('/forbidden'), qr/ 403 /, 'auth forbidden'); | |
138 like(http_get('/error'), qr/ 500 /, 'auth error'); | |
1
dfc5ae42367a
Auth request: support switching off.
Maxim Dounin <mdounin@mdounin.ru>
parents:
0
diff
changeset
|
139 like(http_get('/off'), qr/ 404 /, 'auth off'); |
0 | 140 |
4
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
141 like(http_post('/open'), qr/ 404 /, 'auth post open'); |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
142 like(http_post('/unauthorized'), qr/ 401 /, 'auth post unauthorized'); |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
143 |
0 | 144 like(http_get('/open-static'), qr/ 404 /, 'auth open static'); |
145 unlike(http_get('/open-static'), qr/INVISIBLE/, 'auth static no content'); | |
146 | |
147 like(http_get('/proxy'), qr/ 401 /, 'proxy auth unauthorized'); | |
148 like(http_get('/proxy'), qr/WWW-Authenticate: Basic realm="restricted"/, | |
149 'proxy auth has www-authenticate'); | |
150 like(http_get_auth('/proxy'), qr/ 404 /, 'proxy auth pass'); | |
151 unlike(http_get_auth('/proxy'), qr/INVISIBLE/, 'proxy auth no content'); | |
152 | |
4
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
153 like(http_post('/proxy'), qr/ 401 /, 'proxy auth post'); |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
154 |
10
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
155 # Consider the following scenario: |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
156 # |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
157 # 1. proxy_pass reads request body, then goes to fallback via error_page |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
158 # 2. auth request uses proxy_pass, and upstream module closes request body file |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
159 # in ngx_http_upstream_send_response() |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
160 # 3. oops: fallback has no body |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
161 # |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
162 # To prevent this we always allocate fake request body for auth request. |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
163 # |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
164 # Note that this doesn't happen when using header_only as relevant code |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
165 # in ngx_http_upstream_send_response() isn't reached. It may be reached |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
166 # with proxy_cache or proxy_store, but they will shutdown client connection |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
167 # in case of header_only and hence do not work for us at all. |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
168 |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
169 like(http_post_big('/proxy-double'), qr/ 204 /, 'proxy auth with body read'); |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
170 |
0 | 171 SKIP: { |
172 eval { require FCGI; }; | |
173 skip 'FCGI not installed', 2 if $@; | |
174 | |
175 $t->run_daemon(\&fastcgi_daemon); | |
176 $t->waitforsocket('127.0.0.1:8081'); | |
177 | |
178 like(http_get('/fastcgi'), qr/ 404 /, 'fastcgi auth open'); | |
179 unlike(http_get('/fastcgi'), qr/INVISIBLE/, 'fastcgi auth no content'); | |
180 } | |
181 | |
182 ############################################################################### | |
183 | |
184 sub http_get_auth { | |
185 my ($url, %extra) = @_; | |
186 return http(<<EOF, %extra); | |
187 GET $url HTTP/1.0 | |
188 Host: localhost | |
189 Authorization: Basic dXNlcjpzZWNyZXQ= | |
190 | |
191 EOF | |
192 } | |
193 | |
4
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
194 sub http_post { |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
195 my ($url, %extra) = @_; |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
196 |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
197 my $p = "POST $url HTTP/1.0" . CRLF . |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
198 "Host: localhost" . CRLF . |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
199 "Content-Length: 10" . CRLF . |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
200 CRLF . |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
201 "1234567890"; |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
202 |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
203 return http($p, %extra); |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
204 } |
35f0ee7a3c28
Auth request: fix SIGSEGV on POST.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1
diff
changeset
|
205 |
10
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
206 sub http_post_big { |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
207 my ($url, %extra) = @_; |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
208 |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
209 my $p = "POST $url HTTP/1.0" . CRLF . |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
210 "Host: localhost" . CRLF . |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
211 "Content-Length: 10240" . CRLF . |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
212 CRLF . |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
213 ("1234567890" x 1024); |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
214 |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
215 return http($p, %extra); |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
216 } |
2b95417a1715
Auth request: fix body handling again.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6
diff
changeset
|
217 |
0 | 218 ############################################################################### |
219 | |
220 sub fastcgi_daemon { | |
221 my $socket = FCGI::OpenSocket('127.0.0.1:8081', 5); | |
222 my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, | |
223 $socket); | |
224 | |
225 while ($request->Accept() >= 0) { | |
226 print <<EOF; | |
227 Content-Type: text/html | |
228 | |
229 INVISIBLE | |
230 EOF | |
231 } | |
232 | |
233 FCGI::CloseSocket($socket); | |
234 } | |
235 | |
236 ############################################################################### |