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)