Issue #505: Allow disabling of cookie persistence/sending
authorArup Malakar <amalakar@gmail.com>
Wed, 16 May 2012 22:07:15 +0000 (15:07 -0700)
committerArup Malakar <amalakar@gmail.com>
Wed, 16 May 2012 22:07:15 +0000 (15:07 -0700)
AUTHORS.rst
requests/api.py
requests/models.py
requests/sessions.py
tests/test_cookies.py

index b6002ec8a8242c1645ed894d31a2f57197acf651..ba3f85df3ec1110d7f754b223f6fe0c8ceede382 100644 (file)
@@ -100,3 +100,4 @@ Patches and Suggestions
 - Rohan Jain (crodjer)
 - Justin Barber <barber.justin@gmail.com>
 - Roman Haritonov <@reclosedev>
+- Arup Malakar <amalakar@gmail.com>
index e0bf346cb5f459659a3efa1c65ebc5f69ea3d00f..9c2445be9cc9a95370a41f79f65d4991315e411a 100644 (file)
@@ -23,6 +23,7 @@ def request(method, url, **kwargs):
     :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
     :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
     :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
+    :param store_cookies: (optional) if ``False``, the received cookies as part of the HTTP response would be ignored.
     :param files: (optional) Dictionary of 'name': file-like-objects (or {'name': ('filename', fileobj)}) for multipart encoding upload.
     :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
     :param timeout: (optional) Float describing the timeout of the request.
index beb8f1448e6a7be12065445350f4d3da9fcea75a..9aea52ed13ce596669c7c32985727a65016fe497 100644 (file)
@@ -60,6 +60,7 @@ class Request(object):
         params=dict(),
         auth=None,
         cookies=None,
+        store_cookies=True,
         timeout=None,
         redirect=False,
         allow_redirects=False,
@@ -110,6 +111,9 @@ class Request(object):
         # Dictionary mapping protocol to the URL of the proxy (e.g. {'http': 'foo.bar:3128'})
         self.proxies = dict(proxies or [])
 
+        #param store_cookies: (optional) if ``False``, the received cookies as part of the HTTP response would be ignored.
+        self.store_cookies = store_cookies
+
         # If no proxies are given, allow configuration by environment variables
         # HTTP_PROXY and HTTPS_PROXY.
         if not self.proxies and self.config.get('trust_env'):
@@ -197,8 +201,9 @@ class Request(object):
                 # Set encoding.
                 response.encoding = get_encoding_from_headers(response.headers)
 
-                # Add new cookies from the server.
-                extract_cookies_to_jar(self.cookies, self, resp)
+                # Add new cookies from the server. Don't if configured not to
+                if self.store_cookies:
+                    extract_cookies_to_jar(self.cookies, self, resp)
 
                 # Save cookies in Response.
                 response.cookies = self.cookies
@@ -460,7 +465,7 @@ class Request(object):
             return False
 
     def send(self, anyway=False, prefetch=False):
-        """Sends the request. Returns True of successful, False if not.
+        """Sends the request. Returns True if successful, False if not.
         If there was an HTTPError during transmission,
         self.response.status_code will contain the HTTPError code.
 
index dd670dd33e58151680f3f83300eab30460b11d08..62fde5d30b874cb878cb308daf7670861241fcbd 100644 (file)
@@ -59,6 +59,7 @@ class Session(object):
     def __init__(self,
         headers=None,
         cookies=None,
+        store_cookies=True,
         auth=None,
         timeout=None,
         proxies=None,
@@ -79,6 +80,7 @@ class Session(object):
         self.prefetch = prefetch
         self.verify = verify
         self.cert = cert
+        self.store_cookies = store_cookies
 
         for (k, v) in list(defaults.items()):
             self.config.setdefault(k, v)
@@ -111,6 +113,7 @@ class Session(object):
         data=None,
         headers=None,
         cookies=None,
+        store_cookies=True,
         files=None,
         auth=None,
         timeout=None,
@@ -132,6 +135,7 @@ class Session(object):
         :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
         :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
         :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
+        :param store_cookies: (optional) if ``False``, the received cookies as part of the HTTP response would be ignored.
         :param files: (optional) Dictionary of 'filename': file-like-objects for multipart encoding upload.
         :param auth: (optional) Auth tuple or callable to enable Basic/Digest/Custom HTTP Auth.
         :param timeout: (optional) Float describing the timeout of the request.
@@ -170,6 +174,7 @@ class Session(object):
             params=params,
             headers=headers,
             cookies=cookies,
+            store_cookies=store_cookies,
             files=files,
             auth=auth,
             hooks=hooks,
index dca7d2c44844b6a98d3866eaa49770692c351242..a9fda180ed7ca08f228b6f8f8b92ce76cc8ada5e 100755 (executable)
@@ -102,6 +102,27 @@ class CookieTests(TestBaseMixin, unittest.TestCase):
         insecure_cookies_sent = json.loads(insecure_resp.text)['cookies']
         self.assertEqual(insecure_cookies_sent, {})
 
+    def test_disabled_cookie_persistence(self):
+        """Test that cookies are not persisted when configured accordingly."""
+
+        # Check the case when no cookie is passed as part of the request and the one in response is ignored
+        cookies = requests.get(httpbin('cookies', 'set', 'key', 'value'), store_cookies = False).cookies
+        self.assertIsNone(cookies.get("key"))
+
+        # Test that the cookies passed while making the request still gets used and is available in response object.
+        # only the ones received from server is not saved
+        cookies_2 = requests.get(httpbin('cookies', 'set', 'key', 'value'), store_cookies = False,\
+                                                cookies = {"key_2" : "value_2"}).cookies
+        self.assertEqual(len(cookies_2), 1)
+        self.assertEqual(cookies_2.get("key_2"), "value_2")
+
+        # Use the session and make sure that the received cookie is not used in subsequent calls
+        s = requests.session()
+        s.get(httpbin('cookies', 'set', 'key', 'value'), store_cookies = False)
+        r = s.get(httpbin('cookies'))
+        self.assertEqual(json.loads(r.text)['cookies'], {})
+
+
 class LWPCookieJarTest(TestBaseMixin, unittest.TestCase):
     """Check store/load of cookies to FileCookieJar's, specifically LWPCookieJar's."""