Proxy: added the "proxy_cookie_flags" directive.
This commit is contained in:
parent
8b3f778cbc
commit
21b903f8e3
@ -10,6 +10,19 @@
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define NGX_HTTP_PROXY_COOKIE_SECURE 0x0001
|
||||
#define NGX_HTTP_PROXY_COOKIE_SECURE_ON 0x0002
|
||||
#define NGX_HTTP_PROXY_COOKIE_SECURE_OFF 0x0004
|
||||
#define NGX_HTTP_PROXY_COOKIE_HTTPONLY 0x0008
|
||||
#define NGX_HTTP_PROXY_COOKIE_HTTPONLY_ON 0x0010
|
||||
#define NGX_HTTP_PROXY_COOKIE_HTTPONLY_OFF 0x0020
|
||||
#define NGX_HTTP_PROXY_COOKIE_SAMESITE 0x0040
|
||||
#define NGX_HTTP_PROXY_COOKIE_SAMESITE_STRICT 0x0080
|
||||
#define NGX_HTTP_PROXY_COOKIE_SAMESITE_LAX 0x0100
|
||||
#define NGX_HTTP_PROXY_COOKIE_SAMESITE_NONE 0x0200
|
||||
#define NGX_HTTP_PROXY_COOKIE_SAMESITE_OFF 0x0400
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t caches; /* ngx_http_file_cache_t * */
|
||||
} ngx_http_proxy_main_conf_t;
|
||||
@ -35,6 +48,19 @@ struct ngx_http_proxy_rewrite_s {
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ngx_http_complex_value_t complex;
|
||||
#if (NGX_PCRE)
|
||||
ngx_http_regex_t *regex;
|
||||
#endif
|
||||
} cookie;
|
||||
|
||||
ngx_uint_t flags;
|
||||
ngx_uint_t regex;
|
||||
} ngx_http_proxy_cookie_flags_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t key_start;
|
||||
ngx_str_t schema;
|
||||
@ -72,6 +98,7 @@ typedef struct {
|
||||
ngx_array_t *redirects;
|
||||
ngx_array_t *cookie_domains;
|
||||
ngx_array_t *cookie_paths;
|
||||
ngx_array_t *cookie_flags;
|
||||
|
||||
ngx_http_complex_value_t *method;
|
||||
ngx_str_t location;
|
||||
@ -158,8 +185,14 @@ static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, size_t prefix);
|
||||
static ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h);
|
||||
static ngx_int_t ngx_http_proxy_parse_cookie(ngx_str_t *value,
|
||||
ngx_array_t *attrs);
|
||||
static ngx_int_t ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, u_char *value, ngx_array_t *rewrites);
|
||||
ngx_str_t *value, ngx_array_t *rewrites);
|
||||
static ngx_int_t ngx_http_proxy_rewrite_cookie_flags(ngx_http_request_t *r,
|
||||
ngx_array_t *attrs, ngx_array_t *flags);
|
||||
static ngx_int_t ngx_http_proxy_edit_cookie_flags(ngx_http_request_t *r,
|
||||
ngx_array_t *attrs, ngx_uint_t flags);
|
||||
static ngx_int_t ngx_http_proxy_rewrite(ngx_http_request_t *r,
|
||||
ngx_str_t *value, size_t prefix, size_t len, ngx_str_t *replacement);
|
||||
|
||||
@ -180,6 +213,8 @@ static char *ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_proxy_cookie_path(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_proxy_cookie_flags(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
#if (NGX_HTTP_CACHE)
|
||||
@ -282,6 +317,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_cookie_flags"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
|
||||
ngx_http_proxy_cookie_flags,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_store"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_proxy_store,
|
||||
@ -845,6 +887,36 @@ static ngx_path_init_t ngx_http_proxy_temp_path = {
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_bitmask_t ngx_http_proxy_cookie_flags_masks[] = {
|
||||
|
||||
{ ngx_string("secure"),
|
||||
NGX_HTTP_PROXY_COOKIE_SECURE|NGX_HTTP_PROXY_COOKIE_SECURE_ON },
|
||||
|
||||
{ ngx_string("nosecure"),
|
||||
NGX_HTTP_PROXY_COOKIE_SECURE|NGX_HTTP_PROXY_COOKIE_SECURE_OFF },
|
||||
|
||||
{ ngx_string("httponly"),
|
||||
NGX_HTTP_PROXY_COOKIE_HTTPONLY|NGX_HTTP_PROXY_COOKIE_HTTPONLY_ON },
|
||||
|
||||
{ ngx_string("nohttponly"),
|
||||
NGX_HTTP_PROXY_COOKIE_HTTPONLY|NGX_HTTP_PROXY_COOKIE_HTTPONLY_OFF },
|
||||
|
||||
{ ngx_string("samesite=strict"),
|
||||
NGX_HTTP_PROXY_COOKIE_SAMESITE|NGX_HTTP_PROXY_COOKIE_SAMESITE_STRICT },
|
||||
|
||||
{ ngx_string("samesite=lax"),
|
||||
NGX_HTTP_PROXY_COOKIE_SAMESITE|NGX_HTTP_PROXY_COOKIE_SAMESITE_LAX },
|
||||
|
||||
{ ngx_string("samesite=none"),
|
||||
NGX_HTTP_PROXY_COOKIE_SAMESITE|NGX_HTTP_PROXY_COOKIE_SAMESITE_NONE },
|
||||
|
||||
{ ngx_string("nosamesite"),
|
||||
NGX_HTTP_PROXY_COOKIE_SAMESITE|NGX_HTTP_PROXY_COOKIE_SAMESITE_OFF },
|
||||
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||
{
|
||||
@ -906,7 +978,7 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||
u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
|
||||
}
|
||||
|
||||
if (plcf->cookie_domains || plcf->cookie_paths) {
|
||||
if (plcf->cookie_domains || plcf->cookie_paths || plcf->cookie_flags) {
|
||||
u->rewrite_cookie = ngx_http_proxy_rewrite_cookie;
|
||||
}
|
||||
|
||||
@ -2598,27 +2670,41 @@ ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h)
|
||||
{
|
||||
size_t prefix;
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_int_t rc, rv;
|
||||
ngx_str_t *key, *value;
|
||||
ngx_uint_t i;
|
||||
ngx_array_t attrs;
|
||||
ngx_keyval_t *attr;
|
||||
ngx_http_proxy_loc_conf_t *plcf;
|
||||
|
||||
p = (u_char *) ngx_strchr(h->value.data, ';');
|
||||
if (p == NULL) {
|
||||
return NGX_DECLINED;
|
||||
ngx_array_init(&attrs, r->pool, 2, sizeof(ngx_keyval_t));
|
||||
|
||||
if (ngx_http_proxy_parse_cookie(&h->value, &attrs) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
prefix = p + 1 - h->value.data;
|
||||
attr = attrs.elts;
|
||||
|
||||
if (attr[0].value.data == NULL) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
rv = NGX_DECLINED;
|
||||
|
||||
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
|
||||
|
||||
if (plcf->cookie_domains) {
|
||||
p = ngx_strcasestrn(h->value.data + prefix, "domain=", 7 - 1);
|
||||
for (i = 1; i < attrs.nelts; i++) {
|
||||
|
||||
if (p) {
|
||||
rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 7,
|
||||
key = &attr[i].key;
|
||||
value = &attr[i].value;
|
||||
|
||||
if (plcf->cookie_domains && key->len == 6
|
||||
&& ngx_strncasecmp(key->data, (u_char *) "domain", 6) == 0
|
||||
&& value->data)
|
||||
{
|
||||
rc = ngx_http_proxy_rewrite_cookie_value(r, value,
|
||||
plcf->cookie_domains);
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
@ -2628,13 +2714,12 @@ ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h)
|
||||
rv = rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plcf->cookie_paths) {
|
||||
p = ngx_strcasestrn(h->value.data + prefix, "path=", 5 - 1);
|
||||
|
||||
if (p) {
|
||||
rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 5,
|
||||
if (plcf->cookie_paths && key->len == 4
|
||||
&& ngx_strncasecmp(key->data, (u_char *) "path", 4) == 0
|
||||
&& value->data)
|
||||
{
|
||||
rc = ngx_http_proxy_rewrite_cookie_value(r, value,
|
||||
plcf->cookie_paths);
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
@ -2646,30 +2731,153 @@ ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h)
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
if (plcf->cookie_flags) {
|
||||
rc = ngx_http_proxy_rewrite_cookie_flags(r, &attrs,
|
||||
plcf->cookie_flags);
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc != NGX_DECLINED) {
|
||||
rv = rc;
|
||||
}
|
||||
|
||||
attr = attrs.elts;
|
||||
}
|
||||
|
||||
if (rv != NGX_OK) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
|
||||
for (i = 0; i < attrs.nelts; i++) {
|
||||
|
||||
if (attr[i].key.data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
len += 2;
|
||||
}
|
||||
|
||||
len += attr[i].key.len;
|
||||
|
||||
if (attr[i].value.data) {
|
||||
len += 1 + attr[i].value.len;
|
||||
}
|
||||
}
|
||||
|
||||
p = ngx_pnalloc(r->pool, len + 1);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
h->value.data = p;
|
||||
h->value.len = len;
|
||||
|
||||
for (i = 0; i < attrs.nelts; i++) {
|
||||
|
||||
if (attr[i].key.data == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
*p++ = ';';
|
||||
*p++ = ' ';
|
||||
}
|
||||
|
||||
p = ngx_cpymem(p, attr[i].key.data, attr[i].key.len);
|
||||
|
||||
if (attr[i].value.data) {
|
||||
*p++ = '=';
|
||||
p = ngx_cpymem(p, attr[i].value.data, attr[i].value.len);
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
u_char *value, ngx_array_t *rewrites)
|
||||
ngx_http_proxy_parse_cookie(ngx_str_t *value, ngx_array_t *attrs)
|
||||
{
|
||||
u_char *start, *end, *p, *last;
|
||||
ngx_str_t name, val;
|
||||
ngx_keyval_t *attr;
|
||||
|
||||
start = value->data;
|
||||
end = value->data + value->len;
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
last = (u_char *) ngx_strchr(start, ';');
|
||||
|
||||
if (last == NULL) {
|
||||
last = end;
|
||||
}
|
||||
|
||||
while (start < last && *start == ' ') { start++; }
|
||||
|
||||
for (p = start; p < last && *p != '='; p++) { /* void */ }
|
||||
|
||||
name.data = start;
|
||||
name.len = p - start;
|
||||
|
||||
while (name.len && name.data[name.len - 1] == ' ') {
|
||||
name.len--;
|
||||
}
|
||||
|
||||
if (p < last) {
|
||||
|
||||
p++;
|
||||
|
||||
while (p < last && *p == ' ') { p++; }
|
||||
|
||||
val.data = p;
|
||||
val.len = last - val.data;
|
||||
|
||||
while (val.len && val.data[val.len - 1] == ' ') {
|
||||
val.len--;
|
||||
}
|
||||
|
||||
} else {
|
||||
ngx_str_null(&val);
|
||||
}
|
||||
|
||||
attr = ngx_array_push(attrs);
|
||||
if (attr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
attr->key = name;
|
||||
attr->value = val;
|
||||
|
||||
if (last == end) {
|
||||
break;
|
||||
}
|
||||
|
||||
start = last + 1;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, ngx_str_t *value,
|
||||
ngx_array_t *rewrites)
|
||||
{
|
||||
size_t len, prefix;
|
||||
u_char *p;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i;
|
||||
ngx_http_proxy_rewrite_t *pr;
|
||||
|
||||
prefix = value - h->value.data;
|
||||
|
||||
p = (u_char *) ngx_strchr(value, ';');
|
||||
|
||||
len = p ? (size_t) (p - value) : (h->value.len - prefix);
|
||||
|
||||
pr = rewrites->elts;
|
||||
|
||||
for (i = 0; i < rewrites->nelts; i++) {
|
||||
rc = pr[i].handler(r, &h->value, prefix, len, &pr[i]);
|
||||
rc = pr[i].handler(r, value, 0, value->len, &pr[i]);
|
||||
|
||||
if (rc != NGX_DECLINED) {
|
||||
return rc;
|
||||
@ -2680,6 +2888,192 @@ ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_rewrite_cookie_flags(ngx_http_request_t *r, ngx_array_t *attrs,
|
||||
ngx_array_t *flags)
|
||||
{
|
||||
ngx_str_t pattern;
|
||||
#if (NGX_PCRE)
|
||||
ngx_int_t rc;
|
||||
#endif
|
||||
ngx_uint_t i;
|
||||
ngx_keyval_t *attr;
|
||||
ngx_http_proxy_cookie_flags_t *pcf;
|
||||
|
||||
attr = attrs->elts;
|
||||
pcf = flags->elts;
|
||||
|
||||
for (i = 0; i < flags->nelts; i++) {
|
||||
|
||||
#if (NGX_PCRE)
|
||||
if (pcf[i].regex) {
|
||||
rc = ngx_http_regex_exec(r, pcf[i].cookie.regex, &attr[0].key);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* NGX_DECLINED */
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ngx_http_complex_value(r, &pcf[i].cookie.complex, &pattern)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (pattern.len == attr[0].key.len
|
||||
&& ngx_strncasecmp(attr[0].key.data, pattern.data, pattern.len)
|
||||
== 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == flags->nelts) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
return ngx_http_proxy_edit_cookie_flags(r, attrs, pcf[i].flags);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_edit_cookie_flags(ngx_http_request_t *r, ngx_array_t *attrs,
|
||||
ngx_uint_t flags)
|
||||
{
|
||||
ngx_str_t *key, *value;
|
||||
ngx_uint_t i;
|
||||
ngx_keyval_t *attr;
|
||||
|
||||
attr = attrs->elts;
|
||||
|
||||
for (i = 1; i < attrs->nelts; i++) {
|
||||
key = &attr[i].key;
|
||||
|
||||
if (key->len == 6
|
||||
&& ngx_strncasecmp(key->data, (u_char *) "secure", 6) == 0)
|
||||
{
|
||||
if (flags & NGX_HTTP_PROXY_COOKIE_SECURE_ON) {
|
||||
flags &= ~NGX_HTTP_PROXY_COOKIE_SECURE_ON;
|
||||
|
||||
} else if (flags & NGX_HTTP_PROXY_COOKIE_SECURE_OFF) {
|
||||
key->data = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key->len == 8
|
||||
&& ngx_strncasecmp(key->data, (u_char *) "httponly", 8) == 0)
|
||||
{
|
||||
if (flags & NGX_HTTP_PROXY_COOKIE_HTTPONLY_ON) {
|
||||
flags &= ~NGX_HTTP_PROXY_COOKIE_HTTPONLY_ON;
|
||||
|
||||
} else if (flags & NGX_HTTP_PROXY_COOKIE_HTTPONLY_OFF) {
|
||||
key->data = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key->len == 8
|
||||
&& ngx_strncasecmp(key->data, (u_char *) "samesite", 8) == 0)
|
||||
{
|
||||
value = &attr[i].value;
|
||||
|
||||
if (flags & NGX_HTTP_PROXY_COOKIE_SAMESITE_STRICT) {
|
||||
flags &= ~NGX_HTTP_PROXY_COOKIE_SAMESITE_STRICT;
|
||||
|
||||
if (value->len != 6
|
||||
|| ngx_strncasecmp(value->data, (u_char *) "strict", 6)
|
||||
!= 0)
|
||||
{
|
||||
ngx_str_set(key, "SameSite");
|
||||
ngx_str_set(value, "Strict");
|
||||
}
|
||||
|
||||
} else if (flags & NGX_HTTP_PROXY_COOKIE_SAMESITE_LAX) {
|
||||
flags &= ~NGX_HTTP_PROXY_COOKIE_SAMESITE_LAX;
|
||||
|
||||
if (value->len != 3
|
||||
|| ngx_strncasecmp(value->data, (u_char *) "lax", 3) != 0)
|
||||
{
|
||||
ngx_str_set(key, "SameSite");
|
||||
ngx_str_set(value, "Lax");
|
||||
}
|
||||
|
||||
} else if (flags & NGX_HTTP_PROXY_COOKIE_SAMESITE_NONE) {
|
||||
flags &= ~NGX_HTTP_PROXY_COOKIE_SAMESITE_NONE;
|
||||
|
||||
if (value->len != 4
|
||||
|| ngx_strncasecmp(value->data, (u_char *) "none", 4) != 0)
|
||||
{
|
||||
ngx_str_set(key, "SameSite");
|
||||
ngx_str_set(value, "None");
|
||||
}
|
||||
|
||||
} else if (flags & NGX_HTTP_PROXY_COOKIE_SAMESITE_OFF) {
|
||||
key->data = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & NGX_HTTP_PROXY_COOKIE_SECURE_ON) {
|
||||
attr = ngx_array_push(attrs);
|
||||
if (attr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_str_set(&attr->key, "Secure");
|
||||
ngx_str_null(&attr->value);
|
||||
}
|
||||
|
||||
if (flags & NGX_HTTP_PROXY_COOKIE_HTTPONLY_ON) {
|
||||
attr = ngx_array_push(attrs);
|
||||
if (attr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_str_set(&attr->key, "HttpOnly");
|
||||
ngx_str_null(&attr->value);
|
||||
}
|
||||
|
||||
if (flags & (NGX_HTTP_PROXY_COOKIE_SAMESITE_STRICT
|
||||
|NGX_HTTP_PROXY_COOKIE_SAMESITE_LAX
|
||||
|NGX_HTTP_PROXY_COOKIE_SAMESITE_NONE))
|
||||
{
|
||||
attr = ngx_array_push(attrs);
|
||||
if (attr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_str_set(&attr->key, "SameSite");
|
||||
|
||||
if (flags & NGX_HTTP_PROXY_COOKIE_SAMESITE_STRICT) {
|
||||
ngx_str_set(&attr->value, "Strict");
|
||||
|
||||
} else if (flags & NGX_HTTP_PROXY_COOKIE_SAMESITE_LAX) {
|
||||
ngx_str_set(&attr->value, "Lax");
|
||||
|
||||
} else {
|
||||
ngx_str_set(&attr->value, "None");
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_rewrite_complex_handler(ngx_http_request_t *r, ngx_str_t *value,
|
||||
size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr)
|
||||
@ -2742,7 +3136,7 @@ ngx_http_proxy_rewrite_domain_handler(ngx_http_request_t *r, ngx_str_t *value,
|
||||
|
||||
p = value->data + prefix;
|
||||
|
||||
if (p[0] == '.') {
|
||||
if (len && p[0] == '.') {
|
||||
p++;
|
||||
prefix++;
|
||||
len--;
|
||||
@ -2955,6 +3349,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
||||
|
||||
conf->cookie_domains = NGX_CONF_UNSET_PTR;
|
||||
conf->cookie_paths = NGX_CONF_UNSET_PTR;
|
||||
conf->cookie_flags = NGX_CONF_UNSET_PTR;
|
||||
|
||||
conf->http_version = NGX_CONF_UNSET_UINT;
|
||||
|
||||
@ -3350,6 +3745,8 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->cookie_paths, prev->cookie_paths, NULL);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->cookie_flags, prev->cookie_flags, NULL);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->http_version, prev->http_version,
|
||||
NGX_HTTP_VERSION_10);
|
||||
|
||||
@ -4081,6 +4478,131 @@ ngx_http_proxy_cookie_path(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_proxy_cookie_flags(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_proxy_loc_conf_t *plcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_uint_t i, m;
|
||||
ngx_conf_bitmask_t *mask;
|
||||
ngx_http_proxy_cookie_flags_t *pcf;
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
#if (NGX_PCRE)
|
||||
ngx_regex_compile_t rc;
|
||||
u_char errstr[NGX_MAX_CONF_ERRSTR];
|
||||
#endif
|
||||
|
||||
if (plcf->cookie_flags == NULL) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (cf->args->nelts == 2) {
|
||||
|
||||
if (ngx_strcmp(value[1].data, "off") == 0) {
|
||||
|
||||
if (plcf->cookie_flags != NGX_CONF_UNSET_PTR) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
plcf->cookie_flags = NULL;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (plcf->cookie_flags == NGX_CONF_UNSET_PTR) {
|
||||
plcf->cookie_flags = ngx_array_create(cf->pool, 1,
|
||||
sizeof(ngx_http_proxy_cookie_flags_t));
|
||||
if (plcf->cookie_flags == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
pcf = ngx_array_push(plcf->cookie_flags);
|
||||
if (pcf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
pcf->regex = 0;
|
||||
|
||||
if (value[1].data[0] == '~') {
|
||||
value[1].len--;
|
||||
value[1].data++;
|
||||
|
||||
#if (NGX_PCRE)
|
||||
ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
|
||||
|
||||
rc.pattern = value[1];
|
||||
rc.err.len = NGX_MAX_CONF_ERRSTR;
|
||||
rc.err.data = errstr;
|
||||
rc.options = NGX_REGEX_CASELESS;
|
||||
|
||||
pcf->cookie.regex = ngx_http_regex_compile(cf, &rc);
|
||||
if (pcf->cookie.regex == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
pcf->regex = 1;
|
||||
#else
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"using regex \"%V\" requires PCRE library",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
|
||||
|
||||
ccv.cf = cf;
|
||||
ccv.value = &value[1];
|
||||
ccv.complex_value = &pcf->cookie.complex;
|
||||
|
||||
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
mask = ngx_http_proxy_cookie_flags_masks;
|
||||
pcf->flags = 0;
|
||||
|
||||
for (i = 2; i < cf->args->nelts; i++) {
|
||||
for (m = 0; mask[m].name.len != 0; m++) {
|
||||
|
||||
if (mask[m].name.len != value[i].len
|
||||
|| ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pcf->flags & mask[m].mask) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"duplicate parameter \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
pcf->flags |= mask[m].mask;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (mask[m].name.len == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_rewrite_regex(ngx_conf_t *cf, ngx_http_proxy_rewrite_t *pr,
|
||||
ngx_str_t *regex, ngx_uint_t caseless)
|
||||
|
Loading…
x
Reference in New Issue
Block a user