summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis Leidel <jannis@leidel.info>2011-12-27 22:49:24 +0000
committerJannis Leidel <jannis@leidel.info>2011-12-27 22:49:24 +0000
commit46c12d1293aa90209f3c640f214c4b5a3d6cb9e6 (patch)
treef84e2971618d516b74877bd43022a4ec38858f77
parentae0ce4373ff63fac22f4673928f2cf4378cb54e0 (diff)
Fixed #17455 -- Extended `CachedStaticFilesStorage` slightly to handle some URLs better that are used to add support for webfonts to IE 6-8. Also ignore `data:` URLs and fragment-only URLs (e.g. `#default#VML`).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17282 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/staticfiles/storage.py17
-rw-r--r--tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.eot1
-rw-r--r--tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.svg1
-rw-r--r--tests/regressiontests/staticfiles_tests/project/documents/cached/css/fragments.css8
-rw-r--r--tests/regressiontests/staticfiles_tests/storage.py2
-rw-r--r--tests/regressiontests/staticfiles_tests/tests.py10
6 files changed, 33 insertions, 6 deletions
diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py
index c0cc100ca8..1b2060de13 100644
--- a/django/contrib/staticfiles/storage.py
+++ b/django/contrib/staticfiles/storage.py
@@ -12,7 +12,7 @@ from django.core.cache import (get_cache, InvalidCacheBackendError,
from django.core.exceptions import ImproperlyConfigured
from django.core.files.base import ContentFile
from django.core.files.storage import FileSystemStorage, get_storage_class
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_unicode, smart_str
from django.utils.functional import LazyObject
from django.utils.importlib import import_module
from django.utils.datastructures import SortedDict
@@ -84,9 +84,14 @@ class CachedFilesMixin(object):
for chunk in content.chunks():
md5.update(chunk)
md5sum = md5.hexdigest()[:12]
- hashed_name = 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
+ # Special casing for a @font-face hack, like url(myfont.eot?#iefix")
+ # http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax
+ if '?#' in name and not unparsed_name[3]:
+ unparsed_name[2] += '?'
return urlunsplit(unparsed_name)
def cache_key(self, name):
@@ -103,7 +108,8 @@ class CachedFilesMixin(object):
hashed_name = self.cache.get(cache_key)
if hashed_name is None:
hashed_name = self.hashed_name(name).replace('\\', '/')
- # 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)
return unquote(super(CachedFilesMixin, self).url(hashed_name))
@@ -119,7 +125,7 @@ class CachedFilesMixin(object):
"""
matched, url = matchobj.groups()
# Completely ignore http(s) prefixed URLs
- if url.startswith(('http', 'https')):
+ if url.startswith(('#', 'http', 'https', 'data:')):
return matched
name_parts = name.split(os.sep)
# Using posix normpath here to remove duplicates
@@ -182,7 +188,8 @@ class CachedFilesMixin(object):
if self.exists(hashed_name):
self.delete(hashed_name)
- saved_name = self._save(hashed_name, ContentFile(content))
+ content_file = ContentFile(smart_str(content))
+ saved_name = self._save(hashed_name, content_file)
hashed_name = force_unicode(saved_name.replace('\\', '/'))
processed_files.append(hashed_name)
diff --git a/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.eot b/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.eot
new file mode 100644
index 0000000000..7c58b2e622
--- /dev/null
+++ b/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.eot
@@ -0,0 +1 @@
+not really a EOT ;) \ No newline at end of file
diff --git a/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.svg b/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.svg
new file mode 100644
index 0000000000..0282375915
--- /dev/null
+++ b/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fonts/font.svg
@@ -0,0 +1 @@
+not really a SVG ;) \ No newline at end of file
diff --git a/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fragments.css b/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fragments.css
new file mode 100644
index 0000000000..540d54b88d
--- /dev/null
+++ b/tests/regressiontests/staticfiles_tests/project/documents/cached/css/fragments.css
@@ -0,0 +1,8 @@
+@font-face {
+ src: url('fonts/font.eot?#iefix') format('embedded-opentype'),
+ url('fonts/font.svg#webfontIyfZbseF') format('svg');
+ url('data:font/woff;charset=utf-8;base64,d09GRgABAAAAADJoAA0AAAAAR2QAAQAAAAAAAAAAAAA');
+}
+div {
+ behavior: url("#default#VML");
+}
diff --git a/tests/regressiontests/staticfiles_tests/storage.py b/tests/regressiontests/staticfiles_tests/storage.py
index cfe1e13bdb..8358f833c8 100644
--- a/tests/regressiontests/staticfiles_tests/storage.py
+++ b/tests/regressiontests/staticfiles_tests/storage.py
@@ -4,7 +4,7 @@ from django.core.files import storage
class DummyStorage(storage.Storage):
"""
A storage class that does implement modified_time() but raises
- NotImplementedError when calling
+ NotImplementedError when calling
"""
def _save(self, name, content):
return 'dummy'
diff --git a/tests/regressiontests/staticfiles_tests/tests.py b/tests/regressiontests/staticfiles_tests/tests.py
index 5d41157351..bd22ea9f3e 100644
--- a/tests/regressiontests/staticfiles_tests/tests.py
+++ b/tests/regressiontests/staticfiles_tests/tests.py
@@ -331,6 +331,16 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
self.assertNotIn("cached/other.css", content)
self.assertIn("/static/cached/other.d41d8cd98f00.css", content)
+ def test_path_with_querystring_and_fragment(self):
+ relpath = self.cached_file_path("cached/css/fragments.css")
+ self.assertEqual(relpath, "cached/css/fragments.75433540b096.css")
+ with storage.staticfiles_storage.open(relpath) as relfile:
+ content = relfile.read()
+ self.assertIn('/static/cached/css/fonts/font.a4b0478549d0.eot?#iefix', content)
+ self.assertIn('/static/cached/css/fonts/font.b8d603e42714.svg#webfontIyfZbseF', content)
+ self.assertIn('data:font/woff;charset=utf-8;base64,d09GRgABAAAAADJoAA0AAAAAR2QAAQAAAAAAAAAAAAA', content)
+ self.assertIn('#default#VML', content)
+
def test_template_tag_absolute(self):
relpath = self.cached_file_path("cached/absolute.css")
self.assertEqual(relpath, "cached/absolute.cc80cb5e2eb1.css")