Mercurial > hg > nginx
changeset 5677:3a48775f1535
Upstream: added the "$upstream_cookie_<name>" variables.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Tue, 29 Apr 2014 12:28:41 +0400 |
parents | fbfdf8017748 |
children | 0e1491139947 |
files | src/http/ngx_http.h src/http/ngx_http_parse.c src/http/ngx_http_upstream.c src/http/ngx_http_upstream.h src/http/ngx_http_variables.c |
diffstat | 5 files changed, 131 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/ngx_http.h Mon Nov 18 03:06:45 2013 +0400 +++ b/src/http/ngx_http.h Tue Apr 29 12:28:41 2014 +0400 @@ -105,6 +105,8 @@ ngx_uint_t allow_underscores); ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, ngx_str_t *value); +ngx_int_t ngx_http_parse_set_cookie_lines(ngx_array_t *headers, + ngx_str_t *name, ngx_str_t *value); ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value); void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri,
--- a/src/http/ngx_http_parse.c Mon Nov 18 03:06:45 2013 +0400 +++ b/src/http/ngx_http_parse.c Tue Apr 29 12:28:41 2014 +0400 @@ -1985,6 +1985,57 @@ ngx_int_t +ngx_http_parse_set_cookie_lines(ngx_array_t *headers, ngx_str_t *name, + ngx_str_t *value) +{ + ngx_uint_t i; + u_char *start, *last, *end; + ngx_table_elt_t **h; + + h = headers->elts; + + for (i = 0; i < headers->nelts; i++) { + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0, + "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value); + + if (name->len >= h[i]->value.len) { + continue; + } + + start = h[i]->value.data; + end = h[i]->value.data + h[i]->value.len; + + if (ngx_strncasecmp(start, name->data, name->len) != 0) { + continue; + } + + for (start += name->len; start < end && *start == ' '; start++) { + /* void */ + } + + if (start == end || *start++ != '=') { + /* the invalid header value */ + continue; + } + + while (start < end && *start == ' ') { start++; } + + for (last = start; last < end && *last != ';'; last++) { + /* void */ + } + + value->len = last - start; + value->data = start; + + return i; + } + + return NGX_DECLINED; +} + + +ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value) { u_char *p, *last;
--- a/src/http/ngx_http_upstream.c Mon Nov 18 03:06:45 2013 +0400 +++ b/src/http/ngx_http_upstream.c Tue Apr 29 12:28:41 2014 +0400 @@ -216,7 +216,8 @@ ngx_http_upstream_rewrite_refresh, 0, 0 }, { ngx_string("Set-Cookie"), - ngx_http_upstream_process_set_cookie, 0, + ngx_http_upstream_process_set_cookie, + offsetof(ngx_http_upstream_headers_in_t, cookies), ngx_http_upstream_rewrite_set_cookie, 0, 1 }, { ngx_string("Content-Disposition"), @@ -3731,11 +3732,28 @@ ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { -#if (NGX_HTTP_CACHE) - ngx_http_upstream_t *u; + ngx_array_t *pa; + ngx_table_elt_t **ph; + ngx_http_upstream_t *u; u = r->upstream; - + pa = &u->headers_in.cookies; + + if (pa->elts == NULL) { + if (ngx_array_init(pa, r->pool, 1, sizeof(ngx_table_elt_t *)) != NGX_OK) + { + return NGX_ERROR; + } + } + + ph = ngx_array_push(pa); + if (ph == NULL) { + return NGX_ERROR; + } + + *ph = h; + +#if (NGX_HTTP_CACHE) if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) { u->cacheable = 0; } @@ -4657,6 +4675,40 @@ } +ngx_int_t +ngx_http_upstream_cookie_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_str_t *name = (ngx_str_t *) data; + + ngx_str_t cookie, s; + + if (r->upstream == NULL) { + v->not_found = 1; + return NGX_OK; + } + + s.len = name->len - (sizeof("upstream_cookie_") - 1); + s.data = name->data + sizeof("upstream_cookie_") - 1; + + if (ngx_http_parse_set_cookie_lines(&r->upstream->headers_in.cookies, + &s, &cookie) + == NGX_DECLINED) + { + v->not_found = 1; + return NGX_OK; + } + + v->len = cookie.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = cookie.data; + + return NGX_OK; +} + + #if (NGX_HTTP_CACHE) ngx_int_t
--- a/src/http/ngx_http_upstream.h Mon Nov 18 03:06:45 2013 +0400 +++ b/src/http/ngx_http_upstream.h Tue Apr 29 12:28:41 2014 +0400 @@ -248,6 +248,7 @@ off_t content_length_n; ngx_array_t cache_control; + ngx_array_t cookies; unsigned connection_close:1; unsigned chunked:1; @@ -363,6 +364,8 @@ } ngx_http_upstream_param_t; +ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
--- a/src/http/ngx_http_variables.c Mon Nov 18 03:06:45 2013 +0400 +++ b/src/http/ngx_http_variables.c Tue Apr 29 12:28:41 2014 +0400 @@ -613,6 +613,17 @@ return NULL; } + if (ngx_strncmp(name->data, "upstream_cookie_", 16) == 0) { + + if (ngx_http_upstream_cookie_variable(r, vv, (uintptr_t) name) + == NGX_OK) + { + return vv; + } + + return NULL; + } + if (ngx_strncmp(name->data, "arg_", 4) == 0) { if (ngx_http_variable_argument(r, vv, (uintptr_t) name) == NGX_OK) { @@ -2528,6 +2539,14 @@ continue; } + if (ngx_strncmp(v[i].name.data, "upstream_cookie_", 16) == 0) { + v[i].get_handler = ngx_http_upstream_cookie_variable; + v[i].data = (uintptr_t) &v[i].name; + v[i].flags = NGX_HTTP_VAR_NOCACHEABLE; + + continue; + } + if (ngx_strncmp(v[i].name.data, "arg_", 4) == 0) { v[i].get_handler = ngx_http_variable_argument; v[i].data = (uintptr_t) &v[i].name;