Esempio n. 1
0
    def modifyResponse(self, rulename, response, class_=None):
        options = lookupOptions(class_ or self.__class__, rulename)

        maxage   = options.get('maxage') or self.maxage
        smaxage  = options.get('smaxage') or self.smaxage
        etags    = options.get('etags') or self.etags

        anonOnly = options.get('anonOnly', self.anonOnly)
        vary     = u'Cookie,Accept-Encoding'

        # Add the ``anonymousOrRandom`` etag if we are anonymous only
        if anonOnly:
            if etags is None:
                etags = ['anonymousOrRandom']
            elif 'anonymousOrRandom' not in etags:
                etags = tuple(etags) + ('anonymousOrRandom',)

        etag = getETagAnnotation(self.published, self.request, etags)
        lastModified = getLastModifiedAnnotation(self.published, self.request, options['lastModified'])

        # Check for cache stop request variables
        if cacheStop(self.request, rulename):
            # only stop with etags if configured
            if etags:
                etag = "%s%d" % (time.time(), random.randint(0, 1000))
                return setCacheHeaders(self.published, self.request, response, etag=etag)
            # XXX: should there be an else here? Last modified works without extra headers.
            #      Are there other config options?

        # Do the maxage/smaxage settings allow for proxy caching?
        proxyCache = smaxage or (maxage and smaxage is None)

        setCacheHeaders(self.published, self.request, response, maxage=maxage, smaxage=smaxage,
            etag=etag, lastModified=lastModified, vary=vary)
Esempio n. 2
0
    def modifyResponse(self, rulename, response, class_=None):
        options = lookupOptions(class_ or self.__class__, rulename)

        maxage = options.get("maxage", self.maxage)
        smaxage = options.get("smaxage", self.smaxage)
        etags = options.get("etags") or self.etags

        anonOnly = options.get("anonOnly", self.anonOnly)
        ramCache = options.get("ramCache", self.ramCache)
        vary = options.get("vary", self.vary)

        # Add the ``anonymousOrRandom`` etag if we are anonymous only
        if anonOnly:
            if etags is None:
                etags = ["anonymousOrRandom"]
            elif "anonymousOrRandom" not in etags:
                etags = tuple(etags) + ("anonymousOrRandom",)

        etag = getETagAnnotation(self.published, self.request, etags)
        lastModified = getLastModifiedAnnotation(self.published, self.request, options["lastModified"])

        # Check for cache stop request variables
        if cacheStop(self.request, rulename):
            # only stop with etags if configured
            if etags:
                etag = "%s%d" % (time.time(), random.randint(0, 1000))
                return setCacheHeaders(self.published, self.request, response, etag=etag)
            # XXX: should there be an else here? Last modified works without extra headers.
            #      Are there other config options?

        # Do the maxage/smaxage settings allow for proxy caching?
        proxyCache = smaxage or (maxage and smaxage is None)

        # Check if the content can be cached in shared caches
        public = True
        if ramCache or proxyCache:
            if etags is not None:
                if "userid" in etags or "anonymousOrRandom" in etags or "roles" in etags:
                    context = getContext(self.published)
                    portal_state = getMultiAdapter((context, self.request), name=u"plone_portal_state")
                    public = portal_state.anonymous()
            public = public and visibleToRole(self.published, role="Anonymous")

        if proxyCache and not public:
            # This is private so keep it out of both shared and browser caches
            maxage = smaxage = 0

        setCacheHeaders(
            self.published,
            self.request,
            response,
            maxage=maxage,
            smaxage=smaxage,
            etag=etag,
            lastModified=lastModified,
            vary=vary,
        )

        if ramCache and public:
            cacheInRAM(self.published, self.request, response, etag=etag, lastModified=lastModified)
Esempio n. 3
0
    def test_lookupOptions_named(self):
        provideUtility(Registry(), IRegistry)
        registry = getUtility(IRegistry)

        registry.records['plone.caching.tests.test2'] = Record(
            field.TextLine(),
            u'foo'
        )

        @provider(ICachingOperationType)
        class DummyOperation(object):

            title = u''
            description = u''
            prefix = 'plone.caching.tests'
            options = ('test1', 'test2',)

        provideUtility(DummyOperation, name=u'plone.caching.tests')

        result = lookupOptions(
            u'plone.caching.tests',
            'testrule',
            default=_marker
        )
        self.assertEqual({'test1': _marker, 'test2': u'foo'}, result)
