Files
swift/test/unit/common/middleware/test_memcache.py
Vincent Untz e1ff51c045 Do not use pickle for serialization in memcache, but JSON
We don't want to use pickle as it can execute arbitrary code. JSON is
safer. However, note that it supports serialization for only some
specific subset of object types; this should be enough for what we need,
though.

To avoid issues on upgrades (unability to read pickled values, and cache
poisoning for old servers not understanding JSON), we add a
memcache_serialization_support configuration option, with the following
values:

 0 = older, insecure pickle serialization
 1 = json serialization but pickles can still be read (still insecure)
 2 = json serialization only (secure and the default)

To avoid an instant full cache flush, existing installations should
upgrade with 0, then set to 1 and reload, then after some time (24
hours) set to 2 and reload. Support for 0 and 1 will be removed in
future versions.

Part of bug 1006414.

Change-Id: Id7d6d547b103b4f23ebf5be98b88f09ec6027ce4
2012-08-03 16:22:21 +02:00

130 lines
3.9 KiB
Python

# Copyright (c) 2010-2012 OpenStack, LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from ConfigParser import NoSectionError, NoOptionError
from webob import Request
from swift.common.middleware import memcache
from swift.common.memcached import MemcacheRing
class FakeApp(object):
def __call__(self, env, start_response):
return env
class ExcConfigParser(object):
def read(self, path):
raise Exception('read called with %r' % path)
class EmptyConfigParser(object):
def read(self, path):
return False
class SetConfigParser(object):
def read(self, path):
return True
def get(self, section, option):
if section == 'memcache':
if option == 'memcache_servers':
return '1.2.3.4:5'
elif option == 'memcache_serialization_support':
return '2'
else:
raise NoOptionError(option)
else:
raise NoSectionError(option)
def start_response(*args):
pass
class TestCacheMiddleware(unittest.TestCase):
def setUp(self):
self.app = memcache.MemcacheMiddleware(FakeApp(), {})
def test_cache_middleware(self):
req = Request.blank('/something', environ={'REQUEST_METHOD': 'GET'})
resp = self.app(req.environ, start_response)
self.assertTrue('swift.cache' in resp)
self.assertTrue(isinstance(resp['swift.cache'], MemcacheRing))
def test_conf_default_read(self):
orig_parser = memcache.ConfigParser
memcache.ConfigParser = ExcConfigParser
exc = None
try:
app = memcache.MemcacheMiddleware(FakeApp(), {})
except Exception, err:
exc = err
finally:
memcache.ConfigParser = orig_parser
self.assertEquals(str(exc),
"read called with '/etc/swift/memcache.conf'")
def test_conf_set_no_read(self):
orig_parser = memcache.ConfigParser
memcache.ConfigParser = ExcConfigParser
exc = None
try:
app = memcache.MemcacheMiddleware(
FakeApp(), {'memcache_servers': '1.2.3.4:5',
'memcache_serialization_support': '2'})
except Exception, err:
exc = err
finally:
memcache.ConfigParser = orig_parser
self.assertEquals(exc, None)
def test_conf_default(self):
orig_parser = memcache.ConfigParser
memcache.ConfigParser = EmptyConfigParser
try:
app = memcache.MemcacheMiddleware(FakeApp(), {})
finally:
memcache.ConfigParser = orig_parser
self.assertEquals(app.memcache_servers, '127.0.0.1:11211')
def test_conf_from_extra_conf(self):
orig_parser = memcache.ConfigParser
memcache.ConfigParser = SetConfigParser
try:
app = memcache.MemcacheMiddleware(FakeApp(), {})
finally:
memcache.ConfigParser = orig_parser
self.assertEquals(app.memcache_servers, '1.2.3.4:5')
def test_conf_from_inline_conf(self):
orig_parser = memcache.ConfigParser
memcache.ConfigParser = SetConfigParser
try:
app = memcache.MemcacheMiddleware(
FakeApp(), {'memcache_servers': '6.7.8.9:10'})
finally:
memcache.ConfigParser = orig_parser
self.assertEquals(app.memcache_servers, '6.7.8.9:10')
if __name__ == '__main__':
unittest.main()