Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_scgi_module.c @ 4437:3a1507f48686 stable-1.0
Merge of r4372, r4373, r4374:
SCGI fixes:
*) Fixed incorrect use of r->http_version in scgi module.
The r->http_version is a version of client's request, and modules
must not set it unless they are really willing to downgrade protocol
version used for a response (i.e. to HTTP/0.9 if no response headers
are available). In neither case r->http_version may be upgraded.
The former code downgraded response from HTTP/1.1 to HTTP/1.0 for no
reason, causing various problems (see ticket #66). It was also
possible that HTTP/0.9 requests were upgraded to HTTP/1.0.
*) Removed duplicate function declaration.
*) Removed error if there is no Status header.
The SCGI specification doesn't specify format of the response, and
assuming CGI specs should be used there is no reason to complain.
RFC 3875 explicitly states that "A Status header field is optional,
and status 200 'OK' is assumed if it is omitted".
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sun, 05 Feb 2012 13:53:50 +0000 |
parents | 8e7bb000ba4a |
children | 2b2d51cdbd97 |
rev | line source |
---|---|
3637 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 * Copyright (C) Manlio Perillo (manlio.perillo@gmail.com) | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 typedef struct { | |
14 ngx_http_upstream_conf_t upstream; | |
15 | |
16 ngx_array_t *flushes; | |
17 ngx_array_t *params_len; | |
18 ngx_array_t *params; | |
19 ngx_array_t *params_source; | |
20 | |
21 ngx_hash_t headers_hash; | |
22 ngx_uint_t header_params; | |
23 | |
24 ngx_array_t *scgi_lengths; | |
25 ngx_array_t *scgi_values; | |
26 | |
27 #if (NGX_HTTP_CACHE) | |
28 ngx_http_complex_value_t cache_key; | |
29 #endif | |
30 } ngx_http_scgi_loc_conf_t; | |
31 | |
32 | |
33 static ngx_int_t ngx_http_scgi_eval(ngx_http_request_t *r, | |
34 ngx_http_scgi_loc_conf_t *scf); | |
35 static ngx_int_t ngx_http_scgi_create_request(ngx_http_request_t *r); | |
36 static ngx_int_t ngx_http_scgi_reinit_request(ngx_http_request_t *r); | |
37 static ngx_int_t ngx_http_scgi_process_status_line(ngx_http_request_t *r); | |
38 static ngx_int_t ngx_http_scgi_process_header(ngx_http_request_t *r); | |
39 static void ngx_http_scgi_abort_request(ngx_http_request_t *r); | |
40 static void ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc); | |
41 | |
42 static void *ngx_http_scgi_create_loc_conf(ngx_conf_t *cf); | |
43 static char *ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, | |
44 void *child); | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
45 static ngx_int_t ngx_http_scgi_merge_params(ngx_conf_t *cf, |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
46 ngx_http_scgi_loc_conf_t *conf, ngx_http_scgi_loc_conf_t *prev); |
3637 | 47 |
48 static char *ngx_http_scgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
49 static char *ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd, | |
50 void *conf); | |
51 | |
52 #if (NGX_HTTP_CACHE) | |
53 static ngx_int_t ngx_http_scgi_create_key(ngx_http_request_t *r); | |
54 static char *ngx_http_scgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, | |
55 void *conf); | |
56 static char *ngx_http_scgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, | |
57 void *conf); | |
58 #endif | |
59 | |
60 | |
61 static ngx_conf_bitmask_t ngx_http_scgi_next_upstream_masks[] = { | |
62 { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, | |
63 { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, | |
64 { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, | |
65 { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, | |
66 { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, | |
67 { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, | |
68 { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, | |
69 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, | |
70 { ngx_null_string, 0 } | |
71 }; | |
72 | |
73 | |
74 ngx_module_t ngx_http_scgi_module; | |
75 | |
76 | |
77 static ngx_command_t ngx_http_scgi_commands[] = { | |
78 | |
79 { ngx_string("scgi_pass"), | |
80 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, | |
81 ngx_http_scgi_pass, | |
82 NGX_HTTP_LOC_CONF_OFFSET, | |
83 0, | |
84 NULL }, | |
85 | |
86 { ngx_string("scgi_store"), | |
87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
88 ngx_http_scgi_store, | |
89 NGX_HTTP_LOC_CONF_OFFSET, | |
90 0, | |
91 NULL }, | |
92 | |
93 { ngx_string("scgi_store_access"), | |
94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, | |
95 ngx_conf_set_access_slot, | |
96 NGX_HTTP_LOC_CONF_OFFSET, | |
97 offsetof(ngx_http_scgi_loc_conf_t, upstream.store_access), | |
98 NULL }, | |
99 | |
4252 | 100 { ngx_string("scgi_buffering"), |
101 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
102 ngx_conf_set_flag_slot, | |
103 NGX_HTTP_LOC_CONF_OFFSET, | |
104 offsetof(ngx_http_scgi_loc_conf_t, upstream.buffering), | |
105 NULL }, | |
106 | |
3637 | 107 { ngx_string("scgi_ignore_client_abort"), |
108 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
109 ngx_conf_set_flag_slot, | |
110 NGX_HTTP_LOC_CONF_OFFSET, | |
111 offsetof(ngx_http_scgi_loc_conf_t, upstream.ignore_client_abort), | |
112 NULL }, | |
113 | |
114 { ngx_string("scgi_bind"), | |
115 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
116 ngx_http_upstream_bind_set_slot, | |
117 NGX_HTTP_LOC_CONF_OFFSET, | |
118 offsetof(ngx_http_scgi_loc_conf_t, upstream.local), | |
119 NULL }, | |
120 | |
121 { ngx_string("scgi_connect_timeout"), | |
122 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
123 ngx_conf_set_msec_slot, | |
124 NGX_HTTP_LOC_CONF_OFFSET, | |
125 offsetof(ngx_http_scgi_loc_conf_t, upstream.connect_timeout), | |
126 NULL }, | |
127 | |
128 { ngx_string("scgi_send_timeout"), | |
129 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
130 ngx_conf_set_msec_slot, | |
131 NGX_HTTP_LOC_CONF_OFFSET, | |
132 offsetof(ngx_http_scgi_loc_conf_t, upstream.send_timeout), | |
133 NULL }, | |
134 | |
135 { ngx_string("scgi_buffer_size"), | |
136 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
137 ngx_conf_set_size_slot, | |
138 NGX_HTTP_LOC_CONF_OFFSET, | |
139 offsetof(ngx_http_scgi_loc_conf_t, upstream.buffer_size), | |
140 NULL }, | |
141 | |
142 { ngx_string("scgi_pass_request_headers"), | |
143 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
144 ngx_conf_set_flag_slot, | |
145 NGX_HTTP_LOC_CONF_OFFSET, | |
146 offsetof(ngx_http_scgi_loc_conf_t, upstream.pass_request_headers), | |
147 NULL }, | |
148 | |
149 { ngx_string("scgi_pass_request_body"), | |
150 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
151 ngx_conf_set_flag_slot, | |
152 NGX_HTTP_LOC_CONF_OFFSET, | |
153 offsetof(ngx_http_scgi_loc_conf_t, upstream.pass_request_body), | |
154 NULL }, | |
155 | |
156 { ngx_string("scgi_intercept_errors"), | |
157 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
158 ngx_conf_set_flag_slot, | |
159 NGX_HTTP_LOC_CONF_OFFSET, | |
160 offsetof(ngx_http_scgi_loc_conf_t, upstream.intercept_errors), | |
161 NULL }, | |
162 | |
163 { ngx_string("scgi_read_timeout"), | |
164 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
165 ngx_conf_set_msec_slot, | |
166 NGX_HTTP_LOC_CONF_OFFSET, | |
167 offsetof(ngx_http_scgi_loc_conf_t, upstream.read_timeout), | |
168 NULL }, | |
169 | |
170 { ngx_string("scgi_buffers"), | |
171 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, | |
172 ngx_conf_set_bufs_slot, | |
173 NGX_HTTP_LOC_CONF_OFFSET, | |
174 offsetof(ngx_http_scgi_loc_conf_t, upstream.bufs), | |
175 NULL }, | |
176 | |
177 { ngx_string("scgi_busy_buffers_size"), | |
178 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
179 ngx_conf_set_size_slot, | |
180 NGX_HTTP_LOC_CONF_OFFSET, | |
181 offsetof(ngx_http_scgi_loc_conf_t, upstream.busy_buffers_size_conf), | |
182 NULL }, | |
183 | |
184 #if (NGX_HTTP_CACHE) | |
185 | |
186 { ngx_string("scgi_cache"), | |
3729 | 187 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
3637 | 188 ngx_http_scgi_cache, |
189 NGX_HTTP_LOC_CONF_OFFSET, | |
190 0, | |
191 NULL }, | |
192 | |
193 { ngx_string("scgi_cache_key"), | |
3729 | 194 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
3637 | 195 ngx_http_scgi_cache_key, |
196 NGX_HTTP_LOC_CONF_OFFSET, | |
197 0, | |
198 NULL }, | |
199 | |
200 { ngx_string("scgi_cache_path"), | |
201 NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE, | |
202 ngx_http_file_cache_set_slot, | |
203 0, | |
204 0, | |
205 &ngx_http_scgi_module }, | |
206 | |
3699
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
207 { ngx_string("scgi_cache_bypass"), |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
208 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
209 ngx_http_set_predicate_slot, |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
210 NGX_HTTP_LOC_CONF_OFFSET, |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
211 offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_bypass), |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
212 NULL }, |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
213 |
3637 | 214 { ngx_string("scgi_no_cache"), |
215 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
3692
045ea40cbfe8
use ngx_http_test_predicates(), ngx_http_set_predicate_slot()
Igor Sysoev <igor@sysoev.ru>
parents:
3670
diff
changeset
|
216 ngx_http_set_predicate_slot, |
3637 | 217 NGX_HTTP_LOC_CONF_OFFSET, |
218 offsetof(ngx_http_scgi_loc_conf_t, upstream.no_cache), | |
219 NULL }, | |
220 | |
221 { ngx_string("scgi_cache_valid"), | |
222 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
223 ngx_http_file_cache_valid_set_slot, | |
224 NGX_HTTP_LOC_CONF_OFFSET, | |
225 offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_valid), | |
226 NULL }, | |
227 | |
228 { ngx_string("scgi_cache_min_uses"), | |
229 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
230 ngx_conf_set_num_slot, | |
231 NGX_HTTP_LOC_CONF_OFFSET, | |
232 offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_min_uses), | |
233 NULL }, | |
234 | |
235 { ngx_string("scgi_cache_use_stale"), | |
236 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
237 ngx_conf_set_bitmask_slot, | |
238 NGX_HTTP_LOC_CONF_OFFSET, | |
239 offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_use_stale), | |
240 &ngx_http_scgi_next_upstream_masks }, | |
241 | |
242 { ngx_string("scgi_cache_methods"), | |
243 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
244 ngx_conf_set_bitmask_slot, | |
245 NGX_HTTP_LOC_CONF_OFFSET, | |
246 offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_methods), | |
247 &ngx_http_upstream_cache_method_mask }, | |
248 | |
249 #endif | |
250 | |
251 { ngx_string("scgi_temp_path"), | |
252 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, | |
253 ngx_conf_set_path_slot, | |
254 NGX_HTTP_LOC_CONF_OFFSET, | |
255 offsetof(ngx_http_scgi_loc_conf_t, upstream.temp_path), | |
256 NULL }, | |
257 | |
258 { ngx_string("scgi_max_temp_file_size"), | |
259 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
260 ngx_conf_set_size_slot, | |
261 NGX_HTTP_LOC_CONF_OFFSET, | |
262 offsetof(ngx_http_scgi_loc_conf_t, upstream.max_temp_file_size_conf), | |
263 NULL }, | |
264 | |
265 { ngx_string("scgi_temp_file_write_size"), | |
266 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
267 ngx_conf_set_size_slot, | |
268 NGX_HTTP_LOC_CONF_OFFSET, | |
269 offsetof(ngx_http_scgi_loc_conf_t, upstream.temp_file_write_size_conf), | |
270 NULL }, | |
271 | |
272 { ngx_string("scgi_next_upstream"), | |
273 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
274 ngx_conf_set_bitmask_slot, | |
275 NGX_HTTP_LOC_CONF_OFFSET, | |
276 offsetof(ngx_http_scgi_loc_conf_t, upstream.next_upstream), | |
277 &ngx_http_scgi_next_upstream_masks }, | |
278 | |
279 { ngx_string("scgi_param"), | |
280 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, | |
281 ngx_conf_set_keyval_slot, | |
282 NGX_HTTP_LOC_CONF_OFFSET, | |
283 offsetof(ngx_http_scgi_loc_conf_t, params_source), | |
284 NULL }, | |
285 | |
286 { ngx_string("scgi_pass_header"), | |
3729 | 287 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
3637 | 288 ngx_conf_set_str_array_slot, |
289 NGX_HTTP_LOC_CONF_OFFSET, | |
290 offsetof(ngx_http_scgi_loc_conf_t, upstream.pass_headers), | |
291 NULL }, | |
292 | |
293 { ngx_string("scgi_hide_header"), | |
3729 | 294 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
3637 | 295 ngx_conf_set_str_array_slot, |
296 NGX_HTTP_LOC_CONF_OFFSET, | |
297 offsetof(ngx_http_scgi_loc_conf_t, upstream.hide_headers), | |
298 NULL }, | |
299 | |
300 { ngx_string("scgi_ignore_headers"), | |
301 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
302 ngx_conf_set_bitmask_slot, | |
303 NGX_HTTP_LOC_CONF_OFFSET, | |
304 offsetof(ngx_http_scgi_loc_conf_t, upstream.ignore_headers), | |
3667
12bd9e26fadb
use shared ngx_http_upstream_ignore_headers_masks[]
Igor Sysoev <igor@sysoev.ru>
parents:
3637
diff
changeset
|
305 &ngx_http_upstream_ignore_headers_masks }, |
3637 | 306 |
307 ngx_null_command | |
308 }; | |
309 | |
310 | |
311 static ngx_http_module_t ngx_http_scgi_module_ctx = { | |
312 NULL, /* preconfiguration */ | |
313 NULL, /* postconfiguration */ | |
314 | |
315 NULL, /* create main configuration */ | |
316 NULL, /* init main configuration */ | |
317 | |
318 NULL, /* create server configuration */ | |
319 NULL, /* merge server configuration */ | |
320 | |
321 ngx_http_scgi_create_loc_conf, /* create location configuration */ | |
322 ngx_http_scgi_merge_loc_conf /* merge location configuration */ | |
323 }; | |
324 | |
325 | |
326 ngx_module_t ngx_http_scgi_module = { | |
327 NGX_MODULE_V1, | |
328 &ngx_http_scgi_module_ctx, /* module context */ | |
329 ngx_http_scgi_commands, /* module directives */ | |
330 NGX_HTTP_MODULE, /* module type */ | |
331 NULL, /* init master */ | |
332 NULL, /* init module */ | |
333 NULL, /* init process */ | |
334 NULL, /* init thread */ | |
335 NULL, /* exit thread */ | |
336 NULL, /* exit process */ | |
337 NULL, /* exit master */ | |
338 NGX_MODULE_V1_PADDING | |
339 }; | |
340 | |
341 | |
342 static ngx_str_t ngx_http_scgi_hide_headers[] = { | |
343 ngx_string("Status"), | |
344 ngx_string("X-Accel-Expires"), | |
345 ngx_string("X-Accel-Redirect"), | |
346 ngx_string("X-Accel-Limit-Rate"), | |
347 ngx_string("X-Accel-Buffering"), | |
348 ngx_string("X-Accel-Charset"), | |
349 ngx_null_string | |
350 }; | |
351 | |
352 | |
353 #if (NGX_HTTP_CACHE) | |
354 | |
355 static ngx_keyval_t ngx_http_scgi_cache_headers[] = { | |
356 { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") }, | |
357 { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") }, | |
358 { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") }, | |
359 { ngx_string("HTTP_IF_MATCH"), ngx_string("") }, | |
360 { ngx_string("HTTP_RANGE"), ngx_string("") }, | |
361 { ngx_string("HTTP_IF_RANGE"), ngx_string("") }, | |
362 { ngx_null_string, ngx_null_string } | |
363 }; | |
364 | |
365 #endif | |
366 | |
367 | |
368 static ngx_path_init_t ngx_http_scgi_temp_path = { | |
369 ngx_string(NGX_HTTP_SCGI_TEMP_PATH), { 1, 2, 0 } | |
370 }; | |
371 | |
372 | |
373 static ngx_int_t | |
374 ngx_http_scgi_handler(ngx_http_request_t *r) | |
375 { | |
376 ngx_int_t rc; | |
377 ngx_http_status_t *status; | |
378 ngx_http_upstream_t *u; | |
379 ngx_http_scgi_loc_conf_t *scf; | |
380 | |
381 if (r->subrequest_in_memory) { | |
382 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
383 "ngx_http_scgi_module does not support " | |
384 "subrequests in memory"); | |
385 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
386 } | |
387 | |
388 if (ngx_http_upstream_create(r) != NGX_OK) { | |
389 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
390 } | |
391 | |
392 status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t)); | |
393 if (status == NULL) { | |
394 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
395 } | |
396 | |
397 ngx_http_set_ctx(r, status, ngx_http_scgi_module); | |
398 | |
399 scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module); | |
400 | |
401 if (scf->scgi_lengths) { | |
402 if (ngx_http_scgi_eval(r, scf) != NGX_OK) { | |
403 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
404 } | |
405 } | |
406 | |
407 u = r->upstream; | |
408 | |
409 ngx_str_set(&u->schema, "scgi://"); | |
410 u->output.tag = (ngx_buf_tag_t) &ngx_http_scgi_module; | |
411 | |
412 u->conf = &scf->upstream; | |
413 | |
414 #if (NGX_HTTP_CACHE) | |
415 u->create_key = ngx_http_scgi_create_key; | |
416 #endif | |
417 u->create_request = ngx_http_scgi_create_request; | |
418 u->reinit_request = ngx_http_scgi_reinit_request; | |
419 u->process_header = ngx_http_scgi_process_status_line; | |
420 u->abort_request = ngx_http_scgi_abort_request; | |
421 u->finalize_request = ngx_http_scgi_finalize_request; | |
422 | |
4252 | 423 u->buffering = scf->upstream.buffering; |
3637 | 424 |
425 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); | |
426 if (u->pipe == NULL) { | |
427 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
428 } | |
429 | |
430 u->pipe->input_filter = ngx_event_pipe_copy_input_filter; | |
431 u->pipe->input_ctx = r; | |
432 | |
433 rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); | |
434 | |
435 if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { | |
436 return rc; | |
437 } | |
438 | |
439 return NGX_DONE; | |
440 } | |
441 | |
442 | |
443 static ngx_int_t | |
444 ngx_http_scgi_eval(ngx_http_request_t *r, ngx_http_scgi_loc_conf_t * scf) | |
445 { | |
446 ngx_url_t url; | |
447 ngx_http_upstream_t *u; | |
448 | |
449 ngx_memzero(&url, sizeof(ngx_url_t)); | |
450 | |
451 if (ngx_http_script_run(r, &url.url, scf->scgi_lengths->elts, 0, | |
452 scf->scgi_values->elts) | |
453 == NULL) | |
454 { | |
455 return NGX_ERROR; | |
456 } | |
457 | |
458 url.no_resolve = 1; | |
459 | |
460 if (ngx_parse_url(r->pool, &url) != NGX_OK) { | |
461 if (url.err) { | |
462 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
463 "%s in upstream \"%V\"", url.err, &url.url); | |
464 } | |
465 | |
466 return NGX_ERROR; | |
467 } | |
468 | |
469 u = r->upstream; | |
470 | |
471 u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); | |
472 if (u->resolved == NULL) { | |
473 return NGX_ERROR; | |
474 } | |
475 | |
476 if (url.addrs && url.addrs[0].sockaddr) { | |
477 u->resolved->sockaddr = url.addrs[0].sockaddr; | |
478 u->resolved->socklen = url.addrs[0].socklen; | |
479 u->resolved->naddrs = 1; | |
480 u->resolved->host = url.addrs[0].name; | |
481 | |
482 } else { | |
483 u->resolved->host = url.host; | |
484 u->resolved->port = url.port; | |
3879
502a6b0acf3f
fix case when a host in fastcgi_pass, scgi_pass, and uwsgi_pass
Igor Sysoev <igor@sysoev.ru>
parents:
3731
diff
changeset
|
485 u->resolved->no_port = url.no_port; |
3637 | 486 } |
487 | |
488 return NGX_OK; | |
489 } | |
490 | |
491 | |
492 #if (NGX_HTTP_CACHE) | |
493 | |
494 static ngx_int_t | |
495 ngx_http_scgi_create_key(ngx_http_request_t *r) | |
496 { | |
497 ngx_str_t *key; | |
498 ngx_http_scgi_loc_conf_t *scf; | |
499 | |
500 key = ngx_array_push(&r->cache->keys); | |
501 if (key == NULL) { | |
502 return NGX_ERROR; | |
503 } | |
504 | |
505 scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module); | |
506 | |
507 if (ngx_http_complex_value(r, &scf->cache_key, key) != NGX_OK) { | |
508 return NGX_ERROR; | |
509 } | |
510 | |
511 return NGX_OK; | |
512 } | |
513 | |
514 #endif | |
515 | |
516 | |
517 static ngx_int_t | |
518 ngx_http_scgi_create_request(ngx_http_request_t *r) | |
519 { | |
520 u_char ch, *key, *val, *lowcase_key; | |
521 size_t len, allocated; | |
522 ngx_buf_t *b; | |
523 ngx_str_t *content_length; | |
524 ngx_uint_t i, n, hash, header_params; | |
525 ngx_chain_t *cl, *body; | |
526 ngx_list_part_t *part; | |
527 ngx_table_elt_t *header, **ignored; | |
528 ngx_http_script_code_pt code; | |
529 ngx_http_script_engine_t e, le; | |
530 ngx_http_scgi_loc_conf_t *scf; | |
531 ngx_http_script_len_code_pt lcode; | |
532 static ngx_str_t zero = ngx_string("0"); | |
533 | |
534 content_length = r->headers_in.content_length ? | |
535 &r->headers_in.content_length->value : &zero; | |
536 | |
537 len = sizeof("CONTENT_LENGTH") + content_length->len + 1; | |
538 | |
539 header_params = 0; | |
540 ignored = NULL; | |
541 | |
542 scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module); | |
543 | |
544 if (scf->params_len) { | |
545 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); | |
546 | |
547 ngx_http_script_flush_no_cacheable_variables(r, scf->flushes); | |
548 le.flushed = 1; | |
549 | |
550 le.ip = scf->params_len->elts; | |
551 le.request = r; | |
552 | |
553 while (*(uintptr_t *) le.ip) { | |
554 | |
555 lcode = *(ngx_http_script_len_code_pt *) le.ip; | |
556 len += lcode(&le); | |
557 | |
558 while (*(uintptr_t *) le.ip) { | |
559 lcode = *(ngx_http_script_len_code_pt *) le.ip; | |
4362 | 560 len += lcode(&le); |
3637 | 561 } |
4362 | 562 len++; |
563 | |
3637 | 564 le.ip += sizeof(uintptr_t); |
565 } | |
566 } | |
567 | |
568 if (scf->upstream.pass_request_headers) { | |
569 | |
570 allocated = 0; | |
571 lowcase_key = NULL; | |
572 | |
573 if (scf->header_params) { | |
4050 | 574 n = 0; |
575 part = &r->headers_in.headers.part; | |
576 | |
577 while (part) { | |
578 n += part->nelts; | |
579 part = part->next; | |
580 } | |
581 | |
582 ignored = ngx_palloc(r->pool, n * sizeof(void *)); | |
3637 | 583 if (ignored == NULL) { |
584 return NGX_ERROR; | |
585 } | |
586 } | |
587 | |
588 part = &r->headers_in.headers.part; | |
589 header = part->elts; | |
590 | |
591 for (i = 0; /* void */; i++) { | |
592 | |
593 if (i >= part->nelts) { | |
594 if (part->next == NULL) { | |
595 break; | |
596 } | |
597 | |
598 part = part->next; | |
599 header = part->elts; | |
600 i = 0; | |
601 } | |
602 | |
603 if (scf->header_params) { | |
604 if (allocated < header[i].key.len) { | |
605 allocated = header[i].key.len + 16; | |
606 lowcase_key = ngx_pnalloc(r->pool, allocated); | |
607 if (lowcase_key == NULL) { | |
608 return NGX_ERROR; | |
609 } | |
610 } | |
611 | |
612 hash = 0; | |
613 | |
614 for (n = 0; n < header[i].key.len; n++) { | |
615 ch = header[i].key.data[n]; | |
616 | |
617 if (ch >= 'A' && ch <= 'Z') { | |
618 ch |= 0x20; | |
619 | |
620 } else if (ch == '-') { | |
621 ch = '_'; | |
622 } | |
623 | |
624 hash = ngx_hash(hash, ch); | |
625 lowcase_key[n] = ch; | |
626 } | |
627 | |
628 if (ngx_hash_find(&scf->headers_hash, hash, lowcase_key, n)) { | |
629 ignored[header_params++] = &header[i]; | |
630 continue; | |
631 } | |
632 } | |
633 | |
634 len += sizeof("HTTP_") - 1 + header[i].key.len + 1 | |
635 + header[i].value.len + 1; | |
636 } | |
637 } | |
638 | |
639 /* netstring: "length:" + packet + "," */ | |
640 | |
641 b = ngx_create_temp_buf(r->pool, NGX_SIZE_T_LEN + 1 + len + 1); | |
642 if (b == NULL) { | |
643 return NGX_ERROR; | |
644 } | |
645 | |
646 cl = ngx_alloc_chain_link(r->pool); | |
647 if (cl == NULL) { | |
648 return NGX_ERROR; | |
649 } | |
650 | |
651 cl->buf = b; | |
652 | |
653 b->last = ngx_snprintf(b->last, | |
654 NGX_SIZE_T_LEN + 1 + sizeof("CONTENT_LENGTH") | |
655 + NGX_OFF_T_LEN + 1, | |
656 "%ui:CONTENT_LENGTH%Z%V%Z", | |
657 len, content_length); | |
658 | |
659 if (scf->params_len) { | |
660 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); | |
661 | |
662 e.ip = scf->params->elts; | |
663 e.pos = b->last; | |
664 e.request = r; | |
665 e.flushed = 1; | |
666 | |
667 while (*(uintptr_t *) e.ip) { | |
668 | |
669 #if (NGX_DEBUG) | |
670 key = e.pos; | |
671 #endif | |
672 code = *(ngx_http_script_code_pt *) e.ip; | |
673 code((ngx_http_script_engine_t *) & e); | |
674 | |
675 #if (NGX_DEBUG) | |
676 val = e.pos; | |
677 #endif | |
678 while (*(uintptr_t *) e.ip) { | |
679 code = *(ngx_http_script_code_pt *) e.ip; | |
680 code((ngx_http_script_engine_t *) &e); | |
681 } | |
682 *e.pos++ = '\0'; | |
683 e.ip += sizeof(uintptr_t); | |
684 | |
685 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
686 "scgi param: \"%s: %s\"", key, val); | |
687 } | |
688 | |
689 b->last = e.pos; | |
690 } | |
691 | |
692 if (scf->upstream.pass_request_headers) { | |
693 | |
694 part = &r->headers_in.headers.part; | |
695 header = part->elts; | |
696 | |
697 for (i = 0; /* void */; i++) { | |
698 | |
699 if (i >= part->nelts) { | |
700 if (part->next == NULL) { | |
701 break; | |
702 } | |
703 | |
704 part = part->next; | |
705 header = part->elts; | |
706 i = 0; | |
707 } | |
708 | |
709 for (n = 0; n < header_params; n++) { | |
710 if (&header[i] == ignored[n]) { | |
711 goto next; | |
712 } | |
713 } | |
714 | |
715 key = b->last; | |
716 b->last = ngx_cpymem(key, "HTTP_", sizeof("HTTP_") - 1); | |
717 | |
718 for (n = 0; n < header[i].key.len; n++) { | |
719 ch = header[i].key.data[n]; | |
720 | |
721 if (ch >= 'a' && ch <= 'z') { | |
722 ch &= ~0x20; | |
723 | |
724 } else if (ch == '-') { | |
725 ch = '_'; | |
726 } | |
727 | |
728 *b->last++ = ch; | |
729 } | |
730 | |
731 *b->last++ = (u_char) 0; | |
732 | |
733 val = b->last; | |
734 b->last = ngx_copy(val, header[i].value.data, header[i].value.len); | |
735 *b->last++ = (u_char) 0; | |
736 | |
737 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
738 "scgi param: \"%s: %s\"", key, val); | |
739 | |
740 next: | |
741 | |
742 continue; | |
743 } | |
744 } | |
745 | |
746 *b->last++ = (u_char) ','; | |
747 | |
748 if (scf->upstream.pass_request_body) { | |
749 body = r->upstream->request_bufs; | |
750 r->upstream->request_bufs = cl; | |
751 | |
752 while (body) { | |
753 b = ngx_alloc_buf(r->pool); | |
754 if (b == NULL) { | |
755 return NGX_ERROR; | |
756 } | |
757 | |
758 ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); | |
759 | |
760 cl->next = ngx_alloc_chain_link(r->pool); | |
761 if (cl->next == NULL) { | |
762 return NGX_ERROR; | |
763 } | |
764 | |
765 cl = cl->next; | |
766 cl->buf = b; | |
767 | |
768 body = body->next; | |
769 } | |
770 | |
771 } else { | |
772 r->upstream->request_bufs = cl; | |
773 } | |
774 | |
775 cl->next = NULL; | |
776 | |
777 return NGX_OK; | |
778 } | |
779 | |
780 | |
781 static ngx_int_t | |
782 ngx_http_scgi_reinit_request(ngx_http_request_t *r) | |
783 { | |
784 ngx_http_status_t *status; | |
785 | |
786 status = ngx_http_get_module_ctx(r, ngx_http_scgi_module); | |
787 | |
788 if (status == NULL) { | |
789 return NGX_OK; | |
790 } | |
791 | |
792 status->code = 0; | |
793 status->count = 0; | |
794 status->start = NULL; | |
795 status->end = NULL; | |
796 | |
797 r->upstream->process_header = ngx_http_scgi_process_status_line; | |
798 | |
799 return NGX_OK; | |
800 } | |
801 | |
802 | |
803 static ngx_int_t | |
804 ngx_http_scgi_process_status_line(ngx_http_request_t *r) | |
805 { | |
806 size_t len; | |
807 ngx_int_t rc; | |
808 ngx_http_status_t *status; | |
809 ngx_http_upstream_t *u; | |
810 | |
811 status = ngx_http_get_module_ctx(r, ngx_http_scgi_module); | |
812 | |
813 if (status == NULL) { | |
814 return NGX_ERROR; | |
815 } | |
816 | |
817 u = r->upstream; | |
818 | |
819 rc = ngx_http_parse_status_line(r, &u->buffer, status); | |
820 | |
821 if (rc == NGX_AGAIN) { | |
822 return rc; | |
823 } | |
824 | |
825 if (rc == NGX_ERROR) { | |
826 u->process_header = ngx_http_scgi_process_header; | |
827 return ngx_http_scgi_process_header(r); | |
828 } | |
829 | |
830 if (u->state) { | |
831 u->state->status = status->code; | |
832 } | |
833 | |
834 u->headers_in.status_n = status->code; | |
835 | |
836 len = status->end - status->start; | |
837 u->headers_in.status_line.len = len; | |
838 | |
839 u->headers_in.status_line.data = ngx_pnalloc(r->pool, len); | |
840 if (u->headers_in.status_line.data == NULL) { | |
841 return NGX_ERROR; | |
842 } | |
843 | |
844 ngx_memcpy(u->headers_in.status_line.data, status->start, len); | |
845 | |
846 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
847 "http scgi status %ui \"%V\"", | |
848 u->headers_in.status_n, &u->headers_in.status_line); | |
849 | |
850 u->process_header = ngx_http_scgi_process_header; | |
851 | |
852 return ngx_http_scgi_process_header(r); | |
853 } | |
854 | |
855 | |
856 static ngx_int_t | |
857 ngx_http_scgi_process_header(ngx_http_request_t *r) | |
858 { | |
859 ngx_str_t *status_line; | |
860 ngx_int_t rc, status; | |
861 ngx_table_elt_t *h; | |
862 ngx_http_upstream_t *u; | |
863 ngx_http_upstream_header_t *hh; | |
864 ngx_http_upstream_main_conf_t *umcf; | |
865 | |
866 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | |
867 | |
868 for ( ;; ) { | |
869 | |
870 rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1); | |
871 | |
872 if (rc == NGX_OK) { | |
873 | |
874 /* a header line has been parsed successfully */ | |
875 | |
876 h = ngx_list_push(&r->upstream->headers_in.headers); | |
877 if (h == NULL) { | |
878 return NGX_ERROR; | |
879 } | |
880 | |
881 h->hash = r->header_hash; | |
882 | |
883 h->key.len = r->header_name_end - r->header_name_start; | |
884 h->value.len = r->header_end - r->header_start; | |
885 | |
886 h->key.data = ngx_pnalloc(r->pool, | |
887 h->key.len + 1 + h->value.len + 1 | |
888 + h->key.len); | |
889 if (h->key.data == NULL) { | |
890 return NGX_ERROR; | |
891 } | |
892 | |
893 h->value.data = h->key.data + h->key.len + 1; | |
894 h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1; | |
895 | |
896 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); | |
897 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); | |
898 | |
899 if (h->key.len == r->lowcase_index) { | |
900 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); | |
901 | |
902 } else { | |
903 ngx_strlow(h->lowcase_key, h->key.data, h->key.len); | |
904 } | |
905 | |
906 hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, | |
907 h->lowcase_key, h->key.len); | |
908 | |
909 if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { | |
910 return NGX_ERROR; | |
911 } | |
912 | |
913 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
914 "http scgi header: \"%V: %V\"", &h->key, &h->value); | |
915 | |
916 continue; | |
917 } | |
918 | |
919 if (rc == NGX_HTTP_PARSE_HEADER_DONE) { | |
920 | |
921 /* a whole header has been parsed successfully */ | |
922 | |
923 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
924 "http scgi header done"); | |
925 | |
4437
3a1507f48686
Merge of r4372, r4373, r4374:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4362
diff
changeset
|
926 u = r->upstream; |
3a1507f48686
Merge of r4372, r4373, r4374:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4362
diff
changeset
|
927 |
3a1507f48686
Merge of r4372, r4373, r4374:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4362
diff
changeset
|
928 if (u->headers_in.status_n) { |
3637 | 929 return NGX_OK; |
930 } | |
931 | |
932 if (u->headers_in.status) { | |
933 status_line = &u->headers_in.status->value; | |
934 | |
935 status = ngx_atoi(status_line->data, 3); | |
936 if (status == NGX_ERROR) { | |
937 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
938 "upstream sent invalid status \"%V\"", | |
939 status_line); | |
940 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
941 } | |
942 | |
943 u->headers_in.status_n = status; | |
944 u->headers_in.status_line = *status_line; | |
945 | |
946 } else if (u->headers_in.location) { | |
947 u->headers_in.status_n = 302; | |
948 ngx_str_set(&u->headers_in.status_line, | |
949 "302 Moved Temporarily"); | |
950 | |
951 } else { | |
952 u->headers_in.status_n = 200; | |
953 ngx_str_set(&u->headers_in.status_line, "200 OK"); | |
954 } | |
955 | |
956 if (u->state) { | |
957 u->state->status = u->headers_in.status_n; | |
958 } | |
959 | |
960 return NGX_OK; | |
961 } | |
962 | |
963 if (rc == NGX_AGAIN) { | |
964 return NGX_AGAIN; | |
965 } | |
966 | |
967 /* there was error while a header line parsing */ | |
968 | |
969 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
970 "upstream sent invalid header"); | |
971 | |
972 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
973 } | |
974 } | |
975 | |
976 | |
977 static void | |
978 ngx_http_scgi_abort_request(ngx_http_request_t *r) | |
979 { | |
980 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
981 "abort http scgi request"); | |
982 | |
983 return; | |
984 } | |
985 | |
986 | |
987 static void | |
988 ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc) | |
989 { | |
990 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
991 "finalize http scgi request"); | |
992 | |
993 return; | |
994 } | |
995 | |
996 | |
997 static void * | |
998 ngx_http_scgi_create_loc_conf(ngx_conf_t *cf) | |
999 { | |
1000 ngx_http_scgi_loc_conf_t *conf; | |
1001 | |
1002 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_scgi_loc_conf_t)); | |
1003 if (conf == NULL) { | |
1004 return NULL; | |
1005 } | |
1006 | |
1007 conf->upstream.store = NGX_CONF_UNSET; | |
1008 conf->upstream.store_access = NGX_CONF_UNSET_UINT; | |
1009 conf->upstream.buffering = NGX_CONF_UNSET; | |
1010 conf->upstream.ignore_client_abort = NGX_CONF_UNSET; | |
1011 | |
1012 conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; | |
1013 conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; | |
1014 conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; | |
1015 | |
1016 conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; | |
1017 conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; | |
1018 | |
1019 conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE; | |
1020 conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; | |
1021 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; | |
1022 | |
1023 conf->upstream.pass_request_headers = NGX_CONF_UNSET; | |
1024 conf->upstream.pass_request_body = NGX_CONF_UNSET; | |
1025 | |
1026 #if (NGX_HTTP_CACHE) | |
1027 conf->upstream.cache = NGX_CONF_UNSET_PTR; | |
1028 conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; | |
3699
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
1029 conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; |
3693
e3bcc2f4c418
fix scgi_no_cache and uwsgi_no_cache initialization
Igor Sysoev <igor@sysoev.ru>
parents:
3692
diff
changeset
|
1030 conf->upstream.no_cache = NGX_CONF_UNSET_PTR; |
3637 | 1031 conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; |
1032 #endif | |
1033 | |
1034 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; | |
1035 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; | |
1036 | |
1037 conf->upstream.intercept_errors = NGX_CONF_UNSET; | |
1038 | |
1039 /* "scgi_cyclic_temp_file" is disabled */ | |
1040 conf->upstream.cyclic_temp_file = 0; | |
1041 | |
4252 | 1042 conf->upstream.change_buffering = 1; |
1043 | |
4045
2d062c031fff
Merge of r3964, r3977, r3978:
Igor Sysoev <igor@sysoev.ru>
parents:
3879
diff
changeset
|
1044 ngx_str_set(&conf->upstream.module, "scgi"); |
2d062c031fff
Merge of r3964, r3977, r3978:
Igor Sysoev <igor@sysoev.ru>
parents:
3879
diff
changeset
|
1045 |
3637 | 1046 return conf; |
1047 } | |
1048 | |
1049 | |
1050 static char * | |
1051 ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
1052 { | |
1053 ngx_http_scgi_loc_conf_t *prev = parent; | |
1054 ngx_http_scgi_loc_conf_t *conf = child; | |
1055 | |
1056 size_t size; | |
1057 ngx_hash_init_t hash; | |
3731
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1058 ngx_http_core_loc_conf_t *clcf; |
3637 | 1059 |
1060 if (conf->upstream.store != 0) { | |
1061 ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0); | |
1062 | |
1063 if (conf->upstream.store_lengths == NULL) { | |
1064 conf->upstream.store_lengths = prev->upstream.store_lengths; | |
1065 conf->upstream.store_values = prev->upstream.store_values; | |
1066 } | |
1067 } | |
1068 | |
1069 ngx_conf_merge_uint_value(conf->upstream.store_access, | |
1070 prev->upstream.store_access, 0600); | |
1071 | |
1072 ngx_conf_merge_value(conf->upstream.buffering, | |
1073 prev->upstream.buffering, 1); | |
1074 | |
1075 ngx_conf_merge_value(conf->upstream.ignore_client_abort, | |
1076 prev->upstream.ignore_client_abort, 0); | |
1077 | |
1078 ngx_conf_merge_msec_value(conf->upstream.connect_timeout, | |
1079 prev->upstream.connect_timeout, 60000); | |
1080 | |
1081 ngx_conf_merge_msec_value(conf->upstream.send_timeout, | |
1082 prev->upstream.send_timeout, 60000); | |
1083 | |
1084 ngx_conf_merge_msec_value(conf->upstream.read_timeout, | |
1085 prev->upstream.read_timeout, 60000); | |
1086 | |
1087 ngx_conf_merge_size_value(conf->upstream.send_lowat, | |
1088 prev->upstream.send_lowat, 0); | |
1089 | |
1090 ngx_conf_merge_size_value(conf->upstream.buffer_size, | |
1091 prev->upstream.buffer_size, | |
1092 (size_t) ngx_pagesize); | |
1093 | |
1094 | |
1095 ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, | |
1096 8, ngx_pagesize); | |
1097 | |
1098 if (conf->upstream.bufs.num < 2) { | |
1099 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1100 "there must be at least 2 \"scgi_buffers\""); | |
1101 return NGX_CONF_ERROR; | |
1102 } | |
1103 | |
1104 | |
1105 size = conf->upstream.buffer_size; | |
1106 if (size < conf->upstream.bufs.size) { | |
1107 size = conf->upstream.bufs.size; | |
1108 } | |
1109 | |
1110 | |
1111 ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf, | |
1112 prev->upstream.busy_buffers_size_conf, | |
1113 NGX_CONF_UNSET_SIZE); | |
1114 | |
1115 if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) { | |
1116 conf->upstream.busy_buffers_size = 2 * size; | |
1117 } else { | |
1118 conf->upstream.busy_buffers_size = | |
1119 conf->upstream.busy_buffers_size_conf; | |
1120 } | |
1121 | |
1122 if (conf->upstream.busy_buffers_size < size) { | |
1123 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1124 "\"scgi_busy_buffers_size\" must be equal or bigger " | |
1125 "than maximum of the value of \"scgi_buffer_size\" and " | |
1126 "one of the \"scgi_buffers\""); | |
1127 | |
1128 return NGX_CONF_ERROR; | |
1129 } | |
1130 | |
1131 if (conf->upstream.busy_buffers_size | |
1132 > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size) | |
1133 { | |
1134 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1135 "\"scgi_busy_buffers_size\" must be less than " | |
1136 "the size of all \"scgi_buffers\" minus one buffer"); | |
1137 | |
1138 return NGX_CONF_ERROR; | |
1139 } | |
1140 | |
1141 | |
1142 ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf, | |
1143 prev->upstream.temp_file_write_size_conf, | |
1144 NGX_CONF_UNSET_SIZE); | |
1145 | |
1146 if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) { | |
1147 conf->upstream.temp_file_write_size = 2 * size; | |
1148 } else { | |
1149 conf->upstream.temp_file_write_size = | |
1150 conf->upstream.temp_file_write_size_conf; | |
1151 } | |
1152 | |
1153 if (conf->upstream.temp_file_write_size < size) { | |
1154 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1155 "\"scgi_temp_file_write_size\" must be equal or bigger than " | |
1156 "maximum of the value of \"scgi_buffer_size\" and " | |
1157 "one of the \"scgi_buffers\""); | |
1158 | |
1159 return NGX_CONF_ERROR; | |
1160 } | |
1161 | |
1162 | |
1163 ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf, | |
1164 prev->upstream.max_temp_file_size_conf, | |
1165 NGX_CONF_UNSET_SIZE); | |
1166 | |
1167 if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) { | |
1168 conf->upstream.max_temp_file_size = 1024 * 1024 * 1024; | |
1169 } else { | |
1170 conf->upstream.max_temp_file_size = | |
1171 conf->upstream.max_temp_file_size_conf; | |
1172 } | |
1173 | |
1174 if (conf->upstream.max_temp_file_size != 0 | |
1175 && conf->upstream.max_temp_file_size < size) { | |
1176 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1177 "\"scgi_max_temp_file_size\" must be equal to zero to disable " | |
1178 "the temporary files usage or must be equal or bigger than " | |
1179 "maximum of the value of \"scgi_buffer_size\" and " | |
1180 "one of the \"scgi_buffers\""); | |
1181 | |
1182 return NGX_CONF_ERROR; | |
1183 } | |
1184 | |
1185 | |
1186 ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers, | |
1187 prev->upstream.ignore_headers, | |
1188 NGX_CONF_BITMASK_SET); | |
1189 | |
1190 | |
1191 ngx_conf_merge_bitmask_value(conf->upstream.next_upstream, | |
1192 prev->upstream.next_upstream, | |
1193 (NGX_CONF_BITMASK_SET | |
1194 |NGX_HTTP_UPSTREAM_FT_ERROR | |
1195 |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); | |
1196 | |
1197 if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) { | |
1198 conf->upstream.next_upstream = NGX_CONF_BITMASK_SET | |
1199 |NGX_HTTP_UPSTREAM_FT_OFF; | |
1200 } | |
1201 | |
1202 if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path, | |
1203 prev->upstream.temp_path, | |
1204 &ngx_http_scgi_temp_path) | |
1205 != NGX_OK) | |
1206 { | |
1207 return NGX_CONF_ERROR; | |
1208 } | |
1209 | |
1210 #if (NGX_HTTP_CACHE) | |
1211 | |
1212 ngx_conf_merge_ptr_value(conf->upstream.cache, | |
1213 prev->upstream.cache, NULL); | |
1214 | |
1215 if (conf->upstream.cache && conf->upstream.cache->data == NULL) { | |
1216 ngx_shm_zone_t *shm_zone; | |
1217 | |
1218 shm_zone = conf->upstream.cache; | |
1219 | |
1220 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1221 "\"scgi_cache\" zone \"%V\" is unknown", | |
1222 &shm_zone->shm.name); | |
1223 | |
1224 return NGX_CONF_ERROR; | |
1225 } | |
1226 | |
1227 ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, | |
1228 prev->upstream.cache_min_uses, 1); | |
1229 | |
1230 ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, | |
1231 prev->upstream.cache_use_stale, | |
1232 (NGX_CONF_BITMASK_SET | |
1233 |NGX_HTTP_UPSTREAM_FT_OFF)); | |
1234 | |
1235 if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) { | |
1236 conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET | |
1237 |NGX_HTTP_UPSTREAM_FT_OFF; | |
1238 } | |
1239 | |
1240 if (conf->upstream.cache_methods == 0) { | |
1241 conf->upstream.cache_methods = prev->upstream.cache_methods; | |
1242 } | |
1243 | |
1244 conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; | |
1245 | |
3699
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
1246 ngx_conf_merge_ptr_value(conf->upstream.cache_bypass, |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
1247 prev->upstream.cache_bypass, NULL); |
b0a0686a85bb
proxy_cache_pass, fastcgi_cache_bypass, uwsgi_cache_bypass, scgi_cache_bypass
Igor Sysoev <igor@sysoev.ru>
parents:
3693
diff
changeset
|
1248 |
3637 | 1249 ngx_conf_merge_ptr_value(conf->upstream.no_cache, |
1250 prev->upstream.no_cache, NULL); | |
1251 | |
1252 ngx_conf_merge_ptr_value(conf->upstream.cache_valid, | |
1253 prev->upstream.cache_valid, NULL); | |
1254 | |
1255 if (conf->cache_key.value.data == NULL) { | |
1256 conf->cache_key = prev->cache_key; | |
1257 } | |
1258 | |
1259 #endif | |
1260 | |
1261 ngx_conf_merge_value(conf->upstream.pass_request_headers, | |
1262 prev->upstream.pass_request_headers, 1); | |
1263 ngx_conf_merge_value(conf->upstream.pass_request_body, | |
1264 prev->upstream.pass_request_body, 1); | |
1265 | |
1266 ngx_conf_merge_value(conf->upstream.intercept_errors, | |
1267 prev->upstream.intercept_errors, 0); | |
1268 | |
1269 hash.max_size = 512; | |
1270 hash.bucket_size = ngx_align(64, ngx_cacheline_size); | |
1271 hash.name = "scgi_hide_headers_hash"; | |
1272 | |
1273 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, | |
3670
2728c4e4a9ae
do not use a cache headers set to hide
Igor Sysoev <igor@sysoev.ru>
parents:
3668
diff
changeset
|
1274 &prev->upstream, ngx_http_scgi_hide_headers, &hash) |
3637 | 1275 != NGX_OK) |
1276 { | |
1277 return NGX_CONF_ERROR; | |
1278 } | |
1279 | |
1280 if (conf->upstream.upstream == NULL) { | |
1281 conf->upstream.upstream = prev->upstream.upstream; | |
1282 } | |
1283 | |
1284 if (conf->scgi_lengths == NULL) { | |
1285 conf->scgi_lengths = prev->scgi_lengths; | |
1286 conf->scgi_values = prev->scgi_values; | |
1287 } | |
1288 | |
3731
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1289 if (conf->upstream.upstream || conf->scgi_lengths) { |
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1290 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); |
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1291 if (clcf->handler == NULL && clcf->lmt_excpt) { |
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1292 clcf->handler = ngx_http_scgi_handler; |
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1293 } |
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1294 } |
72cc5b789021
inherit proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass inside
Igor Sysoev <igor@sysoev.ru>
parents:
3729
diff
changeset
|
1295 |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1296 if (ngx_http_scgi_merge_params(cf, conf, prev) != NGX_OK) { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1297 return NGX_CONF_ERROR; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1298 } |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1299 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1300 return NGX_CONF_OK; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1301 } |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1302 |
3637 | 1303 |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1304 static ngx_int_t |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1305 ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf, |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1306 ngx_http_scgi_loc_conf_t *prev) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1307 { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1308 u_char *p; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1309 size_t size; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1310 uintptr_t *code; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1311 ngx_uint_t i, nsrc; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1312 ngx_array_t headers_names; |
3637 | 1313 #if (NGX_HTTP_CACHE) |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1314 ngx_array_t params_merged; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1315 #endif |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1316 ngx_keyval_t *src; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1317 ngx_hash_key_t *hk; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1318 ngx_hash_init_t hash; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1319 ngx_http_script_compile_t sc; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1320 ngx_http_script_copy_code_t *copy; |
3637 | 1321 |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1322 if (conf->params_source == NULL) { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1323 conf->params_source = prev->params_source; |
3637 | 1324 |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1325 if (prev->headers_hash.buckets |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1326 #if (NGX_HTTP_CACHE) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1327 && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1328 #endif |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1329 ) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1330 { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1331 conf->flushes = prev->flushes; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1332 conf->params_len = prev->params_len; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1333 conf->params = prev->params; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1334 conf->headers_hash = prev->headers_hash; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1335 conf->header_params = prev->header_params; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1336 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1337 return NGX_OK; |
3637 | 1338 } |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1339 } |
3637 | 1340 |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1341 if (conf->params_source == NULL |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1342 #if (NGX_HTTP_CACHE) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1343 && (conf->upstream.cache == NULL) |
3637 | 1344 #endif |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1345 ) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1346 { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1347 conf->headers_hash.buckets = (void *) 1; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1348 return NGX_OK; |
3637 | 1349 } |
1350 | |
1351 conf->params_len = ngx_array_create(cf->pool, 64, 1); | |
1352 if (conf->params_len == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1353 return NGX_ERROR; |
3637 | 1354 } |
1355 | |
1356 conf->params = ngx_array_create(cf->pool, 512, 1); | |
1357 if (conf->params == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1358 return NGX_ERROR; |
3637 | 1359 } |
1360 | |
1361 if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) | |
1362 != NGX_OK) | |
1363 { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1364 return NGX_ERROR; |
3637 | 1365 } |
1366 | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1367 if (conf->params_source) { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1368 src = conf->params_source->elts; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1369 nsrc = conf->params_source->nelts; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1370 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1371 } else { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1372 src = NULL; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1373 nsrc = 0; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1374 } |
3637 | 1375 |
1376 #if (NGX_HTTP_CACHE) | |
1377 | |
1378 if (conf->upstream.cache) { | |
1379 ngx_keyval_t *h, *s; | |
1380 | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1381 if (ngx_array_init(¶ms_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1382 != NGX_OK) |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1383 { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1384 return NGX_ERROR; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1385 } |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1386 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1387 for (i = 0; i < nsrc; i++) { |
3637 | 1388 |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1389 s = ngx_array_push(¶ms_merged); |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1390 if (s == NULL) { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1391 return NGX_ERROR; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1392 } |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1393 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1394 *s = src[i]; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1395 } |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1396 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1397 h = ngx_http_scgi_cache_headers; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1398 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1399 while (h->key.len) { |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1400 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1401 src = params_merged.elts; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1402 nsrc = params_merged.nelts; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1403 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1404 for (i = 0; i < nsrc; i++) { |
3637 | 1405 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
1406 goto next; | |
1407 } | |
1408 } | |
1409 | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1410 s = ngx_array_push(¶ms_merged); |
3637 | 1411 if (s == NULL) { |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1412 return NGX_ERROR; |
3637 | 1413 } |
1414 | |
1415 *s = *h; | |
1416 | |
1417 next: | |
1418 | |
1419 h++; | |
1420 } | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1421 |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1422 src = params_merged.elts; |
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1423 nsrc = params_merged.nelts; |
3637 | 1424 } |
1425 | |
1426 #endif | |
1427 | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1428 for (i = 0; i < nsrc; i++) { |
3637 | 1429 |
1430 if (src[i].key.len > sizeof("HTTP_") - 1 | |
1431 && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) | |
1432 { | |
1433 hk = ngx_array_push(&headers_names); | |
1434 if (hk == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1435 return NGX_ERROR; |
3637 | 1436 } |
1437 | |
1438 hk->key.len = src[i].key.len - 5; | |
1439 hk->key.data = src[i].key.data + 5; | |
1440 hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len); | |
1441 hk->value = (void *) 1; | |
1442 | |
1443 if (src[i].value.len == 0) { | |
1444 continue; | |
1445 } | |
1446 } | |
1447 | |
1448 copy = ngx_array_push_n(conf->params_len, | |
1449 sizeof(ngx_http_script_copy_code_t)); | |
1450 if (copy == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1451 return NGX_ERROR; |
3637 | 1452 } |
1453 | |
1454 copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; | |
1455 copy->len = src[i].key.len + 1; | |
1456 | |
1457 | |
1458 size = (sizeof(ngx_http_script_copy_code_t) | |
1459 + src[i].key.len + 1 + sizeof(uintptr_t) - 1) | |
1460 & ~(sizeof(uintptr_t) - 1); | |
1461 | |
1462 copy = ngx_array_push_n(conf->params, size); | |
1463 if (copy == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1464 return NGX_ERROR; |
3637 | 1465 } |
1466 | |
1467 copy->code = ngx_http_script_copy_code; | |
1468 copy->len = src[i].key.len + 1; | |
1469 | |
1470 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); | |
1471 (void) ngx_cpystrn(p, src[i].key.data, src[i].key.len + 1); | |
1472 | |
1473 | |
1474 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
1475 | |
1476 sc.cf = cf; | |
1477 sc.source = &src[i].value; | |
1478 sc.flushes = &conf->flushes; | |
1479 sc.lengths = &conf->params_len; | |
1480 sc.values = &conf->params; | |
1481 | |
1482 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1483 return NGX_ERROR; |
3637 | 1484 } |
1485 | |
1486 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); | |
1487 if (code == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1488 return NGX_ERROR; |
3637 | 1489 } |
1490 | |
1491 *code = (uintptr_t) NULL; | |
1492 | |
1493 | |
1494 code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); | |
1495 if (code == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1496 return NGX_ERROR; |
3637 | 1497 } |
1498 | |
1499 *code = (uintptr_t) NULL; | |
1500 } | |
1501 | |
1502 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); | |
1503 if (code == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1504 return NGX_ERROR; |
3637 | 1505 } |
1506 | |
1507 *code = (uintptr_t) NULL; | |
1508 | |
1509 code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); | |
1510 if (code == NULL) { | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1511 return NGX_ERROR; |
3637 | 1512 } |
1513 | |
1514 *code = (uintptr_t) NULL; | |
1515 | |
1516 conf->header_params = headers_names.nelts; | |
1517 | |
1518 hash.hash = &conf->headers_hash; | |
1519 hash.key = ngx_hash_key_lc; | |
1520 hash.max_size = 512; | |
1521 hash.bucket_size = 64; | |
1522 hash.name = "scgi_params_hash"; | |
1523 hash.pool = cf->pool; | |
1524 hash.temp_pool = NULL; | |
1525 | |
4358
94b995c7c614
Merge of r4275, r4276, r4278, r4279:
Maxim Dounin <mdounin@mdounin.ru>
parents:
4252
diff
changeset
|
1526 return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); |
3637 | 1527 } |
1528 | |
1529 | |
1530 static char * | |
1531 ngx_http_scgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1532 { | |
1533 ngx_http_scgi_loc_conf_t *scf = conf; | |
1534 | |
1535 ngx_url_t u; | |
1536 ngx_str_t *value, *url; | |
1537 ngx_uint_t n; | |
1538 ngx_http_core_loc_conf_t *clcf; | |
1539 ngx_http_script_compile_t sc; | |
1540 | |
1541 if (scf->upstream.upstream || scf->scgi_lengths) { | |
1542 return "is duplicate"; | |
1543 } | |
1544 | |
1545 clcf = ngx_http_conf_get_module_loc_conf (cf, ngx_http_core_module); | |
1546 clcf->handler = ngx_http_scgi_handler; | |
1547 | |
1548 value = cf->args->elts; | |
1549 | |
1550 url = &value[1]; | |
1551 | |
1552 n = ngx_http_script_variables_count(url); | |
1553 | |
1554 if (n) { | |
1555 | |
1556 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
1557 | |
1558 sc.cf = cf; | |
1559 sc.source = url; | |
1560 sc.lengths = &scf->scgi_lengths; | |
1561 sc.values = &scf->scgi_values; | |
1562 sc.variables = n; | |
1563 sc.complete_lengths = 1; | |
1564 sc.complete_values = 1; | |
1565 | |
1566 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
1567 return NGX_CONF_ERROR; | |
1568 } | |
1569 | |
1570 return NGX_CONF_OK; | |
1571 } | |
1572 | |
1573 ngx_memzero(&u, sizeof(ngx_url_t)); | |
1574 | |
1575 u.url = value[1]; | |
1576 u.no_resolve = 1; | |
1577 | |
1578 scf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); | |
1579 if (scf->upstream.upstream == NULL) { | |
1580 return NGX_CONF_ERROR; | |
1581 } | |
1582 | |
1583 if (clcf->name.data[clcf->name.len - 1] == '/') { | |
1584 clcf->auto_redirect = 1; | |
1585 } | |
1586 | |
1587 return NGX_CONF_OK; | |
1588 } | |
1589 | |
1590 | |
1591 static char * | |
1592 ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1593 { | |
1594 ngx_http_scgi_loc_conf_t *scf = conf; | |
1595 | |
1596 ngx_str_t *value; | |
1597 ngx_http_script_compile_t sc; | |
1598 | |
1599 if (scf->upstream.store != NGX_CONF_UNSET || scf->upstream.store_lengths) { | |
1600 return "is duplicate"; | |
1601 } | |
1602 | |
1603 value = cf->args->elts; | |
1604 | |
1605 if (ngx_strcmp(value[1].data, "off") == 0) { | |
1606 scf->upstream.store = 0; | |
1607 return NGX_CONF_OK; | |
1608 } | |
1609 | |
1610 #if (NGX_HTTP_CACHE) | |
1611 | |
1612 if (scf->upstream.cache != NGX_CONF_UNSET_PTR | |
1613 && scf->upstream.cache != NULL) | |
1614 { | |
1615 return "is incompatible with \"scgi_cache\""; | |
1616 } | |
1617 | |
1618 #endif | |
1619 | |
1620 if (ngx_strcmp(value[1].data, "on") == 0) { | |
1621 scf->upstream.store = 1; | |
1622 return NGX_CONF_OK; | |
1623 } | |
1624 | |
1625 /* include the terminating '\0' into script */ | |
1626 value[1].len++; | |
1627 | |
1628 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
1629 | |
1630 sc.cf = cf; | |
1631 sc.source = &value[1]; | |
1632 sc.lengths = &scf->upstream.store_lengths; | |
1633 sc.values = &scf->upstream.store_values; | |
1634 sc.variables = ngx_http_script_variables_count(&value[1]);; | |
1635 sc.complete_lengths = 1; | |
1636 sc.complete_values = 1; | |
1637 | |
1638 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
1639 return NGX_CONF_ERROR; | |
1640 } | |
1641 | |
1642 return NGX_CONF_OK; | |
1643 } | |
1644 | |
1645 | |
1646 #if (NGX_HTTP_CACHE) | |
1647 | |
1648 static char * | |
1649 ngx_http_scgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1650 { | |
1651 ngx_http_scgi_loc_conf_t *scf = conf; | |
1652 | |
1653 ngx_str_t *value; | |
1654 | |
1655 value = cf->args->elts; | |
1656 | |
1657 if (scf->upstream.cache != NGX_CONF_UNSET_PTR) { | |
1658 return "is duplicate"; | |
1659 } | |
1660 | |
1661 if (ngx_strcmp(value[1].data, "off") == 0) { | |
1662 scf->upstream.cache = NULL; | |
1663 return NGX_CONF_OK; | |
1664 } | |
1665 | |
1666 if (scf->upstream.store > 0 || scf->upstream.store_lengths) { | |
1667 return "is incompatible with \"scgi_store\""; | |
1668 } | |
1669 | |
1670 scf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0, | |
1671 &ngx_http_scgi_module); | |
1672 if (scf->upstream.cache == NULL) { | |
1673 return NGX_CONF_ERROR; | |
1674 } | |
1675 | |
1676 return NGX_CONF_OK; | |
1677 } | |
1678 | |
1679 | |
1680 static char * | |
1681 ngx_http_scgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1682 { | |
1683 ngx_http_scgi_loc_conf_t *scf = conf; | |
1684 | |
1685 ngx_str_t *value; | |
1686 ngx_http_compile_complex_value_t ccv; | |
1687 | |
1688 value = cf->args->elts; | |
1689 | |
1690 if (scf->cache_key.value.len) { | |
1691 return "is duplicate"; | |
1692 } | |
1693 | |
1694 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
1695 | |
1696 ccv.cf = cf; | |
1697 ccv.value = &value[1]; | |
1698 ccv.complex_value = &scf->cache_key; | |
1699 | |
1700 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1701 return NGX_CONF_ERROR; | |
1702 } | |
1703 | |
1704 return NGX_CONF_OK; | |
1705 } | |
1706 | |
1707 #endif |