Create custom pickle serializer.

We need to do this because when I tride to go to the JSON serializer a
bunch of tests started failing because various parts of our code are
putting things into the session that are not JSON serializable.

We can't keep using the default pickle serializer because it defaluts to
using the highest available protocol and that will cause issues with the
python 2 to 3 upgrade since both will be running in production at the
same time.  We need to use a version of the pickle protocol that both
can use interchangably.

We also need to make sure we read with latin1 encoding to make datetimes
work correctly between the two versions of python.
This commit is contained in:
Feanil Patel
2019-10-18 10:39:01 -04:00
parent 1e97de9105
commit bfc02dc3ab
3 changed files with 39 additions and 0 deletions

View File

@@ -829,6 +829,7 @@ COURSES_WITH_UNSAFE_CODE = []
DEBUG = False
SESSION_COOKIE_SECURE = False
SESSION_SAVE_EVERY_REQUEST = False
SESSION_SERIALIZER = 'openedx.core.lib.session_serializers.PickleV2Serializer'
SESSION_COOKIE_DOMAIN = ""
SESSION_COOKIE_NAME = 'sessionid'

View File

@@ -1101,6 +1101,7 @@ DEBUG = False
USE_TZ = True
SESSION_COOKIE_SECURE = False
SESSION_SAVE_EVERY_REQUEST = False
SESSION_SERIALIZER = 'openedx.core.lib.session_serializers.PickleV2Serializer'
SESSION_COOKIE_DOMAIN = ""
SESSION_COOKIE_NAME = 'sessionid'

View File

@@ -0,0 +1,37 @@
"""
Custom session serializer to deal with going from python2 and python3.
"""
import pickle
import six
class PickleV2Serializer(object):
"""
Lock the pickle serializer to version 2 of the protocol
because we don't want python 2 to be able to read session
data written by python3 while both are running at the same
time in production.
Based on the PickleSerializer built into django:
https://github.com/django/django/blob/master/django/contrib/sessions/serializers.py
"""
protocol = 2
def dumps(self, obj):
"""
Return a pickled representation of object.
"""
return pickle.dumps(obj, self.protocol)
def loads(self, data):
"""
Return a python object from pickled data.
"""
if six.PY2:
# Params used below don't exist in python 2
return pickle.loads(data)
else:
# See notes here about pickling python2 objects in python3
# https://docs.python.org/3/library/pickle.html#pickle.Unpickler
return pickle.loads(data, encoding='latin1') # pylint: disable=unexpected-keyword-arg