mirror of
https://github.com/python/cpython.git
synced 2024-11-27 11:55:13 +08:00
bpo-34911: Added support for secure websocket cookies (GH-9734)
This commit is contained in:
parent
af5658ae93
commit
4c33997057
@ -78,14 +78,16 @@ The following classes are provided:
|
||||
from / returned to the server.
|
||||
|
||||
|
||||
.. class:: DefaultCookiePolicy( blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False )
|
||||
.. class:: DefaultCookiePolicy( blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False, secure_protocols=("https", "wss") )
|
||||
|
||||
Constructor arguments should be passed as keyword arguments only.
|
||||
*blocked_domains* is a sequence of domain names that we never accept cookies
|
||||
from, nor return cookies to. *allowed_domains* if not :const:`None`, this is a
|
||||
sequence of the only domains for which we accept and return cookies. For all
|
||||
other arguments, see the documentation for :class:`CookiePolicy` and
|
||||
:class:`DefaultCookiePolicy` objects.
|
||||
sequence of the only domains for which we accept and return cookies.
|
||||
*secure_protocols* is a sequence of protocols for which secure cookies can be
|
||||
added to. By default *https* and *wss* (secure websocket) are considered
|
||||
secure protocols. For all other arguments, see the documentation for
|
||||
:class:`CookiePolicy` and :class:`DefaultCookiePolicy` objects.
|
||||
|
||||
:class:`DefaultCookiePolicy` implements the standard accept / reject rules for
|
||||
Netscape and :rfc:`2965` cookies. By default, :rfc:`2109` cookies (ie. cookies
|
||||
|
@ -878,6 +878,7 @@ class DefaultCookiePolicy(CookiePolicy):
|
||||
strict_ns_domain=DomainLiberal,
|
||||
strict_ns_set_initial_dollar=False,
|
||||
strict_ns_set_path=False,
|
||||
secure_protocols=("https", "wss")
|
||||
):
|
||||
"""Constructor arguments should be passed as keyword arguments only."""
|
||||
self.netscape = netscape
|
||||
@ -890,6 +891,7 @@ class DefaultCookiePolicy(CookiePolicy):
|
||||
self.strict_ns_domain = strict_ns_domain
|
||||
self.strict_ns_set_initial_dollar = strict_ns_set_initial_dollar
|
||||
self.strict_ns_set_path = strict_ns_set_path
|
||||
self.secure_protocols = secure_protocols
|
||||
|
||||
if blocked_domains is not None:
|
||||
self._blocked_domains = tuple(blocked_domains)
|
||||
@ -1116,7 +1118,7 @@ class DefaultCookiePolicy(CookiePolicy):
|
||||
return True
|
||||
|
||||
def return_ok_secure(self, cookie, request):
|
||||
if cookie.secure and request.type != "https":
|
||||
if cookie.secure and request.type not in self.secure_protocols:
|
||||
_debug(" secure cookie with non-secure request")
|
||||
return False
|
||||
return True
|
||||
|
@ -984,6 +984,61 @@ class CookieTests(unittest.TestCase):
|
||||
c._cookies["www.acme.com"]["/"]["foo2"].secure,
|
||||
"secure cookie registered non-secure")
|
||||
|
||||
def test_secure_block(self):
|
||||
pol = DefaultCookiePolicy()
|
||||
c = CookieJar(policy=pol)
|
||||
|
||||
headers = ["Set-Cookie: session=narf; secure; path=/"]
|
||||
req = urllib.request.Request("https://www.acme.com/")
|
||||
res = FakeResponse(headers, "https://www.acme.com/")
|
||||
c.extract_cookies(res, req)
|
||||
self.assertEqual(len(c), 1)
|
||||
|
||||
req = urllib.request.Request("https://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertTrue(req.has_header("Cookie"))
|
||||
|
||||
req = urllib.request.Request("http://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertFalse(req.has_header("Cookie"))
|
||||
|
||||
# secure websocket protocol
|
||||
req = urllib.request.Request("wss://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertTrue(req.has_header("Cookie"))
|
||||
|
||||
# non-secure websocket protocol
|
||||
req = urllib.request.Request("ws://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertFalse(req.has_header("Cookie"))
|
||||
|
||||
def test_custom_secure_protocols(self):
|
||||
pol = DefaultCookiePolicy(secure_protocols=["foos"])
|
||||
c = CookieJar(policy=pol)
|
||||
|
||||
headers = ["Set-Cookie: session=narf; secure; path=/"]
|
||||
req = urllib.request.Request("https://www.acme.com/")
|
||||
res = FakeResponse(headers, "https://www.acme.com/")
|
||||
c.extract_cookies(res, req)
|
||||
self.assertEqual(len(c), 1)
|
||||
|
||||
# test https removed from secure protocol list
|
||||
req = urllib.request.Request("https://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertFalse(req.has_header("Cookie"))
|
||||
|
||||
req = urllib.request.Request("http://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertFalse(req.has_header("Cookie"))
|
||||
|
||||
req = urllib.request.Request("foos://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertTrue(req.has_header("Cookie"))
|
||||
|
||||
req = urllib.request.Request("foo://www.acme.com/")
|
||||
c.add_cookie_header(req)
|
||||
self.assertFalse(req.has_header("Cookie"))
|
||||
|
||||
def test_quote_cookie_value(self):
|
||||
c = CookieJar(policy=DefaultCookiePolicy(rfc2965=True))
|
||||
interact_2965(c, "http://www.acme.com/", r'foo=\b"a"r; Version=1')
|
||||
|
@ -0,0 +1,3 @@
|
||||
Added *secure_protocols* argument to *http.cookiejar.DefaultCookiePolicy* to
|
||||
allow for tweaking of protocols and also to add support by default for
|
||||
*wss*, the secure websocket protocol.
|
Loading…
Reference in New Issue
Block a user