summaryrefslogtreecommitdiffstats
path: root/Lib/http
diff options
context:
space:
mode:
authorJacob Neil Taylor <me@jacobtaylor.id.au>2020-10-23 22:48:55 (GMT)
committerGitHub <noreply@github.com>2020-10-23 22:48:55 (GMT)
commit16ee68da6e12bb2d79751b32cc37523fe4f4bb48 (patch)
treedd97261b83ce7b3d0b33ae6835efe1f0124a5a22 /Lib/http
parenta3c4ceffe61df89cc9ce5c437cae0276521dc83b (diff)
downloadcpython-16ee68da6e12bb2d79751b32cc37523fe4f4bb48.zip
cpython-16ee68da6e12bb2d79751b32cc37523fe4f4bb48.tar.gz
cpython-16ee68da6e12bb2d79751b32cc37523fe4f4bb48.tar.bz2
bpo-38976: Add support for HTTP Only flag in MozillaCookieJar (#17471)
Add support for HTTP Only flag in MozillaCookieJar Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Diffstat (limited to 'Lib/http')
-rw-r--r--Lib/http/cookiejar.py40
1 files changed, 26 insertions, 14 deletions
diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py
index 47ed5c3..eaa76c2 100644
--- a/Lib/http/cookiejar.py
+++ b/Lib/http/cookiejar.py
@@ -50,10 +50,18 @@ def _debug(*args):
logger = logging.getLogger("http.cookiejar")
return logger.debug(*args)
-
+HTTPONLY_ATTR = "HTTPOnly"
+HTTPONLY_PREFIX = "#HttpOnly_"
DEFAULT_HTTP_PORT = str(http.client.HTTP_PORT)
+NETSCAPE_MAGIC_RGX = re.compile("#( Netscape)? HTTP Cookie File")
MISSING_FILENAME_TEXT = ("a filename was not supplied (nor was the CookieJar "
"instance initialised with one)")
+NETSCAPE_HEADER_TEXT = """\
+# Netscape HTTP Cookie File
+# http://curl.haxx.se/rfc/cookie_spec.html
+# This is a generated file! Do not edit.
+
+"""
def _warn_unhandled_exception():
# There are a few catch-all except: statements in this module, for
@@ -2004,19 +2012,11 @@ class MozillaCookieJar(FileCookieJar):
header by default (Mozilla can cope with that).
"""
- magic_re = re.compile("#( Netscape)? HTTP Cookie File")
- header = """\
-# Netscape HTTP Cookie File
-# http://curl.haxx.se/rfc/cookie_spec.html
-# This is a generated file! Do not edit.
-
-"""
def _really_load(self, f, filename, ignore_discard, ignore_expires):
now = time.time()
- magic = f.readline()
- if not self.magic_re.search(magic):
+ if not NETSCAPE_MAGIC_RGX.match(f.readline()):
raise LoadError(
"%r does not look like a Netscape format cookies file" %
filename)
@@ -2024,8 +2024,17 @@ class MozillaCookieJar(FileCookieJar):
try:
while 1:
line = f.readline()
+ rest = {}
+
if line == "": break
+ # httponly is a cookie flag as defined in rfc6265
+ # when encoded in a netscape cookie file,
+ # the line is prepended with "#HttpOnly_"
+ if line.startswith(HTTPONLY_PREFIX):
+ rest[HTTPONLY_ATTR] = ""
+ line = line[len(HTTPONLY_PREFIX):]
+
# last field may be absent, so keep any trailing tab
if line.endswith("\n"): line = line[:-1]
@@ -2063,7 +2072,7 @@ class MozillaCookieJar(FileCookieJar):
discard,
None,
None,
- {})
+ rest)
if not ignore_discard and c.discard:
continue
if not ignore_expires and c.is_expired(now):
@@ -2083,16 +2092,17 @@ class MozillaCookieJar(FileCookieJar):
else: raise ValueError(MISSING_FILENAME_TEXT)
with open(filename, "w") as f:
- f.write(self.header)
+ f.write(NETSCAPE_HEADER_TEXT)
now = time.time()
for cookie in self:
+ domain = cookie.domain
if not ignore_discard and cookie.discard:
continue
if not ignore_expires and cookie.is_expired(now):
continue
if cookie.secure: secure = "TRUE"
else: secure = "FALSE"
- if cookie.domain.startswith("."): initial_dot = "TRUE"
+ if domain.startswith("."): initial_dot = "TRUE"
else: initial_dot = "FALSE"
if cookie.expires is not None:
expires = str(cookie.expires)
@@ -2107,7 +2117,9 @@ class MozillaCookieJar(FileCookieJar):
else:
name = cookie.name
value = cookie.value
+ if cookie.has_nonstandard_attr(HTTPONLY_ATTR):
+ domain = HTTPONLY_PREFIX + domain
f.write(
- "\t".join([cookie.domain, initial_dot, cookie.path,
+ "\t".join([domain, initial_dot, cookie.path,
secure, expires, name, value])+
"\n")