]> git.kaiwu.me - nginx.git/commitdiff
Core: relative redirects (closes #1000).
authorRuslan Ermilov <ru@nginx.com>
Wed, 21 Dec 2016 20:10:51 +0000 (23:10 +0300)
committerRuslan Ermilov <ru@nginx.com>
Wed, 21 Dec 2016 20:10:51 +0000 (23:10 +0300)
The current version of HTTP/1.1 standard allows relative references in
redirects (https://tools.ietf.org/html/rfc7231#section-7.1.2).

Allow this form for redirects generated by nginx by introducing the new
directive absolute_redirect.

src/http/ngx_http_core_module.c
src/http/ngx_http_core_module.h
src/http/ngx_http_header_filter_module.c
src/http/v2/ngx_http_v2_filter_module.c

index 4e37cec266113cc1fea4a6473fcf4f037c6928a2..685e72e4cdd7671456df5480968213b983488438 100644 (file)
@@ -542,6 +542,13 @@ static ngx_command_t  ngx_http_core_commands[] = {
       offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
       NULL },
 
+    { ngx_string("absolute_redirect"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, absolute_redirect),
+      NULL },
+
     { ngx_string("server_name_in_redirect"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
       ngx_conf_set_flag_slot,
@@ -3563,6 +3570,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
     clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
     clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
     clcf->reset_timedout_connection = NGX_CONF_UNSET;
+    clcf->absolute_redirect = NGX_CONF_UNSET;
     clcf->server_name_in_redirect = NGX_CONF_UNSET;
     clcf->port_in_redirect = NGX_CONF_UNSET;
     clcf->msie_padding = NGX_CONF_UNSET;
@@ -3825,6 +3833,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
 
     ngx_conf_merge_value(conf->reset_timedout_connection,
                               prev->reset_timedout_connection, 0);
+    ngx_conf_merge_value(conf->absolute_redirect,
+                              prev->absolute_redirect, 1);
     ngx_conf_merge_value(conf->server_name_in_redirect,
                               prev->server_name_in_redirect, 0);
     ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
index ade9abbe57863066261ee79291b496f29dbb05c2..237cc5cfd284fc18be569977020d8264bbc1d5f5 100644 (file)
@@ -385,6 +385,7 @@ struct ngx_http_core_loc_conf_s {
     ngx_flag_t    tcp_nopush;              /* tcp_nopush */
     ngx_flag_t    tcp_nodelay;             /* tcp_nodelay */
     ngx_flag_t    reset_timedout_connection; /* reset_timedout_connection */
+    ngx_flag_t    absolute_redirect;       /* absolute_redirect */
     ngx_flag_t    server_name_in_redirect; /* server_name_in_redirect */
     ngx_flag_t    port_in_redirect;        /* port_in_redirect */
     ngx_flag_t    msie_padding;            /* msie_padding */
index f000b2e494edc355cfc4893df8655cbbd4e0e4b1..88c8a61456a2c7c18c232ed96cb5e95a729dc173 100644 (file)
@@ -309,7 +309,8 @@ ngx_http_header_filter(ngx_http_request_t *r)
 
     if (r->headers_out.location
         && r->headers_out.location->value.len
-        && r->headers_out.location->value.data[0] == '/')
+        && r->headers_out.location->value.data[0] == '/'
+        && clcf->absolute_redirect)
     {
         r->headers_out.location->hash = 0;
 
index 8abca4dd28dfd192faecd8a59423b0417fa0c567..f2f0d1e418c5d1c8b4c893db245ae16e19231e50 100644 (file)
@@ -263,7 +263,9 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
 
     if (r->headers_out.location && r->headers_out.location->value.len) {
 
-        if (r->headers_out.location->value.data[0] == '/') {
+        if (r->headers_out.location->value.data[0] == '/'
+            && clcf->absolute_redirect)
+        {
             if (clcf->server_name_in_redirect) {
                 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
                 host = cscf->server_name;