This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/http/response.py b/http/response.py | |
index f7d248e..dbd1c34 100644 | |
--- a/http/response.py | |
+++ b/http/response.py | |
@@ -16,7 +16,7 @@ from django.core.serializers.json import DjangoJSONEncoder | |
from django.http.cookie import SimpleCookie | |
from django.utils import timezone | |
from django.utils.encoding import iri_to_uri | |
-from django.utils.http import http_date | |
+from django.utils.http import http_date, is_new_redirect_supported | |
_charset_from_content_type_re = re.compile(r';\s*charset=(?P<charset>[^\s;]+)', re.I) | |
@@ -470,11 +470,15 @@ class HttpResponseRedirectBase(HttpResponse): | |
class HttpResponseRedirect(HttpResponseRedirectBase): | |
- status_code = 302 | |
+ def __init__(self, *args, request=None, **kwargs): | |
+ self.status_code = 307 if is_new_redirect_supported(request) else 301 | |
+ super().__init__(*args, **kwargs) | |
class HttpResponsePermanentRedirect(HttpResponseRedirectBase): | |
- status_code = 301 | |
+ def __init__(self, *args, request=None, **kwargs): | |
+ self.status_code = 308 if is_new_redirect_supported(request) else 302 | |
+ super().__init__(*args, **kwargs) | |
class HttpResponseNotModified(HttpResponse): | |
diff --git a/middleware/common.py b/middleware/common.py | |
index a18fbe7..a339899 100644 | |
--- a/middleware/common.py | |
+++ b/middleware/common.py | |
@@ -57,7 +57,7 @@ class CommonMiddleware(MiddlewareMixin): | |
# Return a redirect if necessary | |
if redirect_url or path != request.get_full_path(): | |
redirect_url += path | |
- return self.response_redirect_class(redirect_url) | |
+ return self.response_redirect_class(redirect_url, request=request) | |
def should_redirect_with_slash(self, request): | |
""" | |
@@ -104,7 +104,7 @@ class CommonMiddleware(MiddlewareMixin): | |
# a path with a slash appended. | |
if response.status_code == 404: | |
if self.should_redirect_with_slash(request): | |
- return self.response_redirect_class(self.get_full_path_with_slash(request)) | |
+ return self.response_redirect_class(self.get_full_path_with_slash(request), request=request) | |
# Add the Content-Length header to non-streaming responses if not | |
# already set. | |
diff --git a/utils/http.py b/utils/http.py | |
index de1ea71..7414956 100644 | |
--- a/utils/http.py | |
+++ b/utils/http.py | |
@@ -43,6 +43,9 @@ RFC3986_SUBDELIMS = "!$&'()*+,;=" | |
FIELDS_MATCH = re.compile('[&;]') | |
+# IE11 on Win 7/8/8.1 doesn't support 307/308 redirect | |
+OLD_IE_MATCH = re.compile(r'Windows NT 6\.\d;.+Trident') | |
+ | |
@keep_lazy_text | |
def urlquote(url, safe='/'): | |
@@ -456,3 +459,11 @@ def escape_leading_slashes(url): | |
if url.startswith('//'): | |
url = '/%2F{}'.format(url[2:]) | |
return url | |
+ | |
+def is_new_redirect_supported(request): | |
+ """ | |
+ Return user agent support new redirect status code (307/308). | |
+ """ | |
+ if not request: | |
+ return False | |
+ return not OLD_IE_MATCH.search(request.META['HTTP_USER_AGENT']) | |
\ No newline at end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment