Upstream: added the "$upstream_cookie_<name>" variables.

This commit is contained in:
Vladimir Homutov 2014-04-29 12:28:41 +04:00
parent b53306815e
commit ed6780aaf1
5 changed files with 130 additions and 3 deletions

View File

@ -105,6 +105,8 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
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,

View File

@ -1984,6 +1984,57 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
}
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)
{

View File

@ -216,7 +216,8 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
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 @@ static ngx_int_t
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_http_upstream_header_variable(ngx_http_request_t *r,
}
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

View File

@ -248,6 +248,7 @@ typedef struct {
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 @@ typedef struct {
} 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);

View File

@ -613,6 +613,17 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
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 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
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;