diff --git a/envs/dev.py b/envs/dev.py index 9d65059447..cf430dab86 100644 --- a/envs/dev.py +++ b/envs/dev.py @@ -31,7 +31,8 @@ CACHES = { # In staging/prod envs, the sessions also live here. 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - 'LOCATION': 'mitx_loc_mem_cache' + 'LOCATION': 'mitx_loc_mem_cache', + 'KEY_FUNCTION': 'util.memcache.safe_key', }, # The general cache is what you get if you use our util.cache. It's used for @@ -43,6 +44,7 @@ CACHES = { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', 'KEY_PREFIX': 'general', 'VERSION': 4, + 'KEY_FUNCTION': 'util.cache.memcache_safe_key', } } diff --git a/envs/devplus.py b/envs/devplus.py index 4f763b925c..1c81bdd7b2 100644 --- a/envs/devplus.py +++ b/envs/devplus.py @@ -30,12 +30,14 @@ CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', + 'KEY_FUNCTION': 'util.memcache.safe_key', }, 'general': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', 'KEY_PREFIX' : 'general', 'VERSION' : 5, + 'KEY_FUNCTION': 'util.memcache.safe_key', } } diff --git a/envs/static.py b/envs/static.py index 65309c4795..55469ce332 100644 --- a/envs/static.py +++ b/envs/static.py @@ -30,7 +30,8 @@ CACHES = { # In staging/prod envs, the sessions also live here. 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - 'LOCATION': 'mitx_loc_mem_cache' + 'LOCATION': 'mitx_loc_mem_cache', + 'KEY_FUNCTION': 'util.memcache.safe_key', }, # The general cache is what you get if you use our util.cache. It's used for @@ -42,6 +43,7 @@ CACHES = { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', 'KEY_PREFIX': 'general', 'VERSION': 4, + 'KEY_FUNCTION': 'util.memcache.safe_key', } } diff --git a/envs/test.py b/envs/test.py index bf83511786..6702a3c852 100644 --- a/envs/test.py +++ b/envs/test.py @@ -54,7 +54,8 @@ CACHES = { # In staging/prod envs, the sessions also live here. 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - 'LOCATION': 'mitx_loc_mem_cache' + 'LOCATION': 'mitx_loc_mem_cache', + 'KEY_FUNCTION': 'util.memcache.safe_key', }, # The general cache is what you get if you use our util.cache. It's used for @@ -66,6 +67,7 @@ CACHES = { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', 'KEY_PREFIX': 'general', 'VERSION': 4, + 'KEY_FUNCTION': 'util.memcache.safe_key', } } diff --git a/lib/util/memcache.py b/lib/util/memcache.py new file mode 100644 index 0000000000..e0c6037b0c --- /dev/null +++ b/lib/util/memcache.py @@ -0,0 +1,18 @@ +""" +This module provides a KEY_FUNCTION suitable for use with a memcache backend +so that we can cache any keys, not just ones that memcache would ordinarily accept +""" +from django.utils.hashcompat import md5_constructor +from django.utils.encoding import smart_str +import string + +def safe_key(key, key_prefix, version): + safe_key = smart_str(key) + for char in safe_key: + if ord(char) < 33 or ord(char) == 127: + safe_key = safe_key.replace(char, '_') + + if len(safe_key) > 250: + safe_key = md5_constructor(safe_key) + + return ":".join([key_prefix, str(version), safe_key])