Esempio n. 4
0
    def interceptResponse(self, rulename, response, class_=None):
        result = super(PatchedCachingMixin,
                       self).interceptResponse(rulename, response, class_)
        if result != "":
            # "" is the result of a 304 NOT MODIFIED
            return result

        options = lookupOptions(class_ or self.__class__, rulename)
        maxage = options.get("maxage", self.maxage)
        smaxage = options.get("smaxage", self.smaxage)

        if maxage:
            if smaxage is not None:
                maxage = f"{maxage}, s-maxage={smaxage}"
            response.setHeader(
                "Cache-Control",
                f"max-age={maxage}, proxy-revalidate, public",
            )
        elif smaxage:
            response.setHeader(
                "Cache-Control",
                f"max-age=0, s-maxage={smaxage}, must-revalidate",
            )
        else:
            response.setHeader("Cache-Control",
                               "max-age=0, must-revalidate, private")

        return ""
 def interceptResponse(self, rulename, response, class_=None):
     options = lookupOptions(class_ or self.__class__, rulename)
     hostname = getHostname(self.request)
     if hostname in options.get('hostnames_nocache',
                                self.hostnames_nocache):
         return None
     return super(BaseHostnameCaching, self).interceptResponse(rulename,
                                                               response,
                                                               class_=None)
Esempio n. 6
0
    def modifyResponse(self, rulename, response, class_=None):
        options = lookupOptions(class_ or self.__class__, rulename)

        maxage   = options.get('maxage') or self.maxage
        smaxage  = options.get('smaxage') or self.smaxage
        etags    = options.get('etags') or self.etags

        anonOnly = options.get('anonOnly', self.anonOnly)
        ramCache = options.get('ramCache', self.ramCache)
        vary     = options.get('vary', self.vary)

        # Add the ``anonymousOrRandom`` etag if we are anonymous only
        if anonOnly:
            if etags is None:
                etags = ['anonymousOrRandom']
            elif 'anonymousOrRandom' not in etags:
                etags = tuple(etags) + ('anonymousOrRandom',)

        etag = getETagAnnotation(self.published, self.request, etags)
        lastModified = getLastModifiedAnnotation(self.published, self.request, options['lastModified'])

        # Check for cache stop request variables
        if cacheStop(self.request, rulename):
            # only stop with etags if configured
            if etags:
                etag = "%s%d" % (time.time(), random.randint(0, 1000))
                return setCacheHeaders(self.published, self.request, response, etag=etag)
            # XXX: should there be an else here? Last modified works without extra headers.
            #      Are there other config options?

        # Do the maxage/smaxage settings allow for proxy caching?
        proxyCache = smaxage or (maxage and smaxage is None)

        # Check if the content can be cached in shared caches
        public = True
        if ramCache or proxyCache:
            if etags is not None:
                if 'userid' in etags or 'anonymousOrRandom' in etags or 'roles' in etags:
                    context = getContext(self.published)
                    portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state')
                    public = portal_state.anonymous()
            public = public and visibleToRole(self.published, role='Anonymous')

        if proxyCache and not public:
            # This is private so keep it out of proxy caches
            if maxage == 0:
                # maxage is zero so just omit smaxage
                smaxage=None
            else:
                # maxage is missing or non-zero so expire smaxage
                smaxage=0

        setCacheHeaders(self.published, self.request, response, maxage=maxage, smaxage=smaxage,
            etag=etag, lastModified=lastModified, vary=vary)

        if ramCache and public:
            cacheInRAM(self.published, self.request, response, etag=etag, lastModified=lastModified)
 def modifyResponse(self, rulename, response, class_=None):
     options = lookupOptions(class_ or self.__class__, rulename)
     hostname = getHostname(self.request)
     if hostname in options.get('hostnames_nocache',
                                self.hostnames_nocache):
         doNotCache(self.published, self.request, response)
     else:
         return super(BaseHostnameCaching, self).modifyResponse(rulename,
                                                                response,
                                                                class_=None)
Esempio n. 8
0
    def test_lookupOptions_no_registry(self):

        @provider(ICachingOperationType)
        class DummyOperation(object):

            title = u''
            description = u''
            prefix = 'plone.caching.tests'
            options = ('test1', 'test2',)

        result = lookupOptions(DummyOperation, 'testrule', default=_marker)
        self.assertEqual({'test1': _marker, 'test2': _marker}, result)
Esempio n. 9
0
    def test_lookupOptions_no_records(self):
        provideUtility(Registry(), IRegistry)

        class DummyOperation(object):
            classProvides(ICachingOperationType)

            title = u""
            description = u""
            prefix = 'plone.caching.tests'
            options = ('test1', 'test2',)

        result = lookupOptions(DummyOperation, 'testrule', default=_marker)
        self.assertEquals({'test1': _marker, 'test2': _marker}, result)
Esempio n. 10
0
    def interceptResponse(self, rulename, response, class_=None):
        options = lookupOptions(class_ or self.__class__, rulename)

        etags = options.get('etags') or self.etags
        anonOnly = options.get('anonOnly', self.anonOnly)
        ramCache = options.get('ramCache', self.ramCache)
        lastModified = options.get('lastModified', self.lastModified)

        # Add the ``anonymousOrRandom`` etag if we are anonymous only
        if anonOnly:
            if etags is None:
                etags = ['anonymousOrRandom']
            elif 'anonymousOrRandom' not in etags:
                etags = tuple(etags) + ('anonymousOrRandom',)

        etag = getETagAnnotation(self.published, self.request, keys=etags)
        lastModified = getLastModifiedAnnotation(
            self.published, self.request, lastModified=lastModified)

        # Check for cache stop request variables
        if cacheStop(self.request, rulename):
            return None

        # Check if this should be a 304 response
        if not isModified(self.request, etag=etag, lastModified=lastModified):
            return notModified(
                self.published,
                self.request,
                response,
                etag=etag,
                lastModified=lastModified
            )

        # Check if this is in the ram cache
        if ramCache:
            context = getContext(self.published)
            portal_state = getMultiAdapter(
                (context, self.request), name=u'plone_portal_state')

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

        return None
Esempio n. 11
0
    def test_lookupOptions_no_registry(self):
        @provider(ICachingOperationType)
        class DummyOperation(object):

            title = u''
            description = u''
            prefix = 'plone.caching.tests'
            options = (
                'test1',
                'test2',
            )

        result = lookupOptions(DummyOperation, 'testrule', default=_marker)
        self.assertEqual({'test1': _marker, 'test2': _marker}, result)
Esempio n. 12
0
    def interceptResponse(self, rulename, response, class_=None):
        options = lookupOptions(class_ or self.__class__, rulename)

        etags = options.get('etags') or self.etags
        anonOnly = options.get('anonOnly', self.anonOnly)
        ramCache = options.get('ramCache', self.ramCache)
        lastModified = options.get('lastModified', self.lastModified)

        # Add the ``anonymousOrRandom`` etag if we are anonymous only
        if anonOnly:
            if etags is None:
                etags = ['anonymousOrRandom']
            elif 'anonymousOrRandom' not in etags:
                etags = tuple(etags) + ('anonymousOrRandom', )

        etag = getETagAnnotation(self.published, self.request, keys=etags)
        lastModified = getLastModifiedAnnotation(self.published,
                                                 self.request,
                                                 lastModified=lastModified)

        # Check for cache stop request variables
        if cacheStop(self.request, rulename):
            return None

        # Check if this should be a 304 response
        if not isModified(self.request, etag=etag, lastModified=lastModified):
            return notModified(
                self.published,
                self.request,
                response,
                etag=etag,
                lastModified=lastModified,
            )

        # Check if this is in the ram cache
        if ramCache:
            context = getContext(self.published)
            portal_state = getMultiAdapter((context, self.request),
                                           name=u'plone_portal_state')

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

        return None
Esempio n. 13
0
    def test_lookupOptions_no_records(self):
        provideUtility(Registry(), IRegistry)

        class DummyOperation(object):
            classProvides(ICachingOperationType)

            title = u""
            description = u""
            prefix = 'plone.caching.tests'
            options = (
                'test1',
                'test2',
            )

        result = lookupOptions(DummyOperation, 'testrule', default=_marker)
        self.assertEquals({'test1': _marker, 'test2': _marker}, result)
Esempio n. 14
0
    def test_lookupOptions_default(self):
        provideUtility(Registry(), IRegistry)
        registry = getUtility(IRegistry)

        registry.records['plone.caching.tests.test2'] = Record(field.TextLine(), u"foo")

        class DummyOperation(object):
            classProvides(ICachingOperationType)

            title = u""
            description = u""
            prefix = 'plone.caching.tests'
            options = ('test1', 'test2',)

        result = lookupOptions(DummyOperation, 'testrule', default=_marker)
        self.assertEquals({'test1': _marker, 'test2': u"foo"}, result)
Esempio n. 15
0
    def modifyResponse(self, rulename, response):
        options = lookupOptions(self.__class__, rulename)
        
        chained = []
        
        if options['operations']:
            for name in options['operations']:
                
                operation = queryMultiAdapter((self.published, self.request),
                                             ICachingOperation, name=name)
                
                if operation is not None:
                    chained.append(name)
                    operation.modifyResponse(rulename, response)

        if chained:
            response.setHeader('X-Cache-Chain-Operations', '; '.join(chained))
Esempio n. 16
0
    def modifyResponse(self, rulename, response):
        options = lookupOptions(self.__class__, rulename)

        chained = []

        if options['operations']:
            for name in options['operations']:

                operation = queryMultiAdapter((self.published, self.request),
                                              ICachingOperation,
                                              name=name)

                if operation is not None:
                    chained.append(name)
                    operation.modifyResponse(rulename, response)

        if chained:
            response.setHeader('X-Cache-Chain-Operations', '; '.join(chained))
Esempio n. 17
0
    def test_lookupOptions_default(self):
        provideUtility(Registry(), IRegistry)
        registry = getUtility(IRegistry)

        registry.records['plone.caching.tests.test2'] = Record(
            field.TextLine(), u'foo')

        @provider(ICachingOperationType)
        class DummyOperation(object):

            title = u''
            description = u''
            prefix = 'plone.caching.tests'
            options = (
                'test1',
                'test2',
            )

        result = lookupOptions(DummyOperation, 'testrule', default=_marker)
        self.assertEqual({'test1': _marker, 'test2': u'foo'}, result)
Esempio n. 18
0
    def test_lookupOptions_named(self):
        provideUtility(Registry(), IRegistry)
        registry = getUtility(IRegistry)

        registry.records['plone.caching.tests.test2'] = Record(
            field.TextLine(), u"foo")

        class DummyOperation(object):
            classProvides(ICachingOperationType)

            title = u""
            description = u""
            prefix = 'plone.caching.tests'
            options = (
                'test1',
                'test2',
            )

        provideUtility(DummyOperation, name=u"plone.caching.tests")

        result = lookupOptions(u"plone.caching.tests",
                               'testrule',
                               default=_marker)
        self.assertEquals({'test1': _marker, 'test2': u"foo"}, result)
Esempio n. 19
0
    def modifyResponse(self, rulename, response, class_=None):
        options = lookupOptions(class_ or self.__class__, rulename)

        maxage = options.get('maxage', self.maxage)
        smaxage = options.get('smaxage', self.smaxage)
        etags = options.get('etags') or self.etags

        anonOnly = options.get('anonOnly', self.anonOnly)
        ramCache = options.get('ramCache', self.ramCache)
        vary = options.get('vary', self.vary)

        # Add the ``anonymousOrRandom`` etag if we are anonymous only
        if anonOnly:
            if etags is None:
                etags = ['anonymousOrRandom']
            elif 'anonymousOrRandom' not in etags:
                etags = tuple(etags) + ('anonymousOrRandom', )

        etag = getETagAnnotation(self.published, self.request, etags)
        lastModified = getLastModifiedAnnotation(self.published, self.request,
                                                 options['lastModified'])

        # Check for cache stop request variables
        if cacheStop(self.request, rulename):
            # only stop with etags if configured
            if etags:
                etag = "%s%d" % (time.time(), random.randint(0, 1000))
                return setCacheHeaders(self.published,
                                       self.request,
                                       response,
                                       etag=etag)
            # XXX: should there be an else here? Last modified works without extra headers.
            #      Are there other config options?

        # Do the maxage/smaxage settings allow for proxy caching?
        proxyCache = smaxage or (maxage and smaxage is None)

        # Check if the content can be cached in shared caches
        public = True
        if ramCache or proxyCache:
            if etags is not None:
                if 'userid' in etags or 'anonymousOrRandom' in etags or 'roles' in etags:
                    context = getContext(self.published)
                    portal_state = getMultiAdapter((context, self.request),
                                                   name=u'plone_portal_state')
                    public = portal_state.anonymous()
            public = public and visibleToRole(self.published, role='Anonymous')

        if proxyCache and not public:
            # This is private so keep it out of both shared and browser caches
            maxage = smaxage = 0

        setCacheHeaders(self.published,
                        self.request,
                        response,
                        maxage=maxage,
                        smaxage=smaxage,
                        etag=etag,
                        lastModified=lastModified,
                        vary=vary)

        if ramCache and public:
            cacheInRAM(self.published,
                       self.request,
                       response,
                       etag=etag,
                       lastModified=lastModified)