Kaydet (Commit) a82488bf authored tarafından Jannis Leidel's avatar Jannis Leidel

Fixed #16966 -- Stopped CachedStaticFilesStorage from choking on querystrings and path fragments.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17068 bcc190cf-cafb-0310-a4f2-bffc1f526a37
üst 0e2c5439
...@@ -3,6 +3,8 @@ import hashlib ...@@ -3,6 +3,8 @@ import hashlib
import os import os
import posixpath import posixpath
import re import re
from urllib import unquote
from urlparse import urlsplit, urlunsplit
from django.conf import settings from django.conf import settings
from django.core.cache import (get_cache, InvalidCacheBackendError, from django.core.cache import (get_cache, InvalidCacheBackendError,
...@@ -64,23 +66,28 @@ class CachedFilesMixin(object): ...@@ -64,23 +66,28 @@ class CachedFilesMixin(object):
self._patterns.setdefault(extension, []).append(compiled) self._patterns.setdefault(extension, []).append(compiled)
def hashed_name(self, name, content=None): def hashed_name(self, name, content=None):
parsed_name = urlsplit(unquote(name))
clean_name = parsed_name.path
if content is None: if content is None:
if not self.exists(name): if not self.exists(clean_name):
raise ValueError("The file '%s' could not be found with %r." % raise ValueError("The file '%s' could not be found with %r." %
(name, self)) (clean_name, self))
try: try:
content = self.open(name) content = self.open(clean_name)
except IOError: except IOError:
# Handle directory paths # Handle directory paths
return name return name
path, filename = os.path.split(name) path, filename = os.path.split(clean_name)
root, ext = os.path.splitext(filename) root, ext = os.path.splitext(filename)
# Get the MD5 hash of the file # Get the MD5 hash of the file
md5 = hashlib.md5() md5 = hashlib.md5()
for chunk in content.chunks(): for chunk in content.chunks():
md5.update(chunk) md5.update(chunk)
md5sum = md5.hexdigest()[:12] md5sum = md5.hexdigest()[:12]
return os.path.join(path, u"%s.%s%s" % (root, md5sum, ext)) hashed_name = os.path.join(path, u"%s.%s%s" % (root, md5sum, ext))
unparsed_name = list(parsed_name)
unparsed_name[2] = hashed_name
return urlunsplit(unparsed_name)
def cache_key(self, name): def cache_key(self, name):
return u'staticfiles:cache:%s' % name return u'staticfiles:cache:%s' % name
...@@ -98,7 +105,7 @@ class CachedFilesMixin(object): ...@@ -98,7 +105,7 @@ class CachedFilesMixin(object):
hashed_name = self.hashed_name(name) hashed_name = self.hashed_name(name)
# set the cache if there was a miss (e.g. if cache server goes down) # set the cache if there was a miss (e.g. if cache server goes down)
self.cache.set(cache_key, hashed_name) self.cache.set(cache_key, hashed_name)
return super(CachedFilesMixin, self).url(hashed_name) return unquote(super(CachedFilesMixin, self).url(hashed_name))
def url_converter(self, name): def url_converter(self, name):
""" """
...@@ -132,9 +139,9 @@ class CachedFilesMixin(object): ...@@ -132,9 +139,9 @@ class CachedFilesMixin(object):
else: else:
start, end = 1, sub_level - 1 start, end = 1, sub_level - 1
joined_result = '/'.join(name_parts[:-start] + url_parts[end:]) joined_result = '/'.join(name_parts[:-start] + url_parts[end:])
hashed_url = self.url(joined_result, force=True) hashed_url = self.url(unquote(joined_result), force=True)
# Return the hashed and normalized version to the file # Return the hashed and normalized version to the file
return 'url("%s")' % hashed_url return 'url("%s")' % unquote(hashed_url)
return converter return converter
def post_process(self, paths, dry_run=False, **options): def post_process(self, paths, dry_run=False, **options):
......
@import url("../cached/styles.css"); @import url("../cached/styles.css");
@import url("absolute.css"); @import url("absolute.css");
@import url("absolute.css#eggs");
body { body {
background: #d3d6d8 url(img/relative.png); background: #d3d6d8 url(img/relative.png);
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment