Skip to content

Commit 9afdea4

Browse files
committed
backends-nginx: Add support for Nginx versions older than 1.5.9.
In this commit we are adding support for Nginx version older than 1.5.9. This is achieved through conditionally quoting the URL's in X-Accel-Redirect headers according to compatibility with Nginx. Since newer versions of Nginx expect URL's in X-Accel-Redirect to be quoted unlike the versions older that Nginx 1.5.9. In this commit we start to check the Nginx version using 'nginx -v' and then caching the result be making use of a decorator. Using this result we decide whether the outgoing URL should be quoted or not. Fixes: johnsensible#56, johnsensible#58. Closes johnsensible#45.
1 parent b99f963 commit 9afdea4

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

sendfile/backends/_internalredirect.py

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,43 @@
11
import os.path
2+
import subprocess
23

34
from django.conf import settings
45
from django.utils.encoding import smart_text, smart_bytes
6+
from django.conf import settings
57

68
try:
79
from urllib.parse import quote
810
except ImportError:
911
from urllib import quote
1012

1113

14+
def _decision(fn):
15+
_cached_decision = []
16+
def _decorated():
17+
if not _cached_decision:
18+
_cached_decision.append(fn())
19+
return _cached_decision[0]
20+
return _decorated
21+
22+
@_decision
23+
def should_be_quoted():
24+
backend = getattr(settings, 'SENDFILE_BACKEND', None)
25+
if backend == 'sendfile.backends.nginx':
26+
try:
27+
nginx_version = subprocess.Popen(['nginx','-v'],
28+
stdout=subprocess.PIPE,
29+
stderr=subprocess.STDOUT).stdout.read()
30+
nginx_version = nginx_version.split('/')[1].split(' ')[0].split('.')
31+
nginx_version = map(int, nginx_version)
32+
# Since Starting with Nginx 1.5.9, quoted url's are expected to be
33+
# sent with X-Accel-Redirect headers, we will not quote url's for
34+
# versions of Nginx before 1.5.9
35+
if nginx_version < [1, 5, 9]:
36+
return False
37+
except:
38+
return True
39+
return True
40+
1241
def _convert_file_to_url(filename):
1342
relpath = os.path.relpath(filename, settings.SENDFILE_ROOT)
1443

@@ -21,4 +50,7 @@ def _convert_file_to_url(filename):
2150
# Python3 urllib.parse.quote accepts both unicode and bytes, while Python2 urllib.quote only accepts bytes.
2251
# So use bytes for quoting and then go back to unicode.
2352
url = [smart_bytes(url_component) for url_component in url]
24-
return smart_text(quote(b'/'.join(url)))
53+
if should_be_quoted():
54+
return smart_text(quote(b'/'.join(url)))
55+
else:
56+
return smart_text(b'/'.join(url))

0 commit comments

Comments
 (0)