Index: docs/cache.txt
===================================================================
--- docs/cache.txt	(revision 6594)
+++ docs/cache.txt	(working copy)
@@ -263,6 +263,18 @@
 
 .. _`middleware documentation`: ../middleware/
 
+**New in Django development version**
+
+If the view sets its own cache expiry time (i.e. has a ``max-age`` section in
+it's ``Cache-Control`` header) then the page will be cached for the length of
+time given in there, rather than ``CACHE_MIDDLEWARE_SECONDS``. Using the
+decorators in ``django.views.decorators.cache`` you can easily set a view's
+expiry time (by using the ``cache_control`` decorator) or disable caching for a
+view (by using the ``never_cache`` decorator). See the `using other headers`__
+section for more on these decorators.
+
+__ `Controlling cache: Using other headers`_ 
+
 The per-view cache
 ==================
 
@@ -564,7 +576,7 @@
 precedence, and the header values will be merged correctly.)
 
 If you want to use headers to disable caching altogether,
-``django.views.decorators.never_cache`` is a view decorator that adds
+``django.views.decorators.cache.never_cache`` is a view decorator that adds
 headers to ensure the response won't be cached by browsers or other caches. Example::
 
     from django.views.decorators.cache import never_cache
Index: django/utils/cache.py
===================================================================
--- django/utils/cache.py	(revision 6594)
+++ django/utils/cache.py	(working copy)
@@ -69,6 +69,27 @@
     cc = ', '.join([dictvalue(el) for el in cc.items()])
     response['Cache-Control'] = cc
 
+def get_max_age(response):
+    """
+    Returns the max-age from the response Cache-Control header as an integer (or
+    ``None`` if it wasn't found or wasn't an integer.
+    """
+    def dictitem(s):
+        t = s.split('=',1)
+        if len(t) > 1:
+            return (t[0].lower(), t[1])
+        else:
+            return (t[0].lower(), True)
+    if response.has_header('Cache-Control'):
+        cc = cc_delim_re.split(response['Cache-Control'])
+        cc = dict([dictitem(el) for el in cc])
+        if 'max-age' in cc:
+            try:
+                return int(cc['max-age'])
+            except ValueError, TypeError:
+                pass
+    return None
+
 vary_delim_re = re.compile(r',\s*')
 
 def patch_response_headers(response, cache_timeout=None):
Index: django/middleware/cache.py
===================================================================
--- django/middleware/cache.py	(revision 6594)
+++ django/middleware/cache.py	(working copy)
@@ -1,14 +1,18 @@
 from django.conf import settings
 from django.core.cache import cache
-from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers
+from django.utils.cache import get_cache_key, learn_cache_key, patch_response_headers, get_max_age
 
 class CacheMiddleware(object):
     """
     Cache middleware. If this is enabled, each Django-powered page will be
-    cached for CACHE_MIDDLEWARE_SECONDS seconds. Cache is based on URLs.
+    cached (based on URLs).
 
     Only parameter-less GET or HEAD-requests with status code 200 are cached.
 
+    The number of seconds each page is stored for is set by the
+    "max-age" section of the response's "Cache-Control" header, falling back to
+    the CACHE_MIDDLEWARE_SECONDS setting if the section was not found.
+
     If CACHE_MIDDLEWARE_ANONYMOUS_ONLY is set to True, only anonymous requests
     (i.e., those not made by a logged-in user) will be cached. This is a
     simple and effective way of avoiding the caching of the Django admin (and
@@ -78,7 +82,16 @@
             return response
         if not response.status_code == 200:
             return response
-        patch_response_headers(response, self.cache_timeout)
-        cache_key = learn_cache_key(request, response, self.cache_timeout, self.key_prefix)
-        cache.set(cache_key, response, self.cache_timeout)
+        # Try to get the timeout from the "max-age" section of the "Cache-
+        # Control" header before reverting to using the default cache_timeout
+        # length.
+        timeout = get_max_age(response)
+        if timeout == None:
+            timeout = self.cache_timeout
+        elif timeout == 0:
+            # max-age was set to 0, don't bother caching.
+            return response
+        patch_response_headers(response, timeout)
+        cache_key = learn_cache_key(request, response, timeout, self.key_prefix)
+        cache.set(cache_key, response, timeout)
         return response
