diff src/http/ngx_http.c @ 7848:1bde031b59ff

Location header escaping in redirects (ticket #882). The header is escaped in redirects based on request URI or location name (auto redirect).
author Ruslan Ermilov <ru@nginx.com>
date Mon, 24 May 2021 21:55:20 +0300
parents 4e141d0816d4
children 61abb35bb8cf d514f88053e5
line wrap: on
line diff
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -37,6 +37,8 @@ static ngx_int_t ngx_http_init_locations
     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, ng
 
     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;
 }