Mercurial > hg > nginx
comparison src/http/modules/ngx_http_proxy_module.c @ 4465:8293fc2d802b
Proxy: added the "proxy_cookie_domain" directive.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Mon, 13 Feb 2012 11:04:45 +0000 |
parents | a068ec122f17 |
children | b404f34b5cb8 |
comparison
equal
deleted
inserted
replaced
4464:7bf3b68239a3 | 4465:8293fc2d802b |
---|---|
53 | 53 |
54 ngx_array_t *proxy_lengths; | 54 ngx_array_t *proxy_lengths; |
55 ngx_array_t *proxy_values; | 55 ngx_array_t *proxy_values; |
56 | 56 |
57 ngx_array_t *redirects; | 57 ngx_array_t *redirects; |
58 ngx_array_t *cookie_domains; | |
58 | 59 |
59 ngx_str_t body_source; | 60 ngx_str_t body_source; |
60 | 61 |
61 ngx_str_t method; | 62 ngx_str_t method; |
62 ngx_str_t location; | 63 ngx_str_t location; |
122 static ngx_int_t | 123 static ngx_int_t |
123 ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, | 124 ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, |
124 ngx_http_variable_value_t *v, uintptr_t data); | 125 ngx_http_variable_value_t *v, uintptr_t data); |
125 static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, | 126 static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, |
126 ngx_table_elt_t *h, size_t prefix); | 127 ngx_table_elt_t *h, size_t prefix); |
128 static ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, | |
129 ngx_table_elt_t *h); | |
130 static ngx_int_t ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, | |
131 ngx_table_elt_t *h, u_char *value, ngx_array_t *rewrites); | |
127 static ngx_int_t ngx_http_proxy_rewrite(ngx_http_request_t *r, | 132 static ngx_int_t ngx_http_proxy_rewrite(ngx_http_request_t *r, |
128 ngx_table_elt_t *h, size_t prefix, size_t len, ngx_str_t *replacement); | 133 ngx_table_elt_t *h, size_t prefix, size_t len, ngx_str_t *replacement); |
129 | 134 |
130 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); | 135 static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); |
131 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); | 136 static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); |
135 ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_loc_conf_t *prev); | 140 ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_loc_conf_t *prev); |
136 | 141 |
137 static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, | 142 static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, |
138 void *conf); | 143 void *conf); |
139 static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, | 144 static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, |
145 void *conf); | |
146 static char *ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd, | |
140 void *conf); | 147 void *conf); |
141 static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, | 148 static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, |
142 void *conf); | 149 void *conf); |
143 #if (NGX_HTTP_CACHE) | 150 #if (NGX_HTTP_CACHE) |
144 static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, | 151 static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, |
198 NULL }, | 205 NULL }, |
199 | 206 |
200 { ngx_string("proxy_redirect"), | 207 { ngx_string("proxy_redirect"), |
201 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, | 208 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, |
202 ngx_http_proxy_redirect, | 209 ngx_http_proxy_redirect, |
210 NGX_HTTP_LOC_CONF_OFFSET, | |
211 0, | |
212 NULL }, | |
213 | |
214 { ngx_string("proxy_cookie_domain"), | |
215 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, | |
216 ngx_http_proxy_cookie_domain, | |
203 NGX_HTTP_LOC_CONF_OFFSET, | 217 NGX_HTTP_LOC_CONF_OFFSET, |
204 0, | 218 0, |
205 NULL }, | 219 NULL }, |
206 | 220 |
207 { ngx_string("proxy_store"), | 221 { ngx_string("proxy_store"), |
651 u->finalize_request = ngx_http_proxy_finalize_request; | 665 u->finalize_request = ngx_http_proxy_finalize_request; |
652 r->state = 0; | 666 r->state = 0; |
653 | 667 |
654 if (plcf->redirects) { | 668 if (plcf->redirects) { |
655 u->rewrite_redirect = ngx_http_proxy_rewrite_redirect; | 669 u->rewrite_redirect = ngx_http_proxy_rewrite_redirect; |
670 } | |
671 | |
672 if (plcf->cookie_domains) { | |
673 u->rewrite_cookie = ngx_http_proxy_rewrite_cookie; | |
656 } | 674 } |
657 | 675 |
658 u->buffering = plcf->upstream.buffering; | 676 u->buffering = plcf->upstream.buffering; |
659 | 677 |
660 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); | 678 u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); |
2305 return NGX_DECLINED; | 2323 return NGX_DECLINED; |
2306 } | 2324 } |
2307 | 2325 |
2308 | 2326 |
2309 static ngx_int_t | 2327 static ngx_int_t |
2328 ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h) | |
2329 { | |
2330 size_t prefix; | |
2331 u_char *p; | |
2332 ngx_int_t rc; | |
2333 ngx_http_proxy_loc_conf_t *plcf; | |
2334 | |
2335 p = (u_char *) ngx_strchr(h->value.data, ';'); | |
2336 if (p == NULL) { | |
2337 return NGX_DECLINED; | |
2338 } | |
2339 | |
2340 prefix = p + 1 - h->value.data; | |
2341 | |
2342 rc = NGX_DECLINED; | |
2343 | |
2344 plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); | |
2345 | |
2346 if (plcf->cookie_domains) { | |
2347 p = ngx_strcasestrn(h->value.data + prefix, "domain=", 7 - 1); | |
2348 | |
2349 if (p) { | |
2350 rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 7, | |
2351 plcf->cookie_domains); | |
2352 } | |
2353 } | |
2354 | |
2355 return rc; | |
2356 } | |
2357 | |
2358 | |
2359 static ngx_int_t | |
2360 ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, ngx_table_elt_t *h, | |
2361 u_char *value, ngx_array_t *rewrites) | |
2362 { | |
2363 size_t len, prefix; | |
2364 u_char *p; | |
2365 ngx_int_t rc; | |
2366 ngx_uint_t i; | |
2367 ngx_http_proxy_rewrite_t *pr; | |
2368 | |
2369 prefix = value - h->value.data; | |
2370 | |
2371 p = (u_char *) ngx_strchr(value, ';'); | |
2372 | |
2373 len = p ? (size_t) (p - value) : (h->value.len - prefix); | |
2374 | |
2375 pr = rewrites->elts; | |
2376 | |
2377 for (i = 0; i < rewrites->nelts; i++) { | |
2378 rc = pr[i].handler(r, h, prefix, len, &pr[i]); | |
2379 | |
2380 if (rc != NGX_DECLINED) { | |
2381 return rc; | |
2382 } | |
2383 } | |
2384 | |
2385 return NGX_DECLINED; | |
2386 } | |
2387 | |
2388 | |
2389 static ngx_int_t | |
2310 ngx_http_proxy_rewrite_complex_handler(ngx_http_request_t *r, | 2390 ngx_http_proxy_rewrite_complex_handler(ngx_http_request_t *r, |
2311 ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) | 2391 ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) |
2312 { | 2392 { |
2313 ngx_str_t pattern, replacement; | 2393 ngx_str_t pattern, replacement; |
2314 | 2394 |
2357 | 2437 |
2358 return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement); | 2438 return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement); |
2359 } | 2439 } |
2360 | 2440 |
2361 #endif | 2441 #endif |
2442 | |
2443 | |
2444 static ngx_int_t | |
2445 ngx_http_proxy_rewrite_domain_handler(ngx_http_request_t *r, | |
2446 ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) | |
2447 { | |
2448 u_char *p; | |
2449 ngx_str_t pattern, replacement; | |
2450 | |
2451 if (ngx_http_complex_value(r, &pr->pattern.complex, &pattern) != NGX_OK) { | |
2452 return NGX_ERROR; | |
2453 } | |
2454 | |
2455 p = h->value.data + prefix; | |
2456 | |
2457 if (p[0] == '.') { | |
2458 p++; | |
2459 prefix++; | |
2460 len--; | |
2461 } | |
2462 | |
2463 if (pattern.len != len || ngx_rstrncasecmp(pattern.data, p, len) != 0) { | |
2464 return NGX_DECLINED; | |
2465 } | |
2466 | |
2467 if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { | |
2468 return NGX_ERROR; | |
2469 } | |
2470 | |
2471 return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement); | |
2472 } | |
2362 | 2473 |
2363 | 2474 |
2364 static ngx_int_t | 2475 static ngx_int_t |
2365 ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix, | 2476 ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix, |
2366 size_t len, ngx_str_t *replacement) | 2477 size_t len, ngx_str_t *replacement) |
2495 conf->upstream.cyclic_temp_file = 0; | 2606 conf->upstream.cyclic_temp_file = 0; |
2496 | 2607 |
2497 conf->redirect = NGX_CONF_UNSET; | 2608 conf->redirect = NGX_CONF_UNSET; |
2498 conf->upstream.change_buffering = 1; | 2609 conf->upstream.change_buffering = 1; |
2499 | 2610 |
2611 conf->cookie_domains = NGX_CONF_UNSET_PTR; | |
2612 | |
2500 conf->http_version = NGX_CONF_UNSET_UINT; | 2613 conf->http_version = NGX_CONF_UNSET_UINT; |
2501 | 2614 |
2502 conf->headers_hash_max_size = NGX_CONF_UNSET_UINT; | 2615 conf->headers_hash_max_size = NGX_CONF_UNSET_UINT; |
2503 conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT; | 2616 conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT; |
2504 | 2617 |
2808 | 2921 |
2809 ngx_str_set(&pr->replacement.value, "/"); | 2922 ngx_str_set(&pr->replacement.value, "/"); |
2810 } | 2923 } |
2811 } | 2924 } |
2812 } | 2925 } |
2926 | |
2927 ngx_conf_merge_ptr_value(conf->cookie_domains, prev->cookie_domains, NULL); | |
2813 | 2928 |
2814 #if (NGX_HTTP_SSL) | 2929 #if (NGX_HTTP_SSL) |
2815 if (conf->upstream.ssl == NULL) { | 2930 if (conf->upstream.ssl == NULL) { |
2816 conf->upstream.ssl = prev->upstream.ssl; | 2931 conf->upstream.ssl = prev->upstream.ssl; |
2817 } | 2932 } |
3433 | 3548 |
3434 return NGX_CONF_OK; | 3549 return NGX_CONF_OK; |
3435 } | 3550 } |
3436 | 3551 |
3437 | 3552 |
3553 static char * | |
3554 ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
3555 { | |
3556 ngx_http_proxy_loc_conf_t *plcf = conf; | |
3557 | |
3558 ngx_str_t *value; | |
3559 ngx_http_proxy_rewrite_t *pr; | |
3560 ngx_http_compile_complex_value_t ccv; | |
3561 | |
3562 if (plcf->cookie_domains == NULL) { | |
3563 return NGX_CONF_OK; | |
3564 } | |
3565 | |
3566 value = cf->args->elts; | |
3567 | |
3568 if (cf->args->nelts == 2) { | |
3569 | |
3570 if (ngx_strcmp(value[1].data, "off") == 0) { | |
3571 plcf->cookie_domains = NULL; | |
3572 return NGX_CONF_OK; | |
3573 } | |
3574 | |
3575 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
3576 "invalid parameter \"%V\"", &value[1]); | |
3577 return NGX_CONF_ERROR; | |
3578 } | |
3579 | |
3580 if (plcf->cookie_domains == NGX_CONF_UNSET_PTR) { | |
3581 plcf->cookie_domains = ngx_array_create(cf->pool, 1, | |
3582 sizeof(ngx_http_proxy_rewrite_t)); | |
3583 if (plcf->cookie_domains == NULL) { | |
3584 return NGX_CONF_ERROR; | |
3585 } | |
3586 } | |
3587 | |
3588 pr = ngx_array_push(plcf->cookie_domains); | |
3589 if (pr == NULL) { | |
3590 return NGX_CONF_ERROR; | |
3591 } | |
3592 | |
3593 if (value[1].data[0] == '~') { | |
3594 value[1].len--; | |
3595 value[1].data++; | |
3596 | |
3597 if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) != NGX_OK) { | |
3598 return NGX_CONF_ERROR; | |
3599 } | |
3600 | |
3601 } else { | |
3602 | |
3603 if (value[1].data[0] == '.') { | |
3604 value[1].len--; | |
3605 value[1].data++; | |
3606 } | |
3607 | |
3608 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
3609 | |
3610 ccv.cf = cf; | |
3611 ccv.value = &value[1]; | |
3612 ccv.complex_value = &pr->pattern.complex; | |
3613 | |
3614 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
3615 return NGX_CONF_ERROR; | |
3616 } | |
3617 | |
3618 pr->handler = ngx_http_proxy_rewrite_domain_handler; | |
3619 | |
3620 if (value[2].data[0] == '.') { | |
3621 value[2].len--; | |
3622 value[2].data++; | |
3623 } | |
3624 } | |
3625 | |
3626 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
3627 | |
3628 ccv.cf = cf; | |
3629 ccv.value = &value[2]; | |
3630 ccv.complex_value = &pr->replacement; | |
3631 | |
3632 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
3633 return NGX_CONF_ERROR; | |
3634 } | |
3635 | |
3636 return NGX_CONF_OK; | |
3637 } | |
3638 | |
3639 | |
3438 static ngx_int_t | 3640 static ngx_int_t |
3439 ngx_http_proxy_rewrite_regex(ngx_conf_t *cf, ngx_http_proxy_rewrite_t *pr, | 3641 ngx_http_proxy_rewrite_regex(ngx_conf_t *cf, ngx_http_proxy_rewrite_t *pr, |
3440 ngx_str_t *regex, ngx_uint_t caseless) | 3642 ngx_str_t *regex, ngx_uint_t caseless) |
3441 { | 3643 { |
3442 #if (NGX_PCRE) | 3644 #if (NGX_PCRE) |