Index: django/middleware/cache.py
===================================================================
--- django/middleware/cache.py	(revision 14359)
+++ django/middleware/cache.py	(working copy)
@@ -34,8 +34,8 @@
   and effective way of avoiding the caching of the Django admin (and any other
   user-specific content).
 
-* This middleware expects that a HEAD request is answered with a response
-  exactly like the corresponding GET request.
+* This middleware expects that a HEAD request is answered with the same response
+  headers exactly like the corresponding GET request.
 
 * When a hit occurs, a shallow copy of the original response object is returned
   from process_request.
@@ -71,12 +71,6 @@
         if not hasattr(request, '_cache_update_cache') or not request._cache_update_cache:
             # We don't need to update the cache, just return.
             return response
-        if request.method != 'GET':
-            # This is a stronger requirement than above. It is needed
-            # because of interactions between this middleware and the
-            # HTTPMiddleware, which throws the body of a HEAD-request
-            # away before this middleware gets a chance to cache it.
-            return response
         if not response.status_code == 200:
             return response
         # Try to get the timeout from the "max-age" section of the "Cache-
@@ -90,7 +84,7 @@
             return response
         patch_response_headers(response, timeout)
         if timeout:
-            cache_key = learn_cache_key(request, response, timeout, self.key_prefix)
+            cache_key = learn_cache_key(request, response, timeout, '%s.%s' % (self.key_prefix, request.method))
             cache.set(cache_key, response, timeout)
         return response
 
@@ -123,19 +117,25 @@
             request._cache_update_cache = False
             return None # Don't cache requests from authenticated users.
 
-        cache_key = get_cache_key(request, self.key_prefix)
-        if cache_key is None:
-            request._cache_update_cache = True
-            return None # No cache information available, need to rebuild.
+        possible_cache_keys = [get_cache_key(request, '%s.%s' % (self.key_prefix, request.method))]
 
-        response = cache.get(cache_key, None)
-        if response is None:
-            request._cache_update_cache = True
-            return None # No cache information available, need to rebuild.
+        if request.method == 'HEAD':
+            possible_cache_keys.append(get_cache_key(request, '%s.%s' % (self.key_prefix, 'GET')))
 
-        request._cache_update_cache = False
-        return response
+        for cache_key in possible_cache_keys:
+            if cache_key is None:
+                continue # Check another cache key.
 
+            response = cache.get(cache_key, None)
+            if response is None:
+                continue # Check another cache key.
+
+            request._cache_update_cache = False
+            return response
+
+        request.cache_update_cache = True
+        return None # No cache information available, need to rebuild.
+
 class CacheMiddleware(UpdateCacheMiddleware, FetchFromCacheMiddleware):
     """
     Cache middleware that provides basic behavior for many simple sites.
Index: tests/regressiontests/cache/tests.py
===================================================================
--- tests/regressiontests/cache/tests.py	(revision 14359)
+++ tests/regressiontests/cache/tests.py	(working copy)
@@ -557,6 +557,64 @@
         learn_cache_key(request, response)
         self.assertEqual(get_cache_key(request), 'views.decorators.cache.cache_page.settingsprefix.a8c87a3d8c44853d7f79474f7ffe4ad5.d41d8cd98f00b204e9800998ecf8427e')
 
+class CacheHEADTest(unittest.TestCase):
+
+    def setUp(self):
+        self.orig_cache_middleware_seconds = settings.CACHE_MIDDLEWARE_SECONDS
+        self.orig_cache_middleware_key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
+        self.orig_cache_backend = settings.CACHE_BACKEND
+        settings.CACHE_MIDDLEWARE_SECONDS = 60
+        settings.CACHE_MIDDLEWARE_KEY_PREFIX = 'test'
+        settings.CACHE_BACKEND = 'locmem:///'
+        self.path = '/cache/test/'
+
+    def tearDown(self):
+        settings.CACHE_MIDDLEWARE_SECONDS = self.orig_cache_middleware_seconds
+        settings.CACHE_MIDDLEWARE_KEY_PREFIX = self.orig_cache_middleware_key_prefix
+        settings.CACHE_BACKEND = self.orig_cache_backend
+
+    def _get_request(self, method):
+        request = HttpRequest()
+        request.META = {
+            'SERVER_NAME': 'testserver',
+            'SERVER_PORT': 80,
+        }
+        request.method = method
+        request.path = request.path_info = self.path
+        return request
+
+    def _get_request_cache(self, method):
+        request = self._get_request(method)
+        request._cache_update_cache = True
+        return request
+
+    def _set_cache(self, request, msg):
+        response = HttpResponse()
+        response.content = msg
+        return UpdateCacheMiddleware().process_response(request, response)
+
+    def test_head_caches_correctly(self):
+        test_content = 'test content'
+
+        request = self._get_request_cache('HEAD')
+        self._set_cache(request, test_content)
+
+        request = self._get_request('HEAD')
+        get_cache_data = FetchFromCacheMiddleware().process_request(request)
+        self.assertNotEqual(get_cache_data, None)
+        self.assertEqual(test_content, get_cache_data.content)
+
+    def test_head_with_cached_get(self):
+        test_content = 'test content'
+
+        request = self._get_request_cache('GET')
+        self._set_cache(request, test_content)
+
+        request = self._get_request('HEAD')
+        get_cache_data = FetchFromCacheMiddleware().process_request(request)
+        self.assertNotEqual(get_cache_data, None)
+        self.assertEqual(test_content, get_cache_data.content)
+
 class CacheI18nTest(unittest.TestCase):
 
     def setUp(self):
Index: docs/topics/cache.txt
===================================================================
--- docs/topics/cache.txt	(revision 14359)
+++ docs/topics/cache.txt	(working copy)
@@ -328,7 +328,9 @@
 will be cached. This is a simple and effective way of disabling caching for any
 user-specific pages (include Django's admin interface). Note that if you use
 ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY``, you should make sure you've activated
-``AuthenticationMiddleware``.
+``AuthenticationMiddleware``. The cache middleware expects that a HEAD request
+is answered with the same response headers exactly like the corresponding GET
+request, in that case it could return cached GET response for HEAD request.
 
 Additionally, the cache middleware automatically sets a few headers in each
 ``HttpResponse``:
