Patch: slash_redirect_temporary directive

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Patch: slash_redirect_temporary directive

Blake Williams
Hello!

We ran into an issue where with the permanent redirects in ngx_http_static_module.c that occur when you omit a slash when requesting a folder, for example from "/foo" to the folder "/foo/". We changed some things around in our site so that "/foo" was actually a file, not a folder, but unfortunately, browsers aggressively cache 301 redirects so our clients were trying to hit the new URL, the browser used its permanent cache, and they'd be redirected to "/foo/" again, which no longer existed as it had been changed to a file.

This patch adds an extra configuration directive that allows you to configure that redirect to issue a 302 instead:

# HG changeset patch
# User Blake Williams <[hidden email]>
# Date 1567294381 -36000
#      Sun Sep 01 09:33:01 2019 +1000
# Node ID 85c36c3f5c349a83b1b397a8aad2d11bf6a0875a
# Parent  9f1f9d6e056a4f85907957ef263f78a426ae4f9c
Add slash_redirect_temporary directive to core

diff -r 9f1f9d6e056a -r 85c36c3f5c34 contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim Mon Aug 19 15:16:06 2019 +0300
+++ b/contrib/vim/syntax/nginx.vim Sun Sep 01 09:33:01 2019 +1000
@@ -571,6 +571,7 @@
syn keyword ngxDirective contained session_log_format
syn keyword ngxDirective contained session_log_zone
syn keyword ngxDirective contained set_real_ip_from
+syn keyword ngxDirective contained slash_redirect_temporary
syn keyword ngxDirective contained slice
syn keyword ngxDirective contained smtp_auth
syn keyword ngxDirective contained smtp_capabilities
diff -r 9f1f9d6e056a -r 85c36c3f5c34 src/http/modules/ngx_http_static_module.c
--- a/src/http/modules/ngx_http_static_module.c Mon Aug 19 15:16:06 2019 +0300
+++ b/src/http/modules/ngx_http_static_module.c Sun Sep 01 09:33:01 2019 +1000
@@ -188,7 +188,11 @@
        r->headers_out.location->value.len = len;
        r->headers_out.location->value.data = location;

-        return NGX_HTTP_MOVED_PERMANENTLY;
+        if (!clcf->slash_redirect_temporary) {
+            return NGX_HTTP_MOVED_PERMANENTLY;
+        } else {
+            return NGX_HTTP_MOVED_TEMPORARILY;
+        }
    }

#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
diff -r 9f1f9d6e056a -r 85c36c3f5c34 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Mon Aug 19 15:16:06 2019 +0300
+++ b/src/http/ngx_http_core_module.c Sun Sep 01 09:33:01 2019 +1000
@@ -520,6 +520,13 @@
      offsetof(ngx_http_core_loc_conf_t, satisfy),
      &ngx_http_core_satisfy },

