Sanitize cache keys for memcached

Closes #208
This commit is contained in:
Matthew Tretter 2013-04-30 09:09:08 -04:00
parent bc0c17010e
commit c704db2da5
3 changed files with 24 additions and 2 deletions

View file

@ -1,4 +1,4 @@
from ..utils import get_singleton
from ..utils import get_singleton, sanitize_cache_key
from django.core.cache import get_cache
from django.core.exceptions import ImproperlyConfigured
@ -57,7 +57,8 @@ class CachedFileBackend(object):
def get_key(self, file):
from django.conf import settings
return '%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, file.name)
return sanitize_cache_key('%s%s-state' %
(settings.IMAGEKIT_CACHE_PREFIX, file.name))
def get_state(self, file):
key = self.get_key(file)

View file

@ -13,6 +13,7 @@ class ImageKitConf(AppConf):
CACHE_BACKEND = None
CACHE_PREFIX = 'imagekit:'
USE_MEMCACHED_SAFE_CACHE_KEY = True
def configure_cache_backend(self, value):
if value is None:

View file

@ -1,10 +1,16 @@
import logging
from tempfile import NamedTemporaryFile
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files import File
from django.utils.importlib import import_module
from hashlib import md5
from pilkit.utils import *
import re
bad_memcached_key_chars = re.compile(ur'[\u0000-\u0031\s]+')
def get_nonabstract_descendants(model):
@ -123,3 +129,17 @@ def call_strategy_method(generator, method_name, *args, **kwargs):
fn = getattr(strategy, method_name, None)
if fn is not None:
fn(*args, **kwargs)
def sanitize_cache_key(key):
if settings.IMAGEKIT_USE_MEMCACHED_SAFE_CACHE_KEY:
# Memcached keys can't contain whitespace or control characters.
new_key = bad_memcached_key_chars.sub('', key)
# The also can't be > 250 chars long. Since we don't know what the
# user's cache ``KEY_FUNCTION`` setting is like, we'll limit it to 200.
if len(new_key) >= 200:
new_key = '%s:%s' % (new_key[:200-33], md5(key).hexdigest())
key = new_key
return key