Skip to content

Commit ddb7b0b

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 ddb7b0b

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

sendfile/backends/_internalredirect.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,44 @@
11
import os.path
2+
import subprocess
3+
import re
24

35
from django.conf import settings
46
from django.utils.encoding import smart_text, smart_bytes
7+
from django.conf import settings
58

69
try:
710
from urllib.parse import quote
811
except ImportError:
912
from urllib import quote
1013

1114

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

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

0 commit comments

Comments
 (0)