Skip to content

Commit

Permalink
Initial implementation of 304 responses with the new interceptor appr…
Browse files Browse the repository at this point in the history
…oach

svn path=/plone.app.caching/trunk/; revision=33068
  • Loading branch information
optilude committed Jan 15, 2010
1 parent be619a7 commit cf07a08
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 54 deletions.
2 changes: 0 additions & 2 deletions TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ Plone caching to-do
plone.app.caching
-----------------

[ ] Set RAM cache key

[ ] Tests for utils

[ ] Tests for ETag components
Expand Down
7 changes: 4 additions & 3 deletions plone/app/caching/lastmodified.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime
from dateutil.tz import tzlocal

from zope.interface import implementer, implements
from zope.component import adapter, adapts
Expand Down Expand Up @@ -39,7 +40,7 @@ def __call__(self):
context = aq_base(self.context)
mtime = getattr(context, '_p_mtime', None)
if mtime is not None and mtime > 0:
return datetime.fromtimestamp(mtime)
return datetime.fromtimestamp(mtime, tzlocal())
return None

class OFSFileLastModified(PersistentLastModified):
Expand All @@ -63,7 +64,7 @@ def __call__(self):
# we do this instead of getModTime() to avoid having to convert from
# a DateTime
mtime = self.context._file_mod_time
return datetime.fromtimestamp(mtime)
return datetime.fromtimestamp(mtime, tzlocal())

