@@ -50,10 +50,18 @@ def _debug(*args):
5050 logger = logging .getLogger ("http.cookiejar" )
5151 return logger .debug (* args )
5252
53-
53+ HTTPONLY_ATTR = "HTTPOnly"
54+ HTTPONLY_PREFIX = "#HttpOnly_"
5455DEFAULT_HTTP_PORT = str (http .client .HTTP_PORT )
56+ NETSCAPE_MAGIC_RGX = re .compile ("#( Netscape)? HTTP Cookie File" )
5557MISSING_FILENAME_TEXT = ("a filename was not supplied (nor was the CookieJar "
5658 "instance initialised with one)" )
59+ NETSCAPE_HEADER_TEXT = """\
60+ # Netscape HTTP Cookie File
61+ # http://curl.haxx.se/rfc/cookie_spec.html
62+ # This is a generated file! Do not edit.
63+
64+ """
5765
5866def _warn_unhandled_exception ():
5967 # There are a few catch-all except: statements in this module, for
@@ -2004,28 +2012,29 @@ class MozillaCookieJar(FileCookieJar):
20042012 header by default (Mozilla can cope with that).
20052013
20062014 """
2007- magic_re = re .compile ("#( Netscape)? HTTP Cookie File" )
2008- header = """\
2009- # Netscape HTTP Cookie File
2010- # http://curl.haxx.se/rfc/cookie_spec.html
2011- # This is a generated file! Do not edit.
2012-
2013- """
20142015
20152016 def _really_load (self , f , filename , ignore_discard , ignore_expires ):
20162017 now = time .time ()
20172018
2018- magic = f .readline ()
2019- if not self .magic_re .search (magic ):
2019+ if not NETSCAPE_MAGIC_RGX .match (f .readline ()):
20202020 raise LoadError (
20212021 "%r does not look like a Netscape format cookies file" %
20222022 filename )
20232023
20242024 try :
20252025 while 1 :
20262026 line = f .readline ()
2027+ rest = {}
2028+
20272029 if line == "" : break
20282030
2031+ # httponly is a cookie flag as defined in rfc6265
2032+ # when encoded in a netscape cookie file,
2033+ # the line is prepended with "#HttpOnly_"
2034+ if line .startswith (HTTPONLY_PREFIX ):
2035+ rest [HTTPONLY_ATTR ] = ""
2036+ line = line [len (HTTPONLY_PREFIX ):]
2037+
20292038 # last field may be absent, so keep any trailing tab
20302039 if line .endswith ("\n " ): line = line [:- 1 ]
20312040
@@ -2063,7 +2072,7 @@ def _really_load(self, f, filename, ignore_discard, ignore_expires):
20632072 discard ,
20642073 None ,
20652074 None ,
2066- {} )
2075+ rest )
20672076 if not ignore_discard and c .discard :
20682077 continue
20692078 if not ignore_expires and c .is_expired (now ):
@@ -2083,16 +2092,17 @@ def save(self, filename=None, ignore_discard=False, ignore_expires=False):
20832092 else : raise ValueError (MISSING_FILENAME_TEXT )
20842093
20852094 with open (filename , "w" ) as f :
2086- f .write (self . header )
2095+ f .write (NETSCAPE_HEADER_TEXT )
20872096 now = time .time ()
20882097 for cookie in self :
2098+ domain = cookie .domain
20892099 if not ignore_discard and cookie .discard :
20902100 continue
20912101 if not ignore_expires and cookie .is_expired (now ):
20922102 continue
20932103 if cookie .secure : secure = "TRUE"
20942104 else : secure = "FALSE"
2095- if cookie . domain .startswith ("." ): initial_dot = "TRUE"
2105+ if domain .startswith ("." ): initial_dot = "TRUE"
20962106 else : initial_dot = "FALSE"
20972107 if cookie .expires is not None :
20982108 expires = str (cookie .expires )
@@ -2107,7 +2117,9 @@ def save(self, filename=None, ignore_discard=False, ignore_expires=False):
21072117 else :
21082118 name = cookie .name
21092119 value = cookie .value
2120+ if cookie .has_nonstandard_attr (HTTPONLY_ATTR ):
2121+ domain = HTTPONLY_PREFIX + domain
21102122 f .write (
2111- "\t " .join ([cookie . domain , initial_dot , cookie .path ,
2123+ "\t " .join ([domain , initial_dot , cookie .path ,
21122124 secure , expires , name , value ])+
21132125 "\n " )
0 commit comments