comparison 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
comparison
equal deleted inserted replaced
9:4385a10a836f 10:2b95417a1715
18 18
19 select STDERR; $| = 1; 19 select STDERR; $| = 1;
20 select STDOUT; $| = 1; 20 select STDOUT; $| = 1;
21 21
22 my $t = Test::Nginx->new()->has(qw/http rewrite proxy fastcgi auth_basic/) 22 my $t = Test::Nginx->new()->has(qw/http rewrite proxy fastcgi auth_basic/)
23 ->plan(17); 23 ->plan(18);
24 24
25 $t->write_file_expand('nginx.conf', <<'EOF'); 25 $t->write_file_expand('nginx.conf', <<'EOF');
26 26
27 %%TEST_GLOBALS%% 27 %%TEST_GLOBALS%%
28 28
91 proxy_set_header Content-Length ""; 91 proxy_set_header Content-Length "";
92 } 92 }
93 location = /auth-basic { 93 location = /auth-basic {
94 auth_basic "restricted"; 94 auth_basic "restricted";
95 auth_basic_user_file %%TESTDIR%%/htpasswd; 95 auth_basic_user_file %%TESTDIR%%/htpasswd;
96 }
97
98 location = /proxy-double {
99 proxy_pass http://127.0.0.1:8080/auth-error;
100 proxy_intercept_errors on;
101 error_page 404 = /proxy-double-fallback;
102 client_body_buffer_size 4k;
103 }
104 location = /proxy-double-fallback {
105 auth_request /auth-proxy-double;
106 proxy_pass http://127.0.0.1:8080/auth-open;
107 }
108 location = /auth-proxy-double {
109 proxy_pass http://127.0.0.1:8080/auth-open;
110 proxy_pass_request_body off;
111 proxy_set_header Content-Length "";
96 } 112 }
97 113
98 location /fastcgi { 114 location /fastcgi {
99 auth_request /auth-fastcgi; 115 auth_request /auth-fastcgi;
100 } 116 }
133 'proxy auth has www-authenticate'); 149 'proxy auth has www-authenticate');
134 like(http_get_auth('/proxy'), qr/ 404 /, 'proxy auth pass'); 150 like(http_get_auth('/proxy'), qr/ 404 /, 'proxy auth pass');
135 unlike(http_get_auth('/proxy'), qr/INVISIBLE/, 'proxy auth no content'); 151 unlike(http_get_auth('/proxy'), qr/INVISIBLE/, 'proxy auth no content');
136 152
137 like(http_post('/proxy'), qr/ 401 /, 'proxy auth post'); 153 like(http_post('/proxy'), qr/ 401 /, 'proxy auth post');
154
155 # Consider the following scenario:
156 #
157 # 1. proxy_pass reads request body, then goes to fallback via error_page
158 # 2. auth request uses proxy_pass, and upstream module closes request body file
159 # in ngx_http_upstream_send_response()
160 # 3. oops: fallback has no body
161 #
162 # To prevent this we always allocate fake request body for auth request.
163 #
164 # Note that this doesn't happen when using header_only as relevant code
165 # in ngx_http_upstream_send_response() isn't reached. It may be reached
166 # with proxy_cache or proxy_store, but they will shutdown client connection
167 # in case of header_only and hence do not work for us at all.
168
169 like(http_post_big('/proxy-double'), qr/ 204 /, 'proxy auth with body read');
138 170
139 SKIP: { 171 SKIP: {
140 eval { require FCGI; }; 172 eval { require FCGI; };
141 skip 'FCGI not installed', 2 if $@; 173 skip 'FCGI not installed', 2 if $@;
142 174
169 "1234567890"; 201 "1234567890";
170 202
171 return http($p, %extra); 203 return http($p, %extra);
172 } 204 }
173 205
206 sub http_post_big {
207 my ($url, %extra) = @_;
208
209 my $p = "POST $url HTTP/1.0" . CRLF .
210 "Host: localhost" . CRLF .
211 "Content-Length: 10240" . CRLF .
212 CRLF .
213 ("1234567890" x 1024);
214
215 return http($p, %extra);
216 }
217
174 ############################################################################### 218 ###############################################################################
175 219
176 sub fastcgi_daemon { 220 sub fastcgi_daemon {
177 my $socket = FCGI::OpenSocket('127.0.0.1:8081', 5); 221 my $socket = FCGI::OpenSocket('127.0.0.1:8081', 5);
178 my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, 222 my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,