class CachingPolicyManager304Tests(RequestTest, FSDVTest): def setUp(self): RequestTest.setUp(self) FSDVTest.setUp(self) now = DateTime() # Create a fake portal and the tools we need self.portal = DummySite(id='portal').__of__(self.root) self.portal._setObject('portal_types', DummyTool()) # This is a FSPageTemplate that will be used as the View for # our content objects. It doesn't matter what it returns. path = os.path.join(self.skin_path_name, 'testPT2.pt') self.portal._setObject('dummy_view', FSPageTemplate('dummy_view', path)) uf = self.root.acl_users password = '******' uf.userFolderAddUser(portal_owner, password, ['Manager'], []) user = uf.getUserById(portal_owner) if not hasattr(user, 'aq_base'): user = user.__of__(uf) newSecurityManager(None, user) owner_auth = '%s:%s' % (portal_owner, password) self.auth_header = "Basic %s" % base64.encodestring(owner_auth) self.portal._setObject('doc1', DummyContent('doc1')) self.portal._setObject('doc2', DummyContent('doc2')) self.portal._setObject('doc3', DummyContent('doc3')) self.portal.doc1.modified_date = now self.portal.doc2.modified_date = now self.portal.doc3.modified_date = now CachingPolicyManager.manage_addCachingPolicyManager(self.portal) cpm = self.portal.caching_policy_manager # This policy only applies to doc1. It will not emit any ETag header # but it enables If-modified-since handling. cpm.addPolicy(policy_id = 'policy_no_etag', predicate = 'python:object.getId()=="doc1"', mtime_func = '', max_age_secs = 0, no_cache = 0, no_store = 0, must_revalidate = 0, vary = '', etag_func = '', enable_304s = 1) # This policy only applies to doc2. It will emit an ETag with # the constant value "abc" and also enable if-modified-since handling. cpm.addPolicy(policy_id = 'policy_etag', predicate = 'python:object.getId()=="doc2"', mtime_func = '', max_age_secs = 0, no_cache = 0, no_store = 0, must_revalidate = 0, vary = '', etag_func = 'string:abc', enable_304s = 1) # This policy only applies to doc3. Etags with constant values of # "abc" are emitted, but if-modified-since handling is turned off. cpm.addPolicy(policy_id = 'policy_disabled', predicate = 'python:object.getId()=="doc3"', mtime_func = '', max_age_secs = 0, no_cache = 0, no_store = 0, must_revalidate = 0, vary = '', etag_func = 'string:abc', enable_304s = 0) def tearDown(self): RequestTest.tearDown(self) FSDVTest.tearDown(self) def _cleanup(self): # Clean up request and response req = self.portal.REQUEST for header in ( 'IF_MODIFIED_SINCE' , 'HTTP_AUTHORIZATION' , 'IF_NONE_MATCH' ): if req.environ.get(header, None) is not None: del req.environ[header] req.RESPONSE.setStatus(200) def testUnconditionalGET(self): # In this case the Request does not specify any if-modified-since # value to take into account, thereby completely circumventing any # if-modified-since handling. This must not produce a response status # of 304, regardless of any other headers. self.portal.doc1() response = self.portal.REQUEST.RESPONSE self.assertEqual(response.getStatus(), 200) def testConditionalGETNoETag(self): yesterday = DateTime() - 1 doc1 = self.portal.doc1 request = doc1.REQUEST response = request.RESPONSE # If doc1 has beeen modified since yesterday (which it has), we want # the full rendering. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(yesterday) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 200) self._cleanup() # If doc1 has been modified since its creation (which it hasn't), we # want the full rendering. This must return a 304 response. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc1.modified_date) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 304) self._cleanup() # ETag handling is not enabled in the policy for doc1, so asking for # one will not produce any matches. We get the full rendering. request.environ['IF_NONE_MATCH'] = '"123"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 200) self._cleanup() # We are asking for an ETag as well as modifications after doc2 has # been created. Both won't match and wwe get the full rendering. request.environ['IF_NONE_MATCH'] = '"123"' request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc1.modified_date) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 200) self._cleanup() def testConditionalGETETag(self): yesterday = DateTime() - 1 doc2 = self.portal.doc2 request = doc2.REQUEST response = request.RESPONSE # Has doc2 been modified since yesterday? Yes it has, so we get the # full rendering. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(yesterday) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # If doc2 has not been modified since its creation (which it hasn't), # we would get a 304 here. However, the policy for doc2 also expects # to get an ETag in the request, which we are not setting here. So # the policy fails and we get a full rendering. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc2.modified_date) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # Now we are setting an ETag in our request, but an ETag that does not # match the policy's expected value. The policy fails and we get the # full rendering. request.environ['IF_NONE_MATCH'] = '"123"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # Here we provide the correct and matching ETag value, and we don't # specify any if-modified-since condition. This is enough for our # policy to trigger 304. request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 304) self._cleanup() # We specify an ETag and a modification time condition that dooes not # match, so we get the full rendering request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc2.modified_date) request.environ['IF_NONE_MATCH'] = '"123"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # We hand in a matching modified time condition which is supposed to # trigger full rendering. This will lead the ETag condition to be # overrridden. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(yesterday) request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # Now we pass an ETag that matches the policy and a modified time # condition that is not fulfilled. It is safe to serve a 304. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc2.modified_date) request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 304) self._cleanup() def testConditionalGETDisabled(self): yesterday = DateTime() - 1 doc3 = self.portal.doc3 request = doc3.REQUEST response = request.RESPONSE # Our policy disables any 304-handling, so even though the ETag matches # the policy, we will get the full rendering. request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc3() self.assertEqual(response.getStatus(), 200) self._cleanup() # Now both the ETag and the modified condition would trigger a 304 # response *if* 304-handling was enabled. It is not in our policy, so # we get the full rendering again. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc3.modified_date) request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc3() self.assertEqual(response.getStatus(), 200) self._cleanup()
class CachingPolicyManager304Tests(PlacelessSetup, RequestTest, FSDVTest): def setUp(self): from Products.CMFCore import CachingPolicyManager PlacelessSetup.setUp(self) RequestTest.setUp(self) FSDVTest.setUp(self) zcml.load_config('meta.zcml', Products.Five) zcml.load_config('permissions.zcml', Products.Five) zcml.load_config('configure.zcml', Products.CMFCore) zcml.load_string(_TRAVERSE_ZCML) now = DateTime() # Create a fake portal and the tools we need self.portal = DummySite(id='portal').__of__(self.root) self.portal._setObject('portal_types', DummyTool()) # This is a FSPageTemplate that will be used as the View for # our content objects. It doesn't matter what it returns. path = os.path.join(self.skin_path_name, 'testPT2.pt') self.portal._setObject('dummy_view', FSPageTemplate('dummy_view', path)) uf = self.root.acl_users password = '******' uf.userFolderAddUser(portal_owner, password, ['Manager'], []) user = uf.getUserById(portal_owner) if not hasattr(user, 'aq_base'): user = user.__of__(uf) newSecurityManager(None, user) owner_auth = '%s:%s' % (portal_owner, password) self.auth_header = "Basic %s" % base64.encodestring(owner_auth) self.portal._setObject('doc1', DummyContent('doc1')) self.portal._setObject('doc2', DummyContent('doc2')) self.portal._setObject('doc3', DummyContent('doc3')) self.portal.doc1.modified_date = now self.portal.doc2.modified_date = now self.portal.doc3.modified_date = now CachingPolicyManager.manage_addCachingPolicyManager(self.portal) cpm = self.portal.caching_policy_manager # This policy only applies to doc1. It will not emit any ETag header # but it enables If-modified-since handling. cpm.addPolicy(policy_id='policy_no_etag', predicate='python:object.getId()=="doc1"', mtime_func='', max_age_secs=0, no_cache=0, no_store=0, must_revalidate=0, vary='', etag_func='', enable_304s=1) # This policy only applies to doc2. It will emit an ETag with # the constant value "abc" and also enable if-modified-since handling. cpm.addPolicy(policy_id='policy_etag', predicate='python:object.getId()=="doc2"', mtime_func='', max_age_secs=0, no_cache=0, no_store=0, must_revalidate=0, vary='', etag_func='string:abc', enable_304s=1) # This policy only applies to doc3. Etags with constant values of # "abc" are emitted, but if-modified-since handling is turned off. cpm.addPolicy(policy_id='policy_disabled', predicate='python:object.getId()=="doc3"', mtime_func='', max_age_secs=0, no_cache=0, no_store=0, must_revalidate=0, vary='', etag_func='string:abc', enable_304s=0) def tearDown(self): RequestTest.tearDown(self) FSDVTest.tearDown(self) PlacelessSetup.tearDown(self) def _cleanup(self): # Clean up request and response req = self.portal.REQUEST for header in ('IF_MODIFIED_SINCE', 'HTTP_AUTHORIZATION', 'IF_NONE_MATCH'): if req.environ.get(header, None) is not None: del req.environ[header] req.RESPONSE.setStatus(200) def testUnconditionalGET(self): # In this case the Request does not specify any if-modified-since # value to take into account, thereby completely circumventing any # if-modified-since handling. This must not produce a response status # of 304, regardless of any other headers. self.portal.doc1() response = self.portal.REQUEST.RESPONSE self.assertEqual(response.getStatus(), 200) def testConditionalGETNoETag(self): yesterday = DateTime() - 1 doc1 = self.portal.doc1 request = doc1.REQUEST response = request.RESPONSE # If doc1 has beeen modified since yesterday (which it has), we want # the full rendering. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(yesterday) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 200) self._cleanup() # If doc1 has been modified since its creation (which it hasn't), we # want the full rendering. This must return a 304 response. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc1.modified_date) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 304) self._cleanup() # ETag handling is not enabled in the policy for doc1, so asking for # one will not produce any matches. We get the full rendering. request.environ['IF_NONE_MATCH'] = '"123"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 200) self._cleanup() # We are asking for an ETag as well as modifications after doc2 has # been created. Both won't match and wwe get the full rendering. request.environ['IF_NONE_MATCH'] = '"123"' request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc1.modified_date) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc1() self.assertEqual(response.getStatus(), 200) self._cleanup() def testConditionalGETETag(self): yesterday = DateTime() - 1 doc2 = self.portal.doc2 request = doc2.REQUEST response = request.RESPONSE # Has doc2 been modified since yesterday? Yes it has, so we get the # full rendering. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(yesterday) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # If doc2 has not been modified since its creation (which it hasn't), # we would get a 304 here. However, the policy for doc2 also expects # to get an ETag in the request, which we are not setting here. So # the policy fails and we get a full rendering. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc2.modified_date) request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # Now we are setting an ETag in our request, but an ETag that does not # match the policy's expected value. The policy fails and we get the # full rendering. request.environ['IF_NONE_MATCH'] = '"123"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # Here we provide the correct and matching ETag value, and we don't # specify any if-modified-since condition. This is enough for our # policy to trigger 304. request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 304) self._cleanup() # We specify an ETag and a modification time condition that dooes not # match, so we get the full rendering request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc2.modified_date) request.environ['IF_NONE_MATCH'] = '"123"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # We hand in a matching modified time condition which is supposed to # trigger full rendering. This will lead the ETag condition to be # overrridden. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(yesterday) request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 200) self._cleanup() # Now we pass an ETag that matches the policy and a modified time # condition that is not fulfilled. It is safe to serve a 304. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc2.modified_date) request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc2() self.assertEqual(response.getStatus(), 304) self._cleanup() def testConditionalGETDisabled(self): yesterday = DateTime() - 1 doc3 = self.portal.doc3 request = doc3.REQUEST response = request.RESPONSE # Our policy disables any 304-handling, so even though the ETag matches # the policy, we will get the full rendering. request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc3() self.assertEqual(response.getStatus(), 200) self._cleanup() # Now both the ETag and the modified condition would trigger a 304 # response *if* 304-handling was enabled. It is not in our policy, so # we get the full rendering again. request.environ['IF_MODIFIED_SINCE'] = rfc1123_date(doc3.modified_date) request.environ['IF_NONE_MATCH'] = '"abc"' request.environ['HTTP_AUTHORIZATION'] = self.auth_header doc3() self.assertEqual(response.getStatus(), 200) self._cleanup()