Merge of r4275, r4276, r4278, r4279:
Fixes for proxy_set_header, fastcgi/scgi/uwsgi_param inheritance:
*) Fixed proxy_set_header inheritance with proxy_cache (ticket #45).
Headers cleared with cache enabled (If-Modified-Since etc.) might be
cleared in unrelated servers/locations without proxy_cache enabled
if proxy_cache was used in some server/location.
Example config which triggered the problem:
proxy_set_header X-Test "test";
server { location /1 { proxy_cache name; proxy_pass ... } }
server { location /2 { proxy_pass ... } }
Another one:
server {
proxy_cache name;
location /1 { proxy_pass ... }
location /2 { proxy_cache off; proxy_pass ... }
}
In both cases If-Modified-Since header wasn't sent to backend in
location /2.
Fix is to not modify conf->headers_source, but instead merge user-supplied
headers from conf->headers_source and default headers (either cache or not)
into separate headers_merged array.
*) Fixed proxy_set_header inheritance with proxy_set_body.
*) Separate functions to merge fastcgi/scgi/uwsgi params.
No functional changes.
*) Fixed fastcgi/scgi/uwsgi_param inheritance. The following problems were
fixed:
1. Directive fastcgi_cache affected headers sent to backends in unrelated
servers / locations (see ticket #45).
2. If-Unmodified-Since, If-Match and If-Range headers were sent to
backends if fastcgi_cache was used.
3. Cache-related headers were sent to backends if there were no
fastcgi_param directives and fastcgi_cache was used at server level.
Maxim Dounin
10 years ago
141 | 141 | static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf); |
142 | 142 | static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, |
143 | 143 | void *parent, void *child); |
144 | static ngx_int_t ngx_http_fastcgi_merge_params(ngx_conf_t *cf, | |
145 | ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev); | |
146 | ||
144 | 147 | static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r, |
145 | 148 | ngx_http_variable_value_t *v, uintptr_t data); |
146 | 149 | static ngx_int_t ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r, |
2024 | 2027 | ngx_http_fastcgi_loc_conf_t *prev = parent; |
2025 | 2028 | ngx_http_fastcgi_loc_conf_t *conf = child; |
2026 | 2029 | |
2027 | u_char *p; | |
2028 | 2030 | size_t size; |
2029 | uintptr_t *code; | |
2030 | ngx_uint_t i; | |
2031 | ngx_array_t headers_names; | |
2032 | ngx_keyval_t *src; | |
2033 | ngx_hash_key_t *hk; | |
2034 | 2031 | ngx_hash_init_t hash; |
2035 | 2032 | ngx_http_core_loc_conf_t *clcf; |
2036 | ngx_http_script_compile_t sc; | |
2037 | ngx_http_script_copy_code_t *copy; | |
2038 | 2033 | |
2039 | 2034 | if (conf->upstream.store != 0) { |
2040 | 2035 | ngx_conf_merge_value(conf->upstream.store, |
2292 | 2287 | } |
2293 | 2288 | #endif |
2294 | 2289 | |
2290 | if (ngx_http_fastcgi_merge_params(cf, conf, prev) != NGX_OK) { | |
2291 | return NGX_CONF_ERROR; | |
2292 | } | |
2293 | ||
2294 | return NGX_CONF_OK; | |
2295 | } | |
2296 | ||
2297 | ||
2298 | static ngx_int_t | |
2299 | ngx_http_fastcgi_merge_params(ngx_conf_t *cf, | |
2300 | ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev) | |
2301 | { | |
2302 | u_char *p; | |
2303 | size_t size; | |
2304 | uintptr_t *code; | |
2305 | ngx_uint_t i, nsrc; | |
2306 | ngx_array_t headers_names; | |
2307 | #if (NGX_HTTP_CACHE) | |
2308 | ngx_array_t params_merged; | |
2309 | #endif | |
2310 | ngx_keyval_t *src; | |
2311 | ngx_hash_key_t *hk; | |
2312 | ngx_hash_init_t hash; | |
2313 | ngx_http_script_compile_t sc; | |
2314 | ngx_http_script_copy_code_t *copy; | |
2315 | ||
2295 | 2316 | if (conf->params_source == NULL) { |
2296 | conf->flushes = prev->flushes; | |
2297 | conf->params_len = prev->params_len; | |
2298 | conf->params = prev->params; | |
2299 | 2317 | conf->params_source = prev->params_source; |
2300 | conf->headers_hash = prev->headers_hash; | |
2301 | ||
2318 | ||
2319 | if (prev->headers_hash.buckets | |
2302 | 2320 | #if (NGX_HTTP_CACHE) |
2303 | ||
2304 | if (conf->params_source == NULL) { | |
2305 | ||
2306 | if ((conf->upstream.cache == NULL) | |
2307 | == (prev->upstream.cache == NULL)) | |
2308 | { | |
2309 | return NGX_CONF_OK; | |
2310 | } | |
2311 | ||
2312 | /* 6 is a number of ngx_http_fastcgi_cache_headers entries */ | |
2313 | conf->params_source = ngx_array_create(cf->pool, 6, | |
2314 | sizeof(ngx_keyval_t)); | |
2315 | if (conf->params_source == NULL) { | |
2316 | return NGX_CONF_ERROR; | |
2317 | } | |
2318 | } | |
2319 | #else | |
2320 | ||
2321 | if (conf->params_source == NULL) { | |
2322 | return NGX_CONF_OK; | |
2323 | } | |
2324 | ||
2321 | && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) | |
2325 | 2322 | #endif |
2323 | ) | |
2324 | { | |
2325 | conf->flushes = prev->flushes; | |
2326 | conf->params_len = prev->params_len; | |
2327 | conf->params = prev->params; | |
2328 | conf->headers_hash = prev->headers_hash; | |
2329 | conf->header_params = prev->header_params; | |
2330 | ||
2331 | return NGX_OK; | |
2332 | } | |
2333 | } | |
2334 | ||
2335 | if (conf->params_source == NULL | |
2336 | #if (NGX_HTTP_CACHE) | |
2337 | && (conf->upstream.cache == NULL) | |
2338 | #endif | |
2339 | ) | |
2340 | { | |
2341 | conf->headers_hash.buckets = (void *) 1; | |
2342 | return NGX_OK; | |
2326 | 2343 | } |
2327 | 2344 | |
2328 | 2345 | conf->params_len = ngx_array_create(cf->pool, 64, 1); |
2329 | 2346 | if (conf->params_len == NULL) { |
2330 | return NGX_CONF_ERROR; | |
2347 | return NGX_ERROR; | |
2331 | 2348 | } |
2332 | 2349 | |
2333 | 2350 | conf->params = ngx_array_create(cf->pool, 512, 1); |
2334 | 2351 | if (conf->params == NULL) { |
2335 | return NGX_CONF_ERROR; | |
2352 | return NGX_ERROR; | |
2336 | 2353 | } |
2337 | 2354 | |
2338 | 2355 | if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) |
2339 | 2356 | != NGX_OK) |
2340 | 2357 | { |
2341 | return NGX_CONF_ERROR; | |
2342 | } | |
2343 | ||
2344 | src = conf->params_source->elts; | |
2358 | return NGX_ERROR; | |
2359 | } | |
2360 | ||
2361 | if (conf->params_source) { | |
2362 | src = conf->params_source->elts; | |
2363 | nsrc = conf->params_source->nelts; | |
2364 | ||
2365 | } else { | |
2366 | src = NULL; | |
2367 | nsrc = 0; | |
2368 | } | |
2345 | 2369 | |
2346 | 2370 | #if (NGX_HTTP_CACHE) |
2347 | 2371 | |
2348 | 2372 | if (conf->upstream.cache) { |
2349 | 2373 | ngx_keyval_t *h, *s; |
2350 | 2374 | |
2351 | for (h = ngx_http_fastcgi_cache_headers; h->key.len; h++) { | |
2352 | ||
2353 | for (i = 0; i < conf->params_source->nelts; i++) { | |
2375 | if (ngx_array_init(¶ms_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) | |
2376 | != NGX_OK) | |
2377 | { | |
2378 | return NGX_ERROR; | |
2379 | } | |
2380 | ||
2381 | for (i = 0; i < nsrc; i++) { | |
2382 | ||
2383 | s = ngx_array_push(¶ms_merged); | |
2384 | if (s == NULL) { | |
2385 | return NGX_ERROR; | |
2386 | } | |
2387 | ||
2388 | *s = src[i]; | |
2389 | } | |
2390 | ||
2391 | h = ngx_http_fastcgi_cache_headers; | |
2392 | ||
2393 | while (h->key.len) { | |
2394 | ||
2395 | src = params_merged.elts; | |
2396 | nsrc = params_merged.nelts; | |
2397 | ||
2398 | for (i = 0; i < nsrc; i++) { | |
2354 | 2399 | if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
2355 | 2400 | goto next; |
2356 | 2401 | } |
2357 | 2402 | } |
2358 | 2403 | |
2359 | s = ngx_array_push(conf->params_source); | |
2404 | s = ngx_array_push(¶ms_merged); | |
2360 | 2405 | if (s == NULL) { |
2361 | return NGX_CONF_ERROR; | |
2406 | return NGX_ERROR; | |
2362 | 2407 | } |
2363 | 2408 | |
2364 | 2409 | *s = *h; |
2365 | 2410 | |
2366 | src = conf->params_source->elts; | |
2367 | ||
2368 | 2411 | next: |
2369 | 2412 | |
2370 | 2413 | h++; |
2371 | 2414 | } |
2415 | ||
2416 | src = params_merged.elts; | |
2417 | nsrc = params_merged.nelts; | |
2372 | 2418 | } |
2373 | 2419 | |
2374 | 2420 | #endif |
2375 | 2421 | |
2376 | for (i = 0; i < conf->params_source->nelts; i++) { | |
2422 | for (i = 0; i < nsrc; i++) { | |
2377 | 2423 | |
2378 | 2424 | if (src[i].key.len > sizeof("HTTP_") - 1 |
2379 | 2425 | && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) |
2380 | 2426 | { |
2381 | 2427 | hk = ngx_array_push(&headers_names); |
2382 | 2428 | if (hk == NULL) { |
2383 | return NGX_CONF_ERROR; | |
2429 | return NGX_ERROR; | |
2384 | 2430 | } |
2385 | 2431 | |
2386 | 2432 | hk->key.len = src[i].key.len - 5; |
2396 | 2442 | copy = ngx_array_push_n(conf->params_len, |
2397 | 2443 | sizeof(ngx_http_script_copy_code_t)); |
2398 | 2444 | if (copy == NULL) { |
2399 | return NGX_CONF_ERROR; | |
2445 | return NGX_ERROR; | |
2400 | 2446 | } |
2401 | 2447 | |
2402 | 2448 | copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; |
2405 | 2451 | |
2406 | 2452 | size = (sizeof(ngx_http_script_copy_code_t) |
2407 | 2453 | + src[i].key.len + sizeof(uintptr_t) - 1) |
2408 | & ~(sizeof(uintptr_t) - 1); | |
2454 | & ~(sizeof(uintptr_t) - 1); | |
2409 | 2455 | |
2410 | 2456 | copy = ngx_array_push_n(conf->params, size); |
2411 | 2457 | if (copy == NULL) { |
2412 | return NGX_CONF_ERROR; | |
2458 | return NGX_ERROR; | |
2413 | 2459 | } |
2414 | 2460 | |
2415 | 2461 | copy->code = ngx_http_script_copy_code; |
2428 | 2474 | sc.values = &conf->params; |
2429 | 2475 | |
2430 | 2476 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
2431 | return NGX_CONF_ERROR; | |
2477 | return NGX_ERROR; | |
2432 | 2478 | } |
2433 | 2479 | |
2434 | 2480 | code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
2435 | 2481 | if (code == NULL) { |
2436 | return NGX_CONF_ERROR; | |
2482 | return NGX_ERROR; | |
2437 | 2483 | } |
2438 | 2484 | |
2439 | 2485 | *code = (uintptr_t) NULL; |
2441 | 2487 | |
2442 | 2488 | code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); |
2443 | 2489 | if (code == NULL) { |
2444 | return NGX_CONF_ERROR; | |
2490 | return NGX_ERROR; | |
2445 | 2491 | } |
2446 | 2492 | |
2447 | 2493 | *code = (uintptr_t) NULL; |
2449 | 2495 | |
2450 | 2496 | code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
2451 | 2497 | if (code == NULL) { |
2452 | return NGX_CONF_ERROR; | |
2498 | return NGX_ERROR; | |
2453 | 2499 | } |
2454 | 2500 | |
2455 | 2501 | *code = (uintptr_t) NULL; |
2456 | ||
2457 | 2502 | |
2458 | 2503 | conf->header_params = headers_names.nelts; |
2459 | 2504 | |
2465 | 2510 | hash.pool = cf->pool; |
2466 | 2511 | hash.temp_pool = NULL; |
2467 | 2512 | |
2468 | if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK) | |
2469 | { | |
2470 | return NGX_CONF_ERROR; | |
2471 | } | |
2472 | ||
2473 | return NGX_CONF_OK; | |
2513 | return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); | |
2474 | 2514 | } |
2475 | 2515 | |
2476 | 2516 |
1721 | 1721 | |
1722 | 1722 | u_char *p; |
1723 | 1723 | size_t size; |
1724 | ngx_keyval_t *s; | |
1725 | 1724 | ngx_hash_init_t hash; |
1726 | 1725 | ngx_http_core_loc_conf_t *clcf; |
1727 | 1726 | ngx_http_proxy_redirect_t *pr; |
2066 | 2065 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
2067 | 2066 | return NGX_CONF_ERROR; |
2068 | 2067 | } |
2069 | ||
2070 | if (conf->headers_source == NULL) { | |
2071 | conf->headers_source = ngx_array_create(cf->pool, 4, | |
2072 | sizeof(ngx_keyval_t)); | |
2073 | if (conf->headers_source == NULL) { | |
2074 | return NGX_CONF_ERROR; | |
2075 | } | |
2076 | } | |
2077 | ||
2078 | s = ngx_array_push(conf->headers_source); | |
2079 | if (s == NULL) { | |
2080 | return NGX_CONF_ERROR; | |
2081 | } | |
2082 | ||
2083 | ngx_str_set(&s->key, "Content-Length"); | |
2084 | ngx_str_set(&s->value, "$proxy_internal_body_length"); | |
2085 | 2068 | } |
2086 | 2069 | |
2087 | 2070 | if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) { |
2100 | 2083 | size_t size; |
2101 | 2084 | uintptr_t *code; |
2102 | 2085 | ngx_uint_t i; |
2103 | ngx_array_t headers_names; | |
2086 | ngx_array_t headers_names, headers_merged; | |
2104 | 2087 | ngx_keyval_t *src, *s, *h; |
2105 | 2088 | ngx_hash_key_t *hk; |
2106 | 2089 | ngx_hash_init_t hash; |
2116 | 2099 | } |
2117 | 2100 | |
2118 | 2101 | if (conf->headers_set_hash.buckets |
2102 | && ((conf->body_source.data == NULL) | |
2103 | == (prev->body_source.data == NULL)) | |
2119 | 2104 | #if (NGX_HTTP_CACHE) |
2120 | 2105 | && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) |
2121 | 2106 | #endif |
2131 | 2116 | return NGX_ERROR; |
2132 | 2117 | } |
2133 | 2118 | |
2119 | if (ngx_array_init(&headers_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) | |
2120 | != NGX_OK) | |
2121 | { | |
2122 | return NGX_ERROR; | |
2123 | } | |
2124 | ||
2134 | 2125 | if (conf->headers_source == NULL) { |
2135 | 2126 | conf->headers_source = ngx_array_create(cf->pool, 4, |
2136 | 2127 | sizeof(ngx_keyval_t)); |
2150 | 2141 | } |
2151 | 2142 | |
2152 | 2143 | |
2153 | src = conf->headers_source->elts; | |
2154 | ||
2155 | 2144 | #if (NGX_HTTP_CACHE) |
2156 | 2145 | |
2157 | 2146 | h = conf->upstream.cache ? ngx_http_proxy_cache_headers: |
2162 | 2151 | |
2163 | 2152 | #endif |
2164 | 2153 | |
2154 | src = conf->headers_source->elts; | |
2155 | for (i = 0; i < conf->headers_source->nelts; i++) { | |
2156 | ||
2157 | s = ngx_array_push(&headers_merged); | |
2158 | if (s == NULL) { | |
2159 | return NGX_ERROR; | |
2160 | } | |
2161 | ||
2162 | *s = src[i]; | |
2163 | } | |
2164 | ||
2165 | 2165 | while (h->key.len) { |
2166 | 2166 | |
2167 | for (i = 0; i < conf->headers_source->nelts; i++) { | |
2167 | src = headers_merged.elts; | |
2168 | for (i = 0; i < headers_merged.nelts; i++) { | |
2168 | 2169 | if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
2169 | 2170 | goto next; |
2170 | 2171 | } |
2171 | 2172 | } |
2172 | 2173 | |
2173 | s = ngx_array_push(conf->headers_source); | |
2174 | s = ngx_array_push(&headers_merged); | |
2174 | 2175 | if (s == NULL) { |
2175 | 2176 | return NGX_ERROR; |
2176 | 2177 | } |
2177 | 2178 | |
2178 | 2179 | *s = *h; |
2179 | 2180 | |
2180 | src = conf->headers_source->elts; | |
2181 | ||
2182 | 2181 | next: |
2183 | 2182 | |
2184 | 2183 | h++; |
2185 | 2184 | } |
2186 | 2185 | |
2187 | ||
2188 | src = conf->headers_source->elts; | |
2189 | for (i = 0; i < conf->headers_source->nelts; i++) { | |
2186 | if (conf->body_source.data) { | |
2187 | s = ngx_array_push(&headers_merged); | |
2188 | if (s == NULL) { | |
2189 | return NGX_ERROR; | |
2190 | } | |
2191 | ||
2192 | ngx_str_set(&s->key, "Content-Length"); | |
2193 | ngx_str_set(&s->value, "$proxy_internal_body_length"); | |
2194 | } | |
2195 | ||
2196 | ||
2197 | src = headers_merged.elts; | |
2198 | for (i = 0; i < headers_merged.nelts; i++) { | |
2190 | 2199 | |
2191 | 2200 | hk = ngx_array_push(&headers_names); |
2192 | 2201 | if (hk == NULL) { |
42 | 42 | static void *ngx_http_scgi_create_loc_conf(ngx_conf_t *cf); |
43 | 43 | static char *ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, |
44 | 44 | void *child); |
45 | static ngx_int_t ngx_http_scgi_merge_params(ngx_conf_t *cf, | |
46 | ngx_http_scgi_loc_conf_t *conf, ngx_http_scgi_loc_conf_t *prev); | |
45 | 47 | |
46 | 48 | static char *ngx_http_scgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
47 | 49 | static char *ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd, |
1058 | 1060 | ngx_http_scgi_loc_conf_t *prev = parent; |
1059 | 1061 | ngx_http_scgi_loc_conf_t *conf = child; |
1060 | 1062 | |
1061 | u_char *p; | |
1062 | 1063 | size_t size; |
1063 | uintptr_t *code; | |
1064 | ngx_uint_t i; | |
1065 | ngx_array_t headers_names; | |
1066 | ngx_keyval_t *src; | |
1067 | ngx_hash_key_t *hk; | |
1068 | 1064 | ngx_hash_init_t hash; |
1069 | 1065 | ngx_http_core_loc_conf_t *clcf; |
1070 | ngx_http_script_compile_t sc; | |
1071 | ngx_http_script_copy_code_t *copy; | |
1072 | 1066 | |
1073 | 1067 | if (conf->upstream.store != 0) { |
1074 | 1068 | ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0); |
1306 | 1300 | } |
1307 | 1301 | } |
1308 | 1302 | |
1303 | if (ngx_http_scgi_merge_params(cf, conf, prev) != NGX_OK) { | |
1304 | return NGX_CONF_ERROR; | |
1305 | } | |
1306 | ||
1307 | return NGX_CONF_OK; | |
1308 | } | |
1309 | ||
1310 | ||
1311 | static ngx_int_t | |
1312 | ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf, | |
1313 | ngx_http_scgi_loc_conf_t *prev) | |
1314 | { | |
1315 | u_char *p; | |
1316 | size_t size; | |
1317 | uintptr_t *code; | |
1318 | ngx_uint_t i, nsrc; | |
1319 | ngx_array_t headers_names; | |
1320 | #if (NGX_HTTP_CACHE) | |
1321 | ngx_array_t params_merged; | |
1322 | #endif | |
1323 | ngx_keyval_t *src; | |
1324 | ngx_hash_key_t *hk; | |
1325 | ngx_hash_init_t hash; | |
1326 | ngx_http_script_compile_t sc; | |
1327 | ngx_http_script_copy_code_t *copy; | |
1328 | ||
1309 | 1329 | if (conf->params_source == NULL) { |
1310 | conf->flushes = prev->flushes; | |
1311 | conf->params_len = prev->params_len; | |
1312 | conf->params = prev->params; | |
1313 | 1330 | conf->params_source = prev->params_source; |
1314 | conf->headers_hash = prev->headers_hash; | |
1315 | ||
1331 | ||
1332 | if (prev->headers_hash.buckets | |
1316 | 1333 | #if (NGX_HTTP_CACHE) |
1317 | ||
1318 | if (conf->params_source == NULL) { | |
1319 | ||
1320 | if ((conf->upstream.cache == NULL) | |
1321 | == (prev->upstream.cache == NULL)) | |
1322 | { | |
1323 | return NGX_CONF_OK; | |
1324 | } | |
1325 | ||
1326 | /* 6 is a number of ngx_http_scgi_cache_headers entries */ | |
1327 | conf->params_source = ngx_array_create(cf->pool, 6, | |
1328 | sizeof(ngx_keyval_t)); | |
1329 | if (conf->params_source == NULL) { | |
1330 | return NGX_CONF_ERROR; | |
1331 | } | |
1332 | } | |
1333 | #else | |
1334 | ||
1335 | if (conf->params_source == NULL) { | |
1336 | return NGX_CONF_OK; | |
1337 | } | |
1338 | ||
1334 | && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) | |
1339 | 1335 | #endif |
1336 | ) | |
1337 | { | |
1338 | conf->flushes = prev->flushes; | |
1339 | conf->params_len = prev->params_len; | |
1340 | conf->params = prev->params; | |
1341 | conf->headers_hash = prev->headers_hash; | |
1342 | conf->header_params = prev->header_params; | |
1343 | ||
1344 | return NGX_OK; | |
1345 | } | |
1346 | } | |
1347 | ||
1348 | if (conf->params_source == NULL | |
1349 | #if (NGX_HTTP_CACHE) | |
1350 | && (conf->upstream.cache == NULL) | |
1351 | #endif | |
1352 | ) | |
1353 | { | |
1354 | conf->headers_hash.buckets = (void *) 1; | |
1355 | return NGX_OK; | |
1340 | 1356 | } |
1341 | 1357 | |
1342 | 1358 | conf->params_len = ngx_array_create(cf->pool, 64, 1); |
1343 | 1359 | if (conf->params_len == NULL) { |
1344 | return NGX_CONF_ERROR; | |
1360 | return NGX_ERROR; | |
1345 | 1361 | } |
1346 | 1362 | |
1347 | 1363 | conf->params = ngx_array_create(cf->pool, 512, 1); |
1348 | 1364 | if (conf->params == NULL) { |
1349 | return NGX_CONF_ERROR; | |
1365 | return NGX_ERROR; | |
1350 | 1366 | } |
1351 | 1367 | |
1352 | 1368 | if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) |
1353 | 1369 | != NGX_OK) |
1354 | 1370 | { |
1355 | return NGX_CONF_ERROR; | |
1356 | } | |
1357 | ||
1358 | src = conf->params_source->elts; | |
1371 | return NGX_ERROR; | |
1372 | } | |
1373 | ||
1374 | if (conf->params_source) { | |
1375 | src = conf->params_source->elts; | |
1376 | nsrc = conf->params_source->nelts; | |
1377 | ||
1378 | } else { | |
1379 | src = NULL; | |
1380 | nsrc = 0; | |
1381 | } | |
1359 | 1382 | |
1360 | 1383 | #if (NGX_HTTP_CACHE) |
1361 | 1384 | |
1362 | 1385 | if (conf->upstream.cache) { |
1363 | 1386 | ngx_keyval_t *h, *s; |
1364 | 1387 | |
1365 | for (h = ngx_http_scgi_cache_headers; h->key.len; h++) { | |
1366 | ||
1367 | for (i = 0; i < conf->params_source->nelts; i++) { | |
1388 | if (ngx_array_init(¶ms_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) | |
1389 | != NGX_OK) | |
1390 | { | |
1391 | return NGX_ERROR; | |
1392 | } | |
1393 | ||
1394 | for (i = 0; i < nsrc; i++) { | |
1395 | ||
1396 | s = ngx_array_push(¶ms_merged); | |
1397 | if (s == NULL) { | |
1398 | return NGX_ERROR; | |
1399 | } | |
1400 | ||
1401 | *s = src[i]; | |
1402 | } | |
1403 | ||
1404 | h = ngx_http_scgi_cache_headers; | |
1405 | ||
1406 | while (h->key.len) { | |
1407 | ||
1408 | src = params_merged.elts; | |
1409 | nsrc = params_merged.nelts; | |
1410 | ||
1411 | for (i = 0; i < nsrc; i++) { | |
1368 | 1412 | if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
1369 | 1413 | goto next; |
1370 | 1414 | } |
1371 | 1415 | } |
1372 | 1416 | |
1373 | s = ngx_array_push(conf->params_source); | |
1417 | s = ngx_array_push(¶ms_merged); | |
1374 | 1418 | if (s == NULL) { |
1375 | return NGX_CONF_ERROR; | |
1419 | return NGX_ERROR; | |
1376 | 1420 | } |
1377 | 1421 | |
1378 | 1422 | *s = *h; |
1379 | 1423 | |
1380 | src = conf->params_source->elts; | |
1381 | ||
1382 | 1424 | next: |
1383 | 1425 | |
1384 | 1426 | h++; |
1385 | 1427 | } |
1428 | ||
1429 | src = params_merged.elts; | |
1430 | nsrc = params_merged.nelts; | |
1386 | 1431 | } |
1387 | 1432 | |
1388 | 1433 | #endif |
1389 | 1434 | |
1390 | for (i = 0; i < conf->params_source->nelts; i++) { | |
1435 | for (i = 0; i < nsrc; i++) { | |
1391 | 1436 | |
1392 | 1437 | if (src[i].key.len > sizeof("HTTP_") - 1 |
1393 | 1438 | && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) |
1394 | 1439 | { |
1395 | 1440 | hk = ngx_array_push(&headers_names); |
1396 | 1441 | if (hk == NULL) { |
1397 | return NGX_CONF_ERROR; | |
1442 | return NGX_ERROR; | |
1398 | 1443 | } |
1399 | 1444 | |
1400 | 1445 | hk->key.len = src[i].key.len - 5; |
1410 | 1455 | copy = ngx_array_push_n(conf->params_len, |
1411 | 1456 | sizeof(ngx_http_script_copy_code_t)); |
1412 | 1457 | if (copy == NULL) { |
1413 | return NGX_CONF_ERROR; | |
1458 | return NGX_ERROR; | |
1414 | 1459 | } |
1415 | 1460 | |
1416 | 1461 | copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; |
1423 | 1468 | |
1424 | 1469 | copy = ngx_array_push_n(conf->params, size); |
1425 | 1470 | if (copy == NULL) { |
1426 | return NGX_CONF_ERROR; | |
1471 | return NGX_ERROR; | |
1427 | 1472 | } |
1428 | 1473 | |
1429 | 1474 | copy->code = ngx_http_script_copy_code; |
1442 | 1487 | sc.values = &conf->params; |
1443 | 1488 | |
1444 | 1489 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
1445 | return NGX_CONF_ERROR; | |
1490 | return NGX_ERROR; | |
1446 | 1491 | } |
1447 | 1492 | |
1448 | 1493 | code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
1449 | 1494 | if (code == NULL) { |
1450 | return NGX_CONF_ERROR; | |
1495 | return NGX_ERROR; | |
1451 | 1496 | } |
1452 | 1497 | |
1453 | 1498 | *code = (uintptr_t) NULL; |
1455 | 1500 | |
1456 | 1501 | code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); |
1457 | 1502 | if (code == NULL) { |
1458 | return NGX_CONF_ERROR; | |
1503 | return NGX_ERROR; | |
1459 | 1504 | } |
1460 | 1505 | |
1461 | 1506 | *code = (uintptr_t) NULL; |
1463 | 1508 | |
1464 | 1509 | code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
1465 | 1510 | if (code == NULL) { |
1466 | return NGX_CONF_ERROR; | |
1511 | return NGX_ERROR; | |
1467 | 1512 | } |
1468 | 1513 | |
1469 | 1514 | *code = (uintptr_t) NULL; |
1470 | 1515 | |
1471 | 1516 | code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); |
1472 | 1517 | if (code == NULL) { |
1473 | return NGX_CONF_ERROR; | |
1518 | return NGX_ERROR; | |
1474 | 1519 | } |
1475 | 1520 | |
1476 | 1521 | *code = (uintptr_t) NULL; |
1485 | 1530 | hash.pool = cf->pool; |
1486 | 1531 | hash.temp_pool = NULL; |
1487 | 1532 | |
1488 | if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK) | |
1489 | { | |
1490 | return NGX_CONF_ERROR; | |
1491 | } | |
1492 | ||
1493 | return NGX_CONF_OK; | |
1533 | return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); | |
1494 | 1534 | } |
1495 | 1535 | |
1496 | 1536 |
49 | 49 | static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf); |
50 | 50 | static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, |
51 | 51 | void *child); |
52 | static ngx_int_t ngx_http_uwsgi_merge_params(ngx_conf_t *cf, | |
53 | ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev); | |
52 | 54 | |
53 | 55 | static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, |
54 | 56 | void *conf); |
1111 | 1113 | ngx_http_uwsgi_loc_conf_t *prev = parent; |
1112 | 1114 | ngx_http_uwsgi_loc_conf_t *conf = child; |
1113 | 1115 | |
1114 | u_char *p; | |
1115 | 1116 | size_t size; |
1116 | uintptr_t *code; | |
1117 | ngx_uint_t i; | |
1118 | ngx_array_t headers_names; | |
1119 | ngx_keyval_t *src; | |
1120 | ngx_hash_key_t *hk; | |
1121 | 1117 | ngx_hash_init_t hash; |
1122 | 1118 | ngx_http_core_loc_conf_t *clcf; |
1123 | ngx_http_script_compile_t sc; | |
1124 | ngx_http_script_copy_code_t *copy; | |
1125 | 1119 | |
1126 | 1120 | if (conf->upstream.store != 0) { |
1127 | 1121 | ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0); |
1364 | 1358 | ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0); |
1365 | 1359 | ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0); |
1366 | 1360 | |
1361 | if (ngx_http_uwsgi_merge_params(cf, conf, prev) != NGX_OK) { | |
1362 | return NGX_CONF_ERROR; | |
1363 | } | |
1364 | ||
1365 | return NGX_CONF_OK; | |
1366 | } | |
1367 | ||
1368 | ||
1369 | static ngx_int_t | |
1370 | ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf, | |
1371 | ngx_http_uwsgi_loc_conf_t *prev) | |
1372 | { | |
1373 | u_char *p; | |
1374 | size_t size; | |
1375 | uintptr_t *code; | |
1376 | ngx_uint_t i, nsrc; | |
1377 | ngx_array_t headers_names; | |
1378 | #if (NGX_HTTP_CACHE) | |
1379 | ngx_array_t params_merged; | |
1380 | #endif | |
1381 | ngx_keyval_t *src; | |
1382 | ngx_hash_key_t *hk; | |
1383 | ngx_hash_init_t hash; | |
1384 | ngx_http_script_compile_t sc; | |
1385 | ngx_http_script_copy_code_t *copy; | |
1386 | ||
1367 | 1387 | if (conf->params_source == NULL) { |
1368 | conf->flushes = prev->flushes; | |
1369 | conf->params_len = prev->params_len; | |
1370 | conf->params = prev->params; | |
1371 | 1388 | conf->params_source = prev->params_source; |
1372 | conf->headers_hash = prev->headers_hash; | |
1373 | ||
1389 | ||
1390 | if (prev->headers_hash.buckets | |
1374 | 1391 | #if (NGX_HTTP_CACHE) |
1375 | ||
1376 | if (conf->params_source == NULL) { | |
1377 | ||
1378 | if ((conf->upstream.cache == NULL) | |
1379 | == (prev->upstream.cache == NULL)) | |
1380 | { | |
1381 | return NGX_CONF_OK; | |
1382 | } | |
1383 | ||
1384 | /* 6 is a number of ngx_http_uwsgi_cache_headers entries */ | |
1385 | conf->params_source = ngx_array_create(cf->pool, 6, | |
1386 | sizeof(ngx_keyval_t)); | |
1387 | if (conf->params_source == NULL) { | |
1388 | return NGX_CONF_ERROR; | |
1389 | } | |
1390 | } | |
1391 | #else | |
1392 | ||
1393 | if (conf->params_source == NULL) { | |
1394 | return NGX_CONF_OK; | |
1395 | } | |
1396 | ||
1392 | && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) | |
1397 | 1393 | #endif |
1394 | ) | |
1395 | { | |
1396 | conf->flushes = prev->flushes; | |
1397 | conf->params_len = prev->params_len; | |
1398 | conf->params = prev->params; | |
1399 | conf->headers_hash = prev->headers_hash; | |
1400 | conf->header_params = prev->header_params; | |
1401 | ||
1402 | return NGX_OK; | |
1403 | } | |
1404 | } | |
1405 | ||
1406 | if (conf->params_source == NULL | |
1407 | #if (NGX_HTTP_CACHE) | |
1408 | && (conf->upstream.cache == NULL) | |
1409 | #endif | |
1410 | ) | |
1411 | { | |
1412 | conf->headers_hash.buckets = (void *) 1; | |
1413 | return NGX_OK; | |
1398 | 1414 | } |
1399 | 1415 | |
1400 | 1416 | conf->params_len = ngx_array_create(cf->pool, 64, 1); |
1401 | 1417 | if (conf->params_len == NULL) { |
1402 | return NGX_CONF_ERROR; | |
1418 | return NGX_ERROR; | |
1403 | 1419 | } |
1404 | 1420 | |
1405 | 1421 | conf->params = ngx_array_create(cf->pool, 512, 1); |
1406 | 1422 | if (conf->params == NULL) { |
1407 | return NGX_CONF_ERROR; | |
1423 | return NGX_ERROR; | |
1408 | 1424 | } |
1409 | 1425 | |
1410 | 1426 | if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) |
1411 | 1427 | != NGX_OK) |
1412 | 1428 | { |
1413 | return NGX_CONF_ERROR; | |
1414 | } | |
1415 | ||
1416 | src = conf->params_source->elts; | |
1429 | return NGX_ERROR; | |
1430 | } | |
1431 | ||
1432 | if (conf->params_source) { | |
1433 | src = conf->params_source->elts; | |
1434 | nsrc = conf->params_source->nelts; | |
1435 | ||
1436 | } else { | |
1437 | src = NULL; | |
1438 | nsrc = 0; | |
1439 | } | |
1417 | 1440 | |
1418 | 1441 | #if (NGX_HTTP_CACHE) |
1419 | 1442 | |
1420 | 1443 | if (conf->upstream.cache) { |
1421 | 1444 | ngx_keyval_t *h, *s; |
1422 | 1445 | |
1423 | for (h = ngx_http_uwsgi_cache_headers; h->key.len; h++) { | |
1424 | ||
1425 | for (i = 0; i < conf->params_source->nelts; i++) { | |
1446 | if (ngx_array_init(¶ms_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) | |
1447 | != NGX_OK) | |
1448 | { | |
1449 | return NGX_ERROR; | |
1450 | } | |
1451 | ||
1452 | for (i = 0; i < nsrc; i++) { | |
1453 | ||
1454 | s = ngx_array_push(¶ms_merged); | |
1455 | if (s == NULL) { | |
1456 | return NGX_ERROR; | |
1457 | } | |
1458 | ||
1459 | *s = src[i]; | |
1460 | } | |
1461 | ||
1462 | h = ngx_http_uwsgi_cache_headers; | |
1463 | ||
1464 | while (h->key.len) { | |
1465 | ||
1466 | src = params_merged.elts; | |
1467 | nsrc = params_merged.nelts; | |
1468 | ||
1469 | for (i = 0; i < nsrc; i++) { | |
1426 | 1470 | if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
1427 | 1471 | goto next; |
1428 | 1472 | } |
1429 | 1473 | } |
1430 | 1474 | |
1431 | s = ngx_array_push(conf->params_source); | |
1475 | s = ngx_array_push(¶ms_merged); | |
1432 | 1476 | if (s == NULL) { |
1433 | return NGX_CONF_ERROR; | |
1477 | return NGX_ERROR; | |
1434 | 1478 | } |
1435 | 1479 | |
1436 | 1480 | *s = *h; |
1437 | 1481 | |
1438 | src = conf->params_source->elts; | |
1439 | ||
1440 | 1482 | next: |
1441 | 1483 | |
1442 | 1484 | h++; |
1443 | 1485 | } |
1486 | ||
1487 | src = params_merged.elts; | |
1488 | nsrc = params_merged.nelts; | |
1444 | 1489 | } |
1445 | 1490 | |
1446 | 1491 | #endif |
1447 | 1492 | |
1448 | for (i = 0; i < conf->params_source->nelts; i++) { | |
1493 | for (i = 0; i < nsrc; i++) { | |
1449 | 1494 | |
1450 | 1495 | if (src[i].key.len > sizeof("HTTP_") - 1 |
1451 | 1496 | && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) |
1452 | 1497 | { |
1453 | 1498 | hk = ngx_array_push(&headers_names); |
1454 | 1499 | if (hk == NULL) { |
1455 | return NGX_CONF_ERROR; | |
1500 | return NGX_ERROR; | |
1456 | 1501 | } |
1457 | 1502 | |
1458 | 1503 | hk->key.len = src[i].key.len - 5; |
1468 | 1513 | copy = ngx_array_push_n(conf->params_len, |
1469 | 1514 | sizeof(ngx_http_script_copy_code_t)); |
1470 | 1515 | if (copy == NULL) { |
1471 | return NGX_CONF_ERROR; | |
1516 | return NGX_ERROR; | |
1472 | 1517 | } |
1473 | 1518 | |
1474 | 1519 | copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; |
1481 | 1526 | |
1482 | 1527 | copy = ngx_array_push_n(conf->params, size); |
1483 | 1528 | if (copy == NULL) { |
1484 | return NGX_CONF_ERROR; | |
1529 | return NGX_ERROR; | |
1485 | 1530 | } |
1486 | 1531 | |
1487 | 1532 | copy->code = ngx_http_script_copy_code; |
1500 | 1545 | sc.values = &conf->params; |
1501 | 1546 | |
1502 | 1547 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
1503 | return NGX_CONF_ERROR; | |
1548 | return NGX_ERROR; | |
1504 | 1549 | } |
1505 | 1550 | |
1506 | 1551 | code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
1507 | 1552 | if (code == NULL) { |
1508 | return NGX_CONF_ERROR; | |
1553 | return NGX_ERROR; | |
1509 | 1554 | } |
1510 | 1555 | |
1511 | 1556 | *code = (uintptr_t) NULL; |
1513 | 1558 | |
1514 | 1559 | code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); |
1515 | 1560 | if (code == NULL) { |
1516 | return NGX_CONF_ERROR; | |
1561 | return NGX_ERROR; | |
1517 | 1562 | } |
1518 | 1563 | |
1519 | 1564 | *code = (uintptr_t) NULL; |
1521 | 1566 | |
1522 | 1567 | code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
1523 | 1568 | if (code == NULL) { |
1524 | return NGX_CONF_ERROR; | |
1569 | return NGX_ERROR; | |
1525 | 1570 | } |
1526 | 1571 | |
1527 | 1572 | *code = (uintptr_t) NULL; |
1536 | 1581 | hash.pool = cf->pool; |
1537 | 1582 | hash.temp_pool = NULL; |
1538 | 1583 | |
1539 | if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK) | |
1540 | { | |
1541 | return NGX_CONF_ERROR; | |
1542 | } | |
1543 | ||
1544 | return NGX_CONF_OK; | |
1584 | return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); | |
1545 | 1585 | } |
1546 | 1586 | |
1547 | 1587 |