diff --git a/AUTHORS.rst b/AUTHORS.rst index b0a7e241..e94a4bff 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -144,3 +144,4 @@ Patches and Suggestions - Jayson Vantuyl @kagato - Pengfei.X - Kamil Madac +- Michael Becker @beckerfuffle diff --git a/HISTORY.rst b/HISTORY.rst index 601ba580..f27ce332 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,6 +7,7 @@ Release History ++++++++++++++++++ - Updated CA Bundle, of course. +- Cookies set on individual Requests through a ``Session`` (e.g. via ``Session.get()``) are no longer persisted to the ``Session``. - Clean up connections when we hit problems during chunked upload, rather than leaking them. - Return connections to the pool when a chunked upload is successful, rather than leaking it. - Match the HTTPbis recommendation for HTTP 301 redirects. diff --git a/requests/cookies.py b/requests/cookies.py index c465f552..35dacfc4 100644 --- a/requests/cookies.py +++ b/requests/cookies.py @@ -378,29 +378,29 @@ def create_cookie(name, value, **kwargs): def morsel_to_cookie(morsel): """Convert a Morsel object into a Cookie containing the one k/v pair.""" + expires = None - if morsel["max-age"]: - expires = time.time() + morsel["max-age"] + if morsel['max-age']: + expires = time.time() + morsel['max-age'] elif morsel['expires']: - expires = morsel['expires'] - if type(expires) == type(""): - time_template = "%a, %d-%b-%Y %H:%M:%S GMT" - expires = time.mktime(time.strptime(expires, time_template)) - c = create_cookie( - name=morsel.key, - value=morsel.value, - version=morsel['version'] or 0, - port=None, - domain=morsel['domain'], - path=morsel['path'], - secure=bool(morsel['secure']), - expires=expires, - discard=False, + time_template = '%a, %d-%b-%Y %H:%M:%S GMT' + expires = time.mktime( + time.strptime(morsel['expires'], time_template)) - time.timezone + return create_cookie( comment=morsel['comment'], comment_url=bool(morsel['comment']), + discard=False, + domain=morsel['domain'], + expires=expires, + name=morsel.key, + path=morsel['path'], + port=None, rest={'HttpOnly': morsel['httponly']}, - rfc2109=False,) - return c + rfc2109=False, + secure=bool(morsel['secure']), + value=morsel.value, + version=morsel['version'] or 0, + ) def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): diff --git a/test_requests.py b/test_requests.py index a800ba71..093b37c1 100755 --- a/test_requests.py +++ b/test_requests.py @@ -6,15 +6,16 @@ from __future__ import division import json import os -import unittest import pickle +import unittest import requests import pytest -from requests.auth import HTTPDigestAuth from requests.adapters import HTTPAdapter -from requests.compat import str, cookielib, getproxies, urljoin, urlparse -from requests.cookies import cookiejar_from_dict +from requests.auth import HTTPDigestAuth +from requests.compat import ( + Morsel, cookielib, getproxies, str, urljoin, urlparse) +from requests.cookies import cookiejar_from_dict, morsel_to_cookie from requests.exceptions import InvalidURL, MissingSchema from requests.structures import CaseInsensitiveDict @@ -1004,5 +1005,64 @@ class UtilsTestCase(unittest.TestCase): assert not address_in_network('172.16.0.1', '192.168.1.0/24') + +class TestMorselToCookieExpires(unittest.TestCase): + + """Tests for morsel_to_cookie when morsel contains expires.""" + + def test_expires_valid_str(self): + """Test case where we convert expires from string time.""" + + morsel = Morsel() + morsel['expires'] = 'Thu, 01-Jan-1970 00:00:01 GMT' + cookie = morsel_to_cookie(morsel) + assert cookie.expires == 1 + + def test_expires_invalid_int(self): + """Test case where an invalid type is passed for expires.""" + + morsel = Morsel() + morsel['expires'] = 100 + with pytest.raises(TypeError): + morsel_to_cookie(morsel) + + def test_expires_invalid_str(self): + """Test case where an invalid string is input.""" + + morsel = Morsel() + morsel['expires'] = 'woops' + with pytest.raises(ValueError): + morsel_to_cookie(morsel) + + def test_expires_none(self): + """Test case where expires is None.""" + + morsel = Morsel() + morsel['expires'] = None + cookie = morsel_to_cookie(morsel) + assert cookie.expires is None + + +class TestMorselToCookieMaxAge(unittest.TestCase): + + """Tests for morsel_to_cookie when morsel contains max-age.""" + + def test_max_age_valid_int(self): + """Test case where a valid max age in seconds is passed.""" + + morsel = Morsel() + morsel['max-age'] = 60 + cookie = morsel_to_cookie(morsel) + assert isinstance(cookie.expires, int) + + def test_max_age_invalid_str(self): + """Test case where a invalid max age is passed.""" + + morsel = Morsel() + morsel['max-age'] = 'woops' + with pytest.raises(TypeError): + morsel_to_cookie(morsel) + + if __name__ == '__main__': unittest.main()