class CatalogableDublinCoreLastModified(object):
"""ILastModified adapter for ICatalogableDublinCore, which includes
Expand Down Expand Up @@ -108,5 +109,5 @@ def __init__(self, context):
def __call__(self):
lmt = getattr(self.context.context, 'lmt', None)
if lmt is not None:
return datetime.fromtimestamp(lmt)
return datetime.fromtimestamp(lmt, tzlocal())
return None
84 changes: 63 additions & 21 deletions plone/app/caching/operations/default.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from AccessControl.PermissionRole import rolesForPermissionOn

from zope.interface import implements
from zope.interface import classProvides
from zope.interface import Interface
Expand All @@ -15,14 +13,19 @@
from plone.app.caching.operations.utils import doNotCache
from plone.app.caching.operations.utils import cacheInBrowser
from plone.app.caching.operations.utils import cacheInProxy
from plone.app.caching.operations.utils import cacheEverywhere
from plone.app.caching.operations.utils import cacheInBrowserAndProxy
from plone.app.caching.operations.utils import cacheInRAM

from plone.app.caching.operations.utils import cachedResponse
from plone.app.caching.operations.utils import notModified

from plone.app.caching.operations.utils import getETag
from plone.app.caching.operations.utils import getContext
from plone.app.caching.operations.utils import safeLastModified
from plone.app.caching.operations.utils import getLastModified

from plone.app.caching.operations.utils import fetchFromRAMCache
from plone.app.caching.operations.utils import isModified
from plone.app.caching.operations.utils import visibleToRole

from plone.app.caching.interfaces import _

Expand Down Expand Up @@ -62,11 +65,17 @@ def interceptResponse(self, rulename, response):
context = getContext(self.published)
portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state')

etag = getETag(self.published, self.request, options['etags'] or self.etags)

if portal_state.anonymous():
etag = getETag(self.published, self.request, options['etags'] or self.etags)
cached = fetchFromRAMCache(self.request, etag=etag)
if cached is not None:
return cachedResponse(self.published, self.request, response, cached=cached)

if not isModified(self.request, etag=etag):
return notModified(self.published, self.request, response, etag=etag)

return None

def modifyResponse(self, rulename, response):
options = lookupOptions(CompositeViews, rulename)
Expand Down Expand Up @@ -108,11 +117,17 @@ def interceptResponse(self, rulename, response):
context = getContext(self.published)
portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state')

etag = getETag(self.published, self.request, options['etags'] or self.etags)

if portal_state.anonymous():
etag = getETag(self.published, self.request, options['etags'] or self.etags)
cached = fetchFromRAMCache(self.request, etag=etag)
if cached is not None:
return cachedResponse(self.published, self.request, response, cached=cached)

if not isModified(self.request, etag=etag):
return notModified(self.published, self.request, response, etag=etag)

return None

def modifyResponse(self, rulename, response):
options = lookupOptions(ContentFeeds, rulename)
Expand All @@ -121,6 +136,7 @@ def modifyResponse(self, rulename, response):
portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state')

etag = getETag(self.published, self.request, options['etags'] or self.etags)

cacheInBrowser(self.published, self.request, response, etag=etag)

if portal_state.anonymous():
Expand Down Expand Up @@ -153,6 +169,21 @@ def __init__(self, published, request):
self.request = request

def interceptResponse(self, rulename, response):
options = lookupOptions(ContentFeedsWithProxy, rulename)

context = getContext(self.published)
portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state')

etag = getETag(self.published, self.request, options['etags'] or self.etags)

if portal_state.anonymous():
cached = fetchFromRAMCache(self.request, etag=etag)
if cached is not None:
return cachedResponse(self.published, self.request, response, cached=cached)
else:
if not isModified(self.request, etag=etag):
return notModified(self.published, self.request, response, etag=etag)

return None

def modifyResponse(self, rulename, response):
Expand Down Expand Up @@ -190,13 +221,16 @@ def __init__(self, published, request):
self.request = request

def interceptResponse(self, rulename, response):
if visibleToRole(self.published, role='Anonymous'):
lastmodified = getLastModified(self.published)
if not isModified(self.request, lastmodified=lastmodified):
return notModified(self.published, self.request, response, lastmodified=lastmodified)

return None

def modifyResponse(self, rulename, response):
context = getContext(self.published)

if 'Anonymous' in rolesForPermissionOn('View', context):
lastmodified = safeLastModified(self.published)
if visibleToRole(self.published, role='Anonymous'):
lastmodified = getLastModified(self.published)
cacheInBrowser(self.published, self.request, response, lastmodified=lastmodified)
else:
doNotCache(self.published, self.request, response)
Expand Down Expand Up @@ -232,13 +266,11 @@ def interceptResponse(self, rulename, response):
def modifyResponse(self, rulename, response):
options = lookupOptions(DownloadsWithProxy, rulename)

context = getContext(self.published)

smaxage = options['smaxage'] or self.smaxage
vary = options['vary'] or self.vary

if 'Anonymous' in rolesForPermissionOn('View', context):
lastmodified = safeLastModified(self.published)
if visibleToRole(self.published, role='Anonymous'):
lastmodified = getLastModified(self.published)
cacheInProxy(self.published, self.request, response, smaxage=smaxage, lastmodified=lastmodified, vary=vary)
else:
doNotCache(self.published, self.request, response)
Expand Down Expand Up @@ -267,6 +299,10 @@ def __init__(self, published, request):
self.request = request

def interceptResponse(self, rulename, response):
lastmodified = getLastModified(self.published)
if not isModified(self.request, lastmodified=lastmodified):
return notModified(self.published, self.request, response, lastmodified=lastmodified)

return None

def modifyResponse(self, rulename, response):
Expand All @@ -275,8 +311,8 @@ def modifyResponse(self, rulename, response):
maxage = options['maxage'] or self.maxage
vary = options['vary'] or self.vary

lastmodified = safeLastModified(self.published)
cacheEverywhere(self.published, self.request, response, maxage=maxage, lastmodified=lastmodified, vary=vary)
lastmodified = getLastModified(self.published)
cacheInBrowserAndProxy(self.published, self.request, response, maxage=maxage, lastmodified=lastmodified, vary=vary)

class StableResources(object):
implements(ICachingOperation)
Expand Down Expand Up @@ -304,6 +340,14 @@ def __init__(self, published, request):
self.request = request

def interceptResponse(self, rulename, response):
options = lookupOptions(StableResources, rulename)

lastmodified = getLastModified(self.published)
etag = getETag(self.published, self.request, options['etags'] or self.etags)

if not isModified(self.request, etag=etag, lastmodified=lastmodified):
return notModified(self.published, self.request, response, etag=etag, lastmodified=lastmodified)

return None

def modifyResponse(self, rulename, response):
Expand All @@ -313,8 +357,9 @@ def modifyResponse(self, rulename, response):
etag = getETag(self.published, self.request, options['etags'] or self.etags)
vary = options['vary'] or self.vary

lastmodified = safeLastModified(self.published)
cacheEverywhere(self.published, self.request, response, maxage=maxage, lastmodified=lastmodified, etag=etag, vary=vary)
lastmodified = getLastModified(self.published)
cacheInBrowserAndProxy(self.published, self.request, response,
maxage=maxage, etag=etag, lastmodified=lastmodified, vary=vary)

if HAVE_RESOURCE_REGISTRIES:

Expand All @@ -325,9 +370,6 @@ class ResourceRegistriesStableResources(StableResources):

adapts(ICookedFile, IHTTPRequest)

def interceptResponse(self, rulename, response):
return None

def modifyResponse(self, rulename, response):
registry = getContext(self.published, IResourceRegistry)

Expand Down
4 changes: 2 additions & 2 deletions plone/app/caching/operations/etags.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from plone.app.caching.interfaces import IPloneCacheSettings

from plone.app.caching.operations.utils import getContext
from plone.app.caching.operations.utils import safeLastModified
from plone.app.caching.operations.utils import getLastModified

from Products.CMFCore.utils import getToolByName

Expand Down Expand Up @@ -135,7 +135,7 @@ def __init__(self, published, request):
self.request = request

def __call__(self):
lastModified = safeLastModified(self.published)
lastModified = getLastModified(self.published)
if lastModified is None:
return None
return str(time.mktime(lastModified.timetuple()))
Expand Down
Loading

0 comments on commit cf07a08

Please sign in to comment.