diff options
author | Jacob Neil Taylor <me@jacobtaylor.id.au> | 2020-10-23 22:48:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-23 22:48:55 (GMT) |
commit | 16ee68da6e12bb2d79751b32cc37523fe4f4bb48 (patch) | |
tree | dd97261b83ce7b3d0b33ae6835efe1f0124a5a22 /Lib/http | |
parent | a3c4ceffe61df89cc9ce5c437cae0276521dc83b (diff) | |
download | cpython-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.py | 40 |
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") |