+    { ngx_string("slash_redirect_temporary"),
+      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, slash_redirect_temporary),
+      NULL },
+
    { ngx_string("internal"),
      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
      ngx_http_core_internal,
@@ -3443,6 +3450,8 @@
    clcf->open_file_cache_errors = NGX_CONF_UNSET;
    clcf->open_file_cache_events = NGX_CONF_UNSET;

+    clcf->slash_redirect_temporary = NGX_CONF_UNSET;
+
#if (NGX_HTTP_GZIP)
    clcf->gzip_vary = NGX_CONF_UNSET;
    clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
@@ -3727,6 +3736,9 @@

    ngx_conf_merge_sec_value(conf->open_file_cache_events,
                              prev->open_file_cache_events, 0);
+
+    ngx_conf_merge_value(conf->slash_redirect_temporary,
+                              prev->slash_redirect_temporary, 0);
#if (NGX_HTTP_GZIP)

    ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
diff -r 9f1f9d6e056a -r 85c36c3f5c34 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Mon Aug 19 15:16:06 2019 +0300
+++ b/src/http/ngx_http_core_module.h Sun Sep 01 09:33:01 2019 +1000
@@ -433,6 +433,8 @@
    ngx_uint_t    types_hash_max_size;
    ngx_uint_t    types_hash_bucket_size;

+    ngx_flag_t    slash_redirect_temporary;
+
    ngx_queue_t  *locations;

#if 0
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Patch: slash_redirect_temporary directive

Constantine A. Murenin-2
If you don't like 301 redirects because permanent caching — can't blame you there, as I'm in same boat — an easier way would be to simply use what I call the exception handling mechanism of nginx to change all 301 replies to 302, and you don't need any patches to perform such a change, as a simple nginx.conf snippet would suffice:

        error_page 301 =302 @200;
        location @200 {
                # https://serverfault.com/a/870911/110020
                default_type "";
                return 200;
        }

If you don't like the `200` part in the config, and lack of a body in the response, then the following is also an option:

        error_page 301 = @302;
        location @302 {
                # https://serverfault.com/a/870722/110020
                return  302 $sent_http_location;
        }

I've tested both of the above for directory access sans `/`, and both do the job just fine.

Cheers,
Constantine.SU.                http://cm.su/

On Sat, 31 Aug 2019 at 17:46, Blake Williams <[hidden email]> wrote:
Hello!

We ran into an issue where with the permanent redirects in ngx_http_static_module.c that occur when you omit a slash when requesting a folder, for example from "/foo" to the folder "/foo/". We changed some things around in our site so that "/foo" was actually a file, not a folder, but unfortunately, browsers aggressively cache 301 redirects so our clients were trying to hit the new URL, the browser used its permanent cache, and they'd be redirected to "/foo/" again, which no longer existed as it had been changed to a file.

This patch adds an extra configuration directive that allows you to configure that redirect to issue a 302 instead:

# HG changeset patch
# User Blake Williams <[hidden email]>
# Date 1567294381 -36000
#      Sun Sep 01 09:33:01 2019 +1000
# Node ID 85c36c3f5c349a83b1b397a8aad2d11bf6a0875a
# Parent  9f1f9d6e056a4f85907957ef263f78a426ae4f9c
Add slash_redirect_temporary directive to core

diff -r 9f1f9d6e056a -r 85c36c3f5c34 contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim      Mon Aug 19 15:16:06 2019 +0300
+++ b/contrib/vim/syntax/nginx.vim      Sun Sep 01 09:33:01 2019 +1000
@@ -571,6 +571,7 @@
syn keyword ngxDirective contained session_log_format
syn keyword ngxDirective contained session_log_zone
syn keyword ngxDirective contained set_real_ip_from
+syn keyword ngxDirective contained slash_redirect_temporary
syn keyword ngxDirective contained slice
syn keyword ngxDirective contained smtp_auth
syn keyword ngxDirective contained smtp_capabilities
diff -r 9f1f9d6e056a -r 85c36c3f5c34 src/http/modules/ngx_http_static_module.c
--- a/src/http/modules/ngx_http_static_module.c Mon Aug 19 15:16:06 2019 +0300
+++ b/src/http/modules/ngx_http_static_module.c Sun Sep 01 09:33:01 2019 +1000
@@ -188,7 +188,11 @@
        r->headers_out.location->value.len = len;
        r->headers_out.location->value.data = location;

-        return NGX_HTTP_MOVED_PERMANENTLY;
+        if (!clcf->slash_redirect_temporary) {
+            return NGX_HTTP_MOVED_PERMANENTLY;
+        } else {
+            return NGX_HTTP_MOVED_TEMPORARILY;
+        }
    }

#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
diff -r 9f1f9d6e056a -r 85c36c3f5c34 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c   Mon Aug 19 15:16:06 2019 +0300
+++ b/src/http/ngx_http_core_module.c   Sun Sep 01 09:33:01 2019 +1000
@@ -520,6 +520,13 @@
      offsetof(ngx_http_core_loc_conf_t, satisfy),
      &ngx_http_core_satisfy },

+    { ngx_string("slash_redirect_temporary"),
+      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, slash_redirect_temporary),
+      NULL },
+
    { ngx_string("internal"),
      NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
      ngx_http_core_internal,
@@ -3443,6 +3450,8 @@
    clcf->open_file_cache_errors = NGX_CONF_UNSET;
    clcf->open_file_cache_events = NGX_CONF_UNSET;

+    clcf->slash_redirect_temporary = NGX_CONF_UNSET;
+
#if (NGX_HTTP_GZIP)
    clcf->gzip_vary = NGX_CONF_UNSET;
    clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
@@ -3727,6 +3736,9 @@

    ngx_conf_merge_sec_value(conf->open_file_cache_events,
                              prev->open_file_cache_events, 0);
+
+    ngx_conf_merge_value(conf->slash_redirect_temporary,
+                              prev->slash_redirect_temporary, 0);
#if (NGX_HTTP_GZIP)

    ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
diff -r 9f1f9d6e056a -r 85c36c3f5c34 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h   Mon Aug 19 15:16:06 2019 +0300
+++ b/src/http/ngx_http_core_module.h   Sun Sep 01 09:33:01 2019 +1000
@@ -433,6 +433,8 @@
    ngx_uint_t    types_hash_max_size;
    ngx_uint_t    types_hash_bucket_size;

+    ngx_flag_t    slash_redirect_temporary;
+
    ngx_queue_t  *locations;

#if 0
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx