From e573d4356ed0371f5ba34ff3ff396fefd2e55913 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 20:56:53 -0400 Subject: - New environment setting ``PYRAMID_PREVENT_HTTP_CACHE`` and new configuration file value ``prevent_http_cache``. These are synomymous and allow you to prevent HTTP cache headers from being set by Pyramid's ``http_cache`` machinery globally in a process. see the "Influencing HTTP Caching" section of the "View Configuration" narrative chapter and the detailed documentation for this setting in the "Environment Variables and Configuration Settings" narrative chapter. - New documentation section in View Configuration narrative chapter: "Influencing HTTP Caching". --- CHANGES.txt | 14 ++++++++++++ docs/narr/environment.rst | 19 ++++++++++++++++ docs/narr/viewconfig.rst | 50 ++++++++++++++++++++++++++++++++++++++++++ docs/whatsnew-1.1.rst | 6 +++++ pyramid/config.py | 8 +++++-- pyramid/settings.py | 7 +++++- pyramid/tests/test_config.py | 15 +++++++++++++ pyramid/tests/test_settings.py | 15 +++++++++++++ 8 files changed, 131 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index fd11a16d1..ea83827cc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,17 @@ Next Release ============ +Features +-------- + +- New environment setting ``PYRAMID_PREVENT_HTTP_CACHE`` and new + configuration file value ``prevent_http_cache``. These are synomymous and + allow you to prevent HTTP cache headers from being set by Pyramid's + ``http_cache`` machinery globally in a process. see the "Influencing HTTP + Caching" section of the "View Configuration" narrative chapter and the + detailed documentation for this setting in the "Environment Variables and + Configuration Settings" narrative chapter. + Behavior Changes ---------------- @@ -41,6 +52,9 @@ Documentation match the ``pyramid_routesalchemy`` scaffold function of the same name; it didn't get synchronized when it was changed in the scaffold. +- New documentation section in View Configuration narrative chapter: + "Influencing HTTP Caching". + 1.1b1 (2011-07-10) ================== diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index a57b316e1..7f8e3953d 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -117,6 +117,25 @@ this value is true. See also :ref:`debug_routematch_section`. | | | +---------------------------------+-----------------------------+ +.. _preventing_http_caching: + +Preventing HTTP Caching +------------------------ + +Prevent the ``http_cache`` view configuration argument from having any effect +globally in this process when this value is true. No http caching-related +response headers will be set by the Pyramid ``http_cache`` view configuration +feature when this is true. See also :ref:`influencing_http_caching`. + ++---------------------------------+-----------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+=============================+ +| ``PYRAMID_PREVENT_HTTP_CACHE`` | ``prevent_http_cache`` | +| | | +| | | +| | | ++---------------------------------+-----------------------------+ + Debugging All ------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 326d97506..1ef40e89f 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -82,6 +82,8 @@ being invoked due to an authorization policy. The presence of non-predicate arguments in a view configuration does not narrow the circumstances in which the view callable will be invoked. +.. _nonpredicate_view_args: + Non-Predicate Arguments +++++++++++++++++++++++ @@ -767,6 +769,54 @@ found will be printed to ``stderr``, and the browser representation of the error will include the same information. See :ref:`environment_chapter` for more information about how, and where to set these values. +.. index:: + single: HTTP caching + +.. _influencing_http_caching: + +Influencing HTTP Caching +------------------------ + +.. note:: This feature is new in Pyramid 1.1. + +When a non-``None`` ``http_cache`` argument is passed to a view +configuration, Pyramid will set ``Expires`` and ``Cache-Control`` response +headers in the resulting response, causing browsers to cache the response +data for some time. See ``http_cache`` in :ref:`nonpredicate_view_args` for +the its allowable values and what they mean. + +Sometimes it's undesirable to have these headers set as the result of +returning a response from a view, even though you'd like to decorate the view +with a view configuration decorator that has ``http_cache``. Perhaps there's +an alternate branch in your view code that returns a response that should +never be cacheable, while the "normal" branch returns something that should +always be cacheable. If this is the case, set the ``prevent_auto`` attribute +of the ``response.cache_control`` object to a non-``False`` value. For +example, the below view callable is configured with a ``@view_config`` +decorator that indicates any response from the view should be cached for 3600 +seconds. However, the view itself prevents caching from taking place unless +there's a ``should_cache`` GET or POST variable: + +.. code-block:: python + + from pyramid.view import view_config + + @view_config(http_cache=3600) + def view(request): + response = Response() + if not 'should_cache' in request.params: + response.cache_control.prevent_auto = True + return response + +Note that the ``http_cache`` machinery will overwrite or add to caching +headers you set within the view itself unless you use ``preserve_auto``. + +You can also turn of the effect of ``http_cache`` entirely for the duration +of a Pyramid application lifetime. To do so, set the +``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the +``prevent_http_cache`` configuration value setting to a true value. For more +information, see :ref:`preventing_http_caching`. + .. index:: pair: matching views; printing single: paster pviews diff --git a/docs/whatsnew-1.1.rst b/docs/whatsnew-1.1.rst index b55b30238..20b346090 100644 --- a/docs/whatsnew-1.1.rst +++ b/docs/whatsnew-1.1.rst @@ -167,6 +167,12 @@ Minor Feature Additions to only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` with the first element of ``None``, e.g.: ``(None, {'public':True})``. + The environment setting ``PYRAMID_PREVENT_HTTP_CACHE`` and configuration + file value ``prevent_http_cache`` are synomymous and allow you to prevent + HTTP cache headers from being set by Pyramid's ``http_cache`` machinery + globally in a process. see :ref:`influencing_http_caching` and + :ref:`preventing_http_caching`. + - A `JSONP `_ renderer. See :ref:`jsonp_renderer` for more details. diff --git a/pyramid/config.py b/pyramid/config.py index 6efb6c00e..44ce5110e 100644 --- a/pyramid/config.py +++ b/pyramid/config.py @@ -2970,6 +2970,9 @@ class ViewDeriver(object): @wraps_view def http_cached_view(self, view): + if self.registry.settings.get('prevent_http_cache', False): + return view + seconds = self.kw.get('http_cache') if seconds is None: @@ -2987,8 +2990,9 @@ class ViewDeriver(object): def wrapper(context, request): response = view(context, request) - cache_control = response.cache_control - if not hasattr(cache_control, 'prevent_auto'): + prevent_caching = getattr(response.cache_control, 'prevent_auto', + False) + if not prevent_caching: response.cache_expires(seconds, **options) return response diff --git a/pyramid/settings.py b/pyramid/settings.py index edea9ce99..7ba53ea4c 100644 --- a/pyramid/settings.py +++ b/pyramid/settings.py @@ -48,7 +48,11 @@ class Settings(dict): eff_reload_assets = reload_assets or reload_resources locale_name = self.get('default_locale_name', 'en') eff_locale_name = eget('PYRAMID_DEFAULT_LOCALE_NAME', locale_name) - + + config_prevent_http_cache = self.get('prevent_http_cache', '') + eff_prevent_http_cache = asbool(eget('PYRAMID_PREVENT_HTTP_CACHE', + config_prevent_http_cache)) + update = { 'debug_authorization': eff_debug_all or eff_debug_auth, 'debug_notfound': eff_debug_all or eff_debug_notfound, @@ -58,6 +62,7 @@ class Settings(dict): 'reload_resources':eff_reload_all or eff_reload_assets, 'reload_assets':eff_reload_all or eff_reload_assets, 'default_locale_name':eff_locale_name, + 'prevent_http_cache':eff_prevent_http_cache, } self.update(update) diff --git a/pyramid/tests/test_config.py b/pyramid/tests/test_config.py index 84848c2ad..002eab8e8 100644 --- a/pyramid/tests/test_config.py +++ b/pyramid/tests/test_config.py @@ -4340,6 +4340,21 @@ class TestViewDeriver(unittest.TestCase): self.assertFalse('Expires' in headers) self.assertFalse('Cache-Control' in headers) + def test_http_cached_prevent_http_cache_in_settings(self): + self.config.registry.settings['prevent_http_cache'] = True + from pyramid.response import Response + response = Response() + def inner_view(context, request): + return response + deriver = self._makeOne(http_cache=3600) + result = deriver(inner_view) + request = self._makeRequest() + result = result(None, request) + self.assertEqual(result, response) + headers = dict(result.headerlist) + self.assertFalse('Expires' in headers) + self.assertFalse('Cache-Control' in headers) + def test_http_cached_view_bad_tuple(self): from pyramid.exceptions import ConfigurationError deriver = self._makeOne(http_cache=(None,)) diff --git a/pyramid/tests/test_settings.py b/pyramid/tests/test_settings.py index a444539e0..75d653133 100644 --- a/pyramid/tests/test_settings.py +++ b/pyramid/tests/test_settings.py @@ -28,6 +28,21 @@ class TestSettings(unittest.TestCase): self.assertEqual(settings['reload_templates'], False) self.assertEqual(settings['reload_resources'], False) + def test_prevent_http_cache(self): + settings = self._makeOne({}) + self.assertEqual(settings['prevent_http_cache'], False) + result = self._makeOne({'prevent_http_cache':'false'}) + self.assertEqual(result['prevent_http_cache'], False) + result = self._makeOne({'prevent_http_cache':'t'}) + self.assertEqual(result['prevent_http_cache'], True) + result = self._makeOne({'prevent_http_cache':'1'}) + self.assertEqual(result['prevent_http_cache'], True) + result = self._makeOne({}, {'PYRAMID_PREVENT_HTTP_CACHE':'1'}) + self.assertEqual(result['prevent_http_cache'], True) + result = self._makeOne({'prevent_http_cache':'false'}, + {'PYRAMID_PREVENT_HTTP_CACHE':'1'}) + self.assertEqual(result['prevent_http_cache'], True) + def test_reload_templates(self): settings = self._makeOne({}) self.assertEqual(settings['reload_templates'], False) -- cgit v1.2.3