Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
532efabf
Commit
532efabf
authored
Aug 24, 2005
by
Georg Brandl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
patch #848017: make Cookie more RFC-compliant.
parent
e1b13d20
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
45 additions
and
45 deletions
+45
-45
Doc/lib/libcookie.tex
Doc/lib/libcookie.tex
+19
-17
Lib/Cookie.py
Lib/Cookie.py
+23
-28
Misc/NEWS
Misc/NEWS
+3
-0
No files found.
Doc/lib/libcookie.tex
View file @
532efabf
...
@@ -98,7 +98,9 @@ In general, it should be the case that \method{value_encode()} and
...
@@ -98,7 +98,9 @@ In general, it should be the case that \method{value_encode()} and
Return a string representation suitable to be sent as HTTP headers.
Return a string representation suitable to be sent as HTTP headers.
\var
{
attrs
}
and
\var
{
header
}
are sent to each
\class
{
Morsel
}
's
\var
{
attrs
}
and
\var
{
header
}
are sent to each
\class
{
Morsel
}
's
\method
{
output()
}
method.
\var
{
sep
}
is used to join the headers
\method
{
output()
}
method.
\var
{
sep
}
is used to join the headers
together, and is by default a newline.
together, and is by default the combination '
\r\n
' (CRLF).
\versionchanged
[The default separator has been changed from '
\n
' to match the cookie
specification]
{
2.5
}
\end{methoddesc}
\end{methoddesc}
\begin{methoddesc}
[BaseCookie]
{
js
_
output
}{
\optional
{
attrs
}}
\begin{methoddesc}
[BaseCookie]
{
js
_
output
}{
\optional
{
attrs
}}
...
@@ -195,32 +197,32 @@ The following example demonstrates how to use the \module{Cookie} module.
...
@@ -195,32 +197,32 @@ The following example demonstrates how to use the \module{Cookie} module.
>>> C["fig"] = "newton"
>>> C["fig"] = "newton"
>>> C["sugar"] = "wafer"
>>> C["sugar"] = "wafer"
>>> print C # generate HTTP headers
>>> print C # generate HTTP headers
Set-Cookie: sugar=wafer
;
Set-Cookie: sugar=wafer
Set-Cookie: fig=newton
;
Set-Cookie: fig=newton
>>> print C.output() # same thing
>>> print C.output() # same thing
Set-Cookie: sugar=wafer
;
Set-Cookie: sugar=wafer
Set-Cookie: fig=newton
;
Set-Cookie: fig=newton
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C["rocky"] = "road"
>>> C["rocky"] = "road"
>>> C["rocky"]["path"] = "/cookie"
>>> C["rocky"]["path"] = "/cookie"
>>> print C.output(header="Cookie:")
>>> print C.output(header="Cookie:")
Cookie: rocky=road; Path=/cookie
;
Cookie: rocky=road; Path=/cookie
>>> print C.output(attrs=[], header="Cookie:")
>>> print C.output(attrs=[], header="Cookie:")
Cookie: rocky=road
;
Cookie: rocky=road
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
>>> print C
>>> print C
Set-Cookie: vienna=finger
;
Set-Cookie: vienna=finger
Set-Cookie: chips=ahoy
;
Set-Cookie: chips=ahoy
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C.load('keebler="E=everybody; L=
\\
"Loves
\\
"; fudge=
\\
012;";')
>>> C.load('keebler="E=everybody; L=
\\
"Loves
\\
"; fudge=
\\
012;";')
>>> print C
>>> print C
Set-Cookie: keebler="E=everybody; L=
\"
Loves
\"
; fudge=
\0
12;"
;
Set-Cookie: keebler="E=everybody; L=
\"
Loves
\"
; fudge=
\0
12;"
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C["oreo"] = "doublestuff"
>>> C["oreo"] = "doublestuff"
>>> C["oreo"]["path"] = "/"
>>> C["oreo"]["path"] = "/"
>>> print C
>>> print C
Set-Cookie: oreo=doublestuff; Path=/
;
Set-Cookie: oreo=doublestuff; Path=/
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C["twix"] = "none for you"
>>> C["twix"] = "none for you"
>>> C["twix"].value
>>> C["twix"].value
...
@@ -233,8 +235,8 @@ Set-Cookie: oreo=doublestuff; Path=/;
...
@@ -233,8 +235,8 @@ Set-Cookie: oreo=doublestuff; Path=/;
>>> C["string"].value
>>> C["string"].value
'seven'
'seven'
>>> print C
>>> print C
Set-Cookie: number=7
;
Set-Cookie: number=7
Set-Cookie: string=seven
;
Set-Cookie: string=seven
>>> C = Cookie.SerialCookie()
>>> C = Cookie.SerialCookie()
>>> C["number"] = 7
>>> C["number"] = 7
>>> C["string"] = "seven"
>>> C["string"] = "seven"
...
@@ -243,8 +245,8 @@ Set-Cookie: string=seven;
...
@@ -243,8 +245,8 @@ Set-Cookie: string=seven;
>>> C["string"].value
>>> C["string"].value
'seven'
'seven'
>>> print C
>>> print C
Set-Cookie: number="I7
\0
12."
;
Set-Cookie: number="I7
\0
12."
Set-Cookie: string="S'seven'
\0
12p1
\0
12."
;
Set-Cookie: string="S'seven'
\0
12p1
\0
12."
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C["number"] = 7
>>> C["number"] = 7
>>> C["string"] = "seven"
>>> C["string"] = "seven"
...
@@ -253,6 +255,6 @@ Set-Cookie: string="S'seven'\012p1\012.";
...
@@ -253,6 +255,6 @@ Set-Cookie: string="S'seven'\012p1\012.";
>>> C["string"].value
>>> C["string"].value
'seven'
'seven'
>>> print C
>>> print C
Set-Cookie: number="I7
\0
12."
;
Set-Cookie: number="I7
\0
12."
Set-Cookie: string=seven
;
Set-Cookie: string=seven
\end{verbatim}
\end{verbatim}
Lib/Cookie.py
View file @
532efabf
...
@@ -69,9 +69,8 @@ a dictionary.
...
@@ -69,9 +69,8 @@ a dictionary.
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C["fig"] = "newton"
>>> C["fig"] = "newton"
>>> C["sugar"] = "wafer"
>>> C["sugar"] = "wafer"
>>> print C
>>> C.output()
Set-Cookie: fig=newton;
'Set-Cookie: fig=newton\r\nSet-Cookie: sugar=wafer'
Set-Cookie: sugar=wafer;
Notice that the printable representation of a Cookie is the
Notice that the printable representation of a Cookie is the
appropriate format for a Set-Cookie: header. This is the
appropriate format for a Set-Cookie: header. This is the
...
@@ -82,9 +81,9 @@ attributes by using the .output() function
...
@@ -82,9 +81,9 @@ attributes by using the .output() function
>>> C["rocky"] = "road"
>>> C["rocky"] = "road"
>>> C["rocky"]["path"] = "/cookie"
>>> C["rocky"]["path"] = "/cookie"
>>> print C.output(header="Cookie:")
>>> print C.output(header="Cookie:")
Cookie: rocky=road; Path=/cookie
;
Cookie: rocky=road; Path=/cookie
>>> print C.output(attrs=[], header="Cookie:")
>>> print C.output(attrs=[], header="Cookie:")
Cookie: rocky=road
;
Cookie: rocky=road
The load() method of a Cookie extracts cookies from a string. In a
The load() method of a Cookie extracts cookies from a string. In a
CGI script, you would use this method to extract the cookies from the
CGI script, you would use this method to extract the cookies from the
...
@@ -92,9 +91,8 @@ HTTP_COOKIE environment variable.
...
@@ -92,9 +91,8 @@ HTTP_COOKIE environment variable.
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C.load("chips=ahoy; vienna=finger")
>>> C.load("chips=ahoy; vienna=finger")
>>> print C
>>> C.output()
Set-Cookie: chips=ahoy;
'Set-Cookie: chips=ahoy\r\nSet-Cookie: vienna=finger'
Set-Cookie: vienna=finger;
The load() method is darn-tootin smart about identifying cookies
The load() method is darn-tootin smart about identifying cookies
within a string. Escaped quotation marks, nested semicolons, and other
within a string. Escaped quotation marks, nested semicolons, and other
...
@@ -103,7 +101,7 @@ such trickeries do not confuse it.
...
@@ -103,7 +101,7 @@ such trickeries do not confuse it.
>>> C = Cookie.SmartCookie()
>>> C = Cookie.SmartCookie()
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
>>> print C
>>> print C
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
;
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"
Each element of the Cookie also supports all of the RFC 2109
Each element of the Cookie also supports all of the RFC 2109
Cookie attributes. Here's an example which sets the Path
Cookie attributes. Here's an example which sets the Path
...
@@ -113,7 +111,7 @@ attribute.
...
@@ -113,7 +111,7 @@ attribute.
>>> C["oreo"] = "doublestuff"
>>> C["oreo"] = "doublestuff"
>>> C["oreo"]["path"] = "/"
>>> C["oreo"]["path"] = "/"
>>> print C
>>> print C
Set-Cookie: oreo=doublestuff; Path=/
;
Set-Cookie: oreo=doublestuff; Path=/
Each dictionary element has a 'value' attribute, which gives you
Each dictionary element has a 'value' attribute, which gives you
back the value associated with the key.
back the value associated with the key.
...
@@ -144,9 +142,8 @@ the value to a string, when the values are set dictionary-style.
...
@@ -144,9 +142,8 @@ the value to a string, when the values are set dictionary-style.
'7'
'7'
>>> C["string"].value
>>> C["string"].value
'seven'
'seven'
>>> print C
>>> C.output()
Set-Cookie: number=7;
'Set-Cookie: number=7\r\nSet-Cookie: string=seven'
Set-Cookie: string=seven;
SerialCookie
SerialCookie
...
@@ -165,9 +162,8 @@ values, however.)
...
@@ -165,9 +162,8 @@ values, however.)
7
7
>>> C["string"].value
>>> C["string"].value
'seven'
'seven'
>>> print C
>>> C.output()
Set-Cookie: number="I7\012.";
'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string="S\'seven\'\\012p1\\012."'
Set-Cookie: string="S'seven'\012p1\012.";
Be warned, however, if SerialCookie cannot de-serialize a value (because
Be warned, however, if SerialCookie cannot de-serialize a value (because
it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
...
@@ -190,9 +186,8 @@ as a string.
...
@@ -190,9 +186,8 @@ as a string.
7
7
>>> C["string"].value
>>> C["string"].value
'seven'
'seven'
>>> print C
>>> C.output()
Set-Cookie: number="I7\012.";
'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string=seven'
Set-Cookie: string=seven;
Backwards Compatibility
Backwards Compatibility
...
@@ -228,7 +223,7 @@ __all__ = ["CookieError","BaseCookie","SimpleCookie","SerialCookie",
...
@@ -228,7 +223,7 @@ __all__ = ["CookieError","BaseCookie","SimpleCookie","SerialCookie",
"SmartCookie"
,
"Cookie"
]
"SmartCookie"
,
"Cookie"
]
_nulljoin
=
''
.
join
_nulljoin
=
''
.
join
_s
pacejoin
=
'
'
.
join
_s
emispacejoin
=
';
'
.
join
#
#
# Define an exception visible to External modules
# Define an exception visible to External modules
...
@@ -485,7 +480,7 @@ class Morsel(dict):
...
@@ -485,7 +480,7 @@ class Morsel(dict):
RA
=
result
.
append
RA
=
result
.
append
# First, the key=value pair
# First, the key=value pair
RA
(
"%s=%s
;
"
%
(
self
.
key
,
self
.
coded_value
))
RA
(
"%s=%s"
%
(
self
.
key
,
self
.
coded_value
))
# Now add any defined attributes
# Now add any defined attributes
if
attrs
is
None
:
if
attrs
is
None
:
...
@@ -496,16 +491,16 @@ class Morsel(dict):
...
@@ -496,16 +491,16 @@ class Morsel(dict):
if
V
==
""
:
continue
if
V
==
""
:
continue
if
K
not
in
attrs
:
continue
if
K
not
in
attrs
:
continue
if
K
==
"expires"
and
type
(
V
)
==
type
(
1
):
if
K
==
"expires"
and
type
(
V
)
==
type
(
1
):
RA
(
"%s=%s
;
"
%
(
self
.
_reserved
[
K
],
_getdate
(
V
)))
RA
(
"%s=%s"
%
(
self
.
_reserved
[
K
],
_getdate
(
V
)))
elif
K
==
"max-age"
and
type
(
V
)
==
type
(
1
):
elif
K
==
"max-age"
and
type
(
V
)
==
type
(
1
):
RA
(
"%s=%d
;
"
%
(
self
.
_reserved
[
K
],
V
))
RA
(
"%s=%d"
%
(
self
.
_reserved
[
K
],
V
))
elif
K
==
"secure"
:
elif
K
==
"secure"
:
RA
(
"%s;"
%
self
.
_reserved
[
K
]
)
RA
(
str
(
self
.
_reserved
[
K
])
)
else
:
else
:
RA
(
"%s=%s
;
"
%
(
self
.
_reserved
[
K
],
V
))
RA
(
"%s=%s"
%
(
self
.
_reserved
[
K
],
V
))
# Return the result
# Return the result
return
_spacejoin
(
result
)
return
_s
emis
pacejoin
(
result
)
# end OutputString
# end OutputString
# end Morsel class
# end Morsel class
...
@@ -581,7 +576,7 @@ class BaseCookie(dict):
...
@@ -581,7 +576,7 @@ class BaseCookie(dict):
self
.
__set
(
key
,
rval
,
cval
)
self
.
__set
(
key
,
rval
,
cval
)
# end __setitem__
# end __setitem__
def
output
(
self
,
attrs
=
None
,
header
=
"Set-Cookie:"
,
sep
=
"
\
n
"
):
def
output
(
self
,
attrs
=
None
,
header
=
"Set-Cookie:"
,
sep
=
"
\
015
\
012
"
):
"""Return a string suitable for HTTP."""
"""Return a string suitable for HTTP."""
result
=
[]
result
=
[]
items
=
self
.
items
()
items
=
self
.
items
()
...
@@ -599,7 +594,7 @@ class BaseCookie(dict):
...
@@ -599,7 +594,7 @@ class BaseCookie(dict):
items
.
sort
()
items
.
sort
()
for
K
,
V
in
items
:
for
K
,
V
in
items
:
L
.
append
(
'%s=%s'
%
(
K
,
repr
(
V
.
value
)
)
)
L
.
append
(
'%s=%s'
%
(
K
,
repr
(
V
.
value
)
)
)
return
'<%s: %s>'
%
(
self
.
__class__
.
__name__
,
_spacejoin
(
L
))
return
'<%s: %s>'
%
(
self
.
__class__
.
__name__
,
_s
emis
pacejoin
(
L
))
def
js_output
(
self
,
attrs
=
None
):
def
js_output
(
self
,
attrs
=
None
):
"""Return a string suitable for JavaScript."""
"""Return a string suitable for JavaScript."""
...
...
Misc/NEWS
View file @
532efabf
...
@@ -193,6 +193,9 @@ Extension Modules
...
@@ -193,6 +193,9 @@ Extension Modules
Library
Library
-------
-------
-
Patch
#
848017
:
Make
Cookie
more
RFC
-
compliant
.
Use
CRLF
as
default
output
separator
and
do
not
output
trailing
semicola
.
-
Patch
#
1062060
:
urllib
.
urlretrieve
()
now
raises
a
new
exception
,
named
-
Patch
#
1062060
:
urllib
.
urlretrieve
()
now
raises
a
new
exception
,
named
ContentTooShortException
,
when
the
actually
downloaded
size
does
not
ContentTooShortException
,
when
the
actually
downloaded
size
does
not
match
the
Content
-
Length
header
.
match
the
Content
-
Length
header
.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment