mirror of
https://github.com/nginx/nginx.git
synced 2024-12-24 08:00:14 -06:00
Location header escaping in redirects (ticket #882).
The header is escaped in redirects based on request URI or location name (auto redirect).
This commit is contained in:
parent
52d0ec7d17
commit
41a241b3ef
@ -1072,6 +1072,10 @@ ngx_http_dav_error(ngx_log_t *log, ngx_err_t err, ngx_int_t not_found,
|
||||
static ngx_int_t
|
||||
ngx_http_dav_location(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
uintptr_t escape;
|
||||
|
||||
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.location == NULL) {
|
||||
return NGX_ERROR;
|
||||
@ -1079,7 +1083,26 @@ ngx_http_dav_location(ngx_http_request_t *r)
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
ngx_str_set(&r->headers_out.location->key, "Location");
|
||||
r->headers_out.location->value = r->uri;
|
||||
|
||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_URI);
|
||||
|
||||
if (escape) {
|
||||
len = r->uri.len + escape;
|
||||
|
||||
p = ngx_pnalloc(r->pool, len);
|
||||
if (p == NULL) {
|
||||
ngx_http_clear_location(r);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.location->value.len = len;
|
||||
r->headers_out.location->value.data = p;
|
||||
|
||||
ngx_escape_uri(p, r->uri.data, r->uri.len, NGX_ESCAPE_URI);
|
||||
|
||||
} else {
|
||||
r->headers_out.location->value = r->uri;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *last, *location;
|
||||
size_t root, len;
|
||||
uintptr_t escape;
|
||||
ngx_str_t path;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t level;
|
||||
@ -155,14 +156,18 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
len = r->uri.len + 1;
|
||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
|
||||
NGX_ESCAPE_URI);
|
||||
|
||||
if (!clcf->alias && r->args.len == 0) {
|
||||
if (!clcf->alias && r->args.len == 0 && escape == 0) {
|
||||
len = r->uri.len + 1;
|
||||
location = path.data + root;
|
||||
|
||||
*last = '/';
|
||||
|
||||
} else {
|
||||
len = r->uri.len + escape + 1;
|
||||
|
||||
if (r->args.len) {
|
||||
len += r->args.len + 1;
|
||||
}
|
||||
@ -173,7 +178,13 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
last = ngx_copy(location, r->uri.data, r->uri.len);
|
||||
if (escape) {
|
||||
last = (u_char *) ngx_escape_uri(location, r->uri.data,
|
||||
r->uri.len, NGX_ESCAPE_URI);
|
||||
|
||||
} else {
|
||||
last = ngx_copy(location, r->uri.data, r->uri.len);
|
||||
}
|
||||
|
||||
*last = '/';
|
||||
|
||||
|
@ -37,6 +37,8 @@ static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf,
|
||||
ngx_http_core_srv_conf_t *cscf, ngx_http_core_loc_conf_t *pclcf);
|
||||
static ngx_int_t ngx_http_init_static_location_trees(ngx_conf_t *cf,
|
||||
ngx_http_core_loc_conf_t *pclcf);
|
||||
static ngx_int_t ngx_http_escape_location_name(ngx_conf_t *cf,
|
||||
ngx_http_core_loc_conf_t *clcf);
|
||||
static ngx_int_t ngx_http_cmp_locations(const ngx_queue_t *one,
|
||||
const ngx_queue_t *two);
|
||||
static ngx_int_t ngx_http_join_exact_locations(ngx_conf_t *cf,
|
||||
@ -882,6 +884,41 @@ ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
|
||||
|
||||
ngx_queue_insert_tail(*locations, &lq->queue);
|
||||
|
||||
if (ngx_http_escape_location_name(cf, clcf) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_escape_location_name(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
uintptr_t escape;
|
||||
|
||||
escape = 2 * ngx_escape_uri(NULL, clcf->name.data, clcf->name.len,
|
||||
NGX_ESCAPE_URI);
|
||||
|
||||
if (escape) {
|
||||
len = clcf->name.len + escape;
|
||||
|
||||
p = ngx_pnalloc(cf->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
clcf->escaped_name.len = len;
|
||||
clcf->escaped_name.data = p;
|
||||
|
||||
ngx_escape_uri(p, clcf->name.data, clcf->name.len, NGX_ESCAPE_URI);
|
||||
|
||||
} else {
|
||||
clcf->escaped_name = clcf->name;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -1010,10 +1010,10 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
|
||||
ngx_str_set(&r->headers_out.location->key, "Location");
|
||||
|
||||
if (r->args.len == 0) {
|
||||
r->headers_out.location->value = clcf->name;
|
||||
r->headers_out.location->value = clcf->escaped_name;
|
||||
|
||||
} else {
|
||||
len = clcf->name.len + 1 + r->args.len;
|
||||
len = clcf->escaped_name.len + 1 + r->args.len;
|
||||
p = ngx_pnalloc(r->pool, len);
|
||||
|
||||
if (p == NULL) {
|
||||
@ -1025,7 +1025,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
|
||||
r->headers_out.location->value.len = len;
|
||||
r->headers_out.location->value.data = p;
|
||||
|
||||
p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
|
||||
p = ngx_cpymem(p, clcf->escaped_name.data, clcf->escaped_name.len);
|
||||
*p++ = '?';
|
||||
ngx_memcpy(p, r->args.data, r->args.len);
|
||||
}
|
||||
@ -3467,6 +3467,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* clcf->escaped_name = { 0, NULL };
|
||||
* clcf->root = { 0, NULL };
|
||||
* clcf->limit_except = 0;
|
||||
* clcf->post_action = { 0, NULL };
|
||||
|
@ -299,6 +299,7 @@ typedef struct {
|
||||
|
||||
struct ngx_http_core_loc_conf_s {
|
||||
ngx_str_t name; /* location name */
|
||||
ngx_str_t escaped_name;
|
||||
|
||||
#if (NGX_PCRE)
|
||||
ngx_http_regex_t *regex;
|
||||
|
Loading…
Reference in New Issue
Block a user