Add support for Vary header
diff --git a/python2/httplib2/__init__.py b/python2/httplib2/__init__.py
index 7980ca7..d2abdb4 100644
--- a/python2/httplib2/__init__.py
+++ b/python2/httplib2/__init__.py
@@ -370,6 +370,18 @@
                 if key not in ['status','content-encoding','transfer-encoding']:
                     info[key] = value
 
+            # Add annotations to the cache to indicate what headers
+            # are variant for this request.
+            vary = response_headers.get('vary', None)
+            if vary:
+                vary_headers = vary.lower().replace(' ', '').split(',')
+                for header in vary_headers:
+                    key = '-varied-%s' % header
+                    try:
+                        info[key] = request_headers[header]
+                    except KeyError:
+                        pass
+
             status = response_headers.status
             if status == 304:
                 status = 200
@@ -1036,6 +1048,18 @@
                 # RFC 2616 Section 13.10
                 self.cache.delete(cachekey)
 
+            # Check the vary header in the cache to see if this request
+            # matches what varies in the cache.
+            if method in ['GET', 'HEAD'] and 'vary' in info:
+                vary = info['vary']
+                vary_headers = vary.lower().replace(' ', '').split(',')
+                for header in vary_headers:
+                    key = '-varied-%s' % header
+                    value = info[key]
+                    if headers.get(header, '') != value:
+                            cached_value = None
+                            break
+
             if cached_value and method in ["GET", "HEAD"] and self.cache and 'range' not in headers:
                 if info.has_key('-x-permanent-redirect-url'):
                     # Should cached permanent redirects be counted in our redirection count? For now, yes.
diff --git a/python2/httplib2test.py b/python2/httplib2test.py
index 5bab45e..3bfde31 100755
--- a/python2/httplib2test.py
+++ b/python2/httplib2test.py
@@ -573,6 +573,77 @@
         (response, content) = self.http.request(uri, "GET")
         self.assertEqual(response.status, 410)
 
+    def testVaryHeaderSimple(self):
+        """
+        RFC 2616 13.6
+        When the cache receives a subsequent request whose Request-URI
+        specifies one or more cache entries including a Vary header field,
+        the cache MUST NOT use such a cache entry to construct a response
+        to the new request unless all of the selecting request-headers
+        present in the new request match the corresponding stored
+        request-headers in the original request.
+        """
+        # test that the vary header is sent
+        uri = urlparse.urljoin(base, "vary/accept.asis")
+        (response, content) = self.http.request(uri, "GET", headers={'Accept': 'text/plain'})
+        self.assertEqual(response.status, 200)
+        self.assertTrue(response.has_key('vary'))
+
+        # get the resource again, from the cache since accept header in this
+        # request is the same as the request
+        (response, content) = self.http.request(uri, "GET", headers={'Accept': 'text/plain'})
+        self.assertEqual(response.status, 200)
+        self.assertEqual(response.fromcache, True, msg="Should be from cache")
+
+        # get the resource again, not from cache since Accept headers does not match
+        (response, content) = self.http.request(uri, "GET", headers={'Accept': 'text/html'})
+        self.assertEqual(response.status, 200)
+        self.assertEqual(response.fromcache, False, msg="Should not be from cache")
+
+        # get the resource again, without any Accept header, so again no match
+        (response, content) = self.http.request(uri, "GET")
+        self.assertEqual(response.status, 200)
+        self.assertEqual(response.fromcache, False, msg="Should not be from cache")
+
+    def testNoVary(self):
+        # when there is no vary, a different Accept header (e.g.) should not
+        # impact if the cache is used
+        # test that the vary header is not sent
+        uri = urlparse.urljoin(base, "vary/no-vary.asis")
+        (response, content) = self.http.request(uri, "GET", headers={'Accept': 'text/plain'})
+        self.assertEqual(response.status, 200)
+        self.assertFalse(response.has_key('vary'))
+
+        (response, content) = self.http.request(uri, "GET", headers={'Accept': 'text/plain'})
+        self.assertEqual(response.status, 200)
+        self.assertEqual(response.fromcache, True, msg="Should be from cache")
+        
+        (response, content) = self.http.request(uri, "GET", headers={'Accept': 'text/html'})
+        self.assertEqual(response.status, 200)
+        self.assertEqual(response.fromcache, True, msg="Should be from cache")
+
+    def testVaryHeaderDouble(self):
+        uri = urlparse.urljoin(base, "vary/accept-double.asis")
+        (response, content) = self.http.request(uri, "GET", headers={
+            'Accept': 'text/plain', 'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7'})
+        self.assertEqual(response.status, 200)
+        self.assertTrue(response.has_key('vary'))
+
+        # we are from cache
+        (response, content) = self.http.request(uri, "GET", headers={
+            'Accept': 'text/plain', 'Accept-Language': 'da, en-gb;q=0.8, en;q=0.7'})
+        self.assertEqual(response.fromcache, True, msg="Should be from cache")
+
+        (response, content) = self.http.request(uri, "GET", headers={'Accept': 'text/plain'})
+        self.assertEqual(response.status, 200)
+        self.assertEqual(response.fromcache, False)
+
+        # get the resource again, not from cache, varied headers don't match exact
+        (response, content) = self.http.request(uri, "GET", headers={'Accept-Language': 'da'})
+        self.assertEqual(response.status, 200)
+        self.assertEqual(response.fromcache, False, msg="Should not be from cache")
+
+
     def testHeadGZip(self):
         # Test that we don't try to decompress a HEAD response 
         uri = urlparse.urljoin(base, "gzip/final-destination.txt")
@@ -980,6 +1051,7 @@
 
 
 
+
 # ------------------------------------------------------------------------
 
 class HttpPrivateTest(unittest.TestCase):
@@ -1328,4 +1400,5 @@
         end2end = httplib2._get_end2end_headers(response)
         self.assertEquals(0, len(end2end))
 
-unittest.main()
+if __name__ == '__main__':
+    unittest.main()