blob: 85de33f6b68cd45012870a6245ef0cad67531986 [file] [log] [blame]
Moshe Zadka1b07f2b2000-08-19 14:11:41 +00001\section{\module{Cookie} ---
Fred Drakee5c73522000-08-19 16:54:57 +00002 HTTP state management}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +00003
Fred Drakee5c73522000-08-19 16:54:57 +00004\declaremodule{standard}{Cookie}
5\modulesynopsis{Support for HTTP state management (cookies).}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +00006\moduleauthor{Timothy O'Malley}{timo@alum.mit.edu}
7\sectionauthor{Moshe Zadka}{moshez@zadka.site.co.il}
8
Moshe Zadka1b07f2b2000-08-19 14:11:41 +00009
10The \module{Cookie} module defines classes for abstracting the concept of
11Cookies, an HTTP state management mechanism. It supports both simplistic
12string-only cookies, and provides an abstraction for having any serializable
13data-type as cookie value.
14
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000015
16\begin{excdesc}{CookieError}
Fred Drakee5c73522000-08-19 16:54:57 +000017Exception failing because of \rfc{2109} invalidity: incorrect
18attributes, incorrect \code{Set-Cookie} header, etc.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000019\end{excdesc}
20
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000021
Fred Drakee5c73522000-08-19 16:54:57 +000022This used to be strict parsing based on the \rfc{2109} and \rfc{2068}
23specifications. I have since discovered that MSIE 3.0x doesn't
24follow the character rules outlined in those specs. As a
25result, the parsing rules here are less strict.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000026
Fred Drakee5c73522000-08-19 16:54:57 +000027\begin{classdesc}{BaseCookie}{\optional{input}}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000028This class is a dictionary-like object whose keys are strings and
29whose values are \class{Morsel}s. Note that upon setting a key to
30a value, the value is first converted to a \class{Morsel} containing
31the key and the value.
32
33If \var{input} is given, it is passed to the \method{load} method.
34\end{classdesc}
35
Fred Drakee5c73522000-08-19 16:54:57 +000036\begin{classdesc}{SimpleCookie}{\optional{input}}
37This class derives from \class{BaseCookie} and overrides \method{value_decode}
38and \method{value_encode} to be the identity and \function{str()} respectively.
39\end{classdesc}
40
41\begin{classdesc}{SerialCookie}{\optional{input}}
42This class derives from \class{BaseCookie} and overrides \method{value_decode}
43and \method{value_encode} to be the \function{pickle.loads()} and
44\function{pickle.dumps}. Note that using this class is a security hole,
45as arbitrary client-code can be run on \function{pickle.loads()}.
46\end{classdesc}
47
48\begin{classdesc}{SmartCookie}{\optional{input}}
49This class derives from \class{BaseCookie}. It overrides \method{value_decode}
50to be \function{pickle.loads()} if it is a valid pickle, and otherwise
51the value itself. It overrides \method{value_encode} to be
52\function{pickle.dumps()} unless it is a string, in which case it returns
53the value itself.
54
55The same security warning from \class{SerialCookie} applies here.
56\end{classdesc}
57
58
59\begin{seealso}
60 \seerfc{2109}{HTTP State Management Mechanism}{This is the state
61 management specification implemented by this module.}
62\end{seealso}
63
64
65\subsection{Cookie Objects \label{cookie-objects}}
66
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000067\begin{methoddesc}[BaseCookie]{value_decode}{val}
68Return a decoded value from a string representation. Return value can
69be any type. This method does nothing in \class{BaseCookie} --- it exists
70so it can be overridden.
71\end{methoddesc}
72
73\begin{methoddesc}[BaseCookie]{value_encode}{val}
74Return an encoded value. \var{val} can be any type, but return value
75must be a string. This method does nothing in \class{BaseCookie} --- it exists
76so it can be overridden
77
78In general, it should be the case that \method{value_encode} and
79\method{value_decode} are inverses on the range of \var{value_decode}.
80\end{methoddesc}.
81
Fred Drakee5c73522000-08-19 16:54:57 +000082\begin{methoddesc}[BaseCookie]{output}{\optional{attrs\optional{, header\optional{, sep}}}}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000083Return a string representation suitable to be sent as HTTP headers.
84\var{attrs} and \var{header} are sent to each \class{Morsel}'s \method{output}
85method. \var{sep} is used to join the headers together, and is by default
86a newline.
87\end{methoddesc}
88
Fred Drakee5c73522000-08-19 16:54:57 +000089\begin{methoddesc}[BaseCookie]{js_output}{\optional{attrs}}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000090Return an embeddable JavaScript snippet, which, if run on a browser which
91supports JavaScript, will act the same as if the HTTP headers was sent.
92
93The meaning for \var{attrs} is the same as in \method{output()}.
94\end{methoddesc}
95
96\begin{methoddesc}[BaseCookie]{load}{rawdata}
97If \var{rawdata} is a string, parse it as an \code{HTTP_COOKIE} and add
98the values found there as \class{Morsel}s. If it is a dictionary, it
Fred Drakee5c73522000-08-19 16:54:57 +000099is equivalent to:
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000100
101\begin{verbatim}
Fred Drakee5c73522000-08-19 16:54:57 +0000102for k, v in rawdata.items():
103 cookie[k] = v
104\end{verbatim}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000105\end{methoddesc}
106
Fred Drakee5c73522000-08-19 16:54:57 +0000107
108\subsection{Morsel Objects \label{morsel-objects}}
109
110\begin{classdesc}{Morsel}{}
111Abstract a key/value pair, which has some \rfc{2109} attributes.
112
113Morsels are dictionary-like objects, whose set of keys is constant ---
114the valid \rfc{2109} attributes, which are
115
116\begin{itemize}
117\item \code{expires}
118\item \code{path}
119\item \code{comment}
120\item \code{domain}
121\item \code{max-age}
122\item \code{secure}
123\item \code{version}
124\end{itemize}
125
126The keys are case-insensitive.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000127\end{classdesc}
128
Fred Drakee5c73522000-08-19 16:54:57 +0000129\begin{memberdesc}[Morsel]{value}
130The value of the cookie.
131\end{memberdesc}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000132
Fred Drakee5c73522000-08-19 16:54:57 +0000133\begin{memberdesc}[Morsel]{coded_value}
134The encoded value of the cookie --- this is what should be sent.
135\end{memberdesc}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000136
Fred Drakee5c73522000-08-19 16:54:57 +0000137\begin{memberdesc}[Morsel]{key}
138The name of the cookie.
139\end{memberdesc}
140
141\begin{methoddesc}[Morsel]{set}{key, value, coded_value}
142Set the \var{key}, \var{value} and \var{coded_value} members.
143\end{methoddesc}
144
145\begin{methoddesc}[Morsel]{isReservedKey}{K}
146Whether \var{K} is a member of the set of keys of a \class{Morsel}.
147\end{methoddesc}
148
149\begin{methoddesc}[Morsel]{output}{\optional{attrs\optional{, header}}}
150Return a string representation of the Morsel, suitable
151to be sent as an HTTP header. By default, all the attributes are included,
152unless \var{attrs} is given, in which case it should be a list of attributes
153to use. \var{header} is by default \code{"Set-Cookie:"}.
154\end{methoddesc}
155
156\begin{methoddesc}[Morsel]{js_output}{\optional{attrs}}
157Return an embeddable JavaScript snippet, which, if run on a browser which
158supports JavaScript, will act the same as if the HTTP header was sent.
159
160The meaning for \var{attrs} is the same as in \method{output()}.
161\end{methoddesc}.
162
163\begin{methoddesc}[Morsel]{OutputString}{\optional{attrs}}
164Return a string representing the Morsel, without any surrounding HTTP
165or JavaScript.
166
167The meaning for \var{attrs} is the same as in \method{output()}.
168\end{methoddesc}
169
170
171\subsection{Example \label{cookie-example}}
172
173The following example demonstrates how to open a can of spam using the
174\module{spam} module.
175
176\begin{verbatim}
177>>> import Cookie
178>>> C = Cookie.SimpleCookie()
179>>> C = Cookie.SerialCookie()
180>>> C = Cookie.SmartCookie()
181>>> C = Cookie.Cookie() # backwards compatible alias for SmartCookie
182>>> C = Cookie.SmartCookie()
183>>> C["fig"] = "newton"
184>>> C["sugar"] = "wafer"
185>>> C # generate HTTP headers
186Set-Cookie: sugar=wafer;
187Set-Cookie: fig=newton;
188>>> C = Cookie.SmartCookie()
189>>> C["rocky"] = "road"
190>>> C["rocky"]["path"] = "/cookie"
191>>> print C.output(header="Cookie:")
192Cookie: rocky=road; Path=/cookie;
193>>> print C.output(attrs=[], header="Cookie:")
194Cookie: rocky=road;
195>>> C = Cookie.SmartCookie()
196>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
197>>> C
198Set-Cookie: vienna=finger;
199Set-Cookie: chips=ahoy;
200>>> C = Cookie.SmartCookie()
201>>> C.load('keebler="E=everybody; L=\"Loves\"; fudge=\012;";')
202>>> C
203Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;";
204>>> C = Cookie.SmartCookie()
205>>> C["oreo"] = "doublestuff"
206>>> C["oreo"]["path"] = "/"
207>>> C
208Set-Cookie: oreo="doublestuff"; Path=/;
209>>> C = Cookie.SmartCookie()
210>>> C["twix"] = "none for you"
211>>> C["twix"].value
212'none for you'
213>>> C = Cookie.SimpleCookie()
214>>> C["number"] = 7 # equivalent to C["number"] = str(7)
215>>> C["string"] = "seven"
216>>> C["number"].value
217'7'
218>>> C["string"].value
219'seven'
220>>> C
221Set-Cookie: number=7;
222Set-Cookie: string=seven;
223>>> C = Cookie.SerialCookie()
224>>> C["number"] = 7
225>>> C["string"] = "seven"
226>>> C["number"].value
2277
228>>> C["string"].value
229'seven'
230>>> C
231Set-Cookie: number="I7\012.";
232Set-Cookie: string="S'seven'\012p1\012.";
233>>> C = Cookie.SmartCookie()
234>>> C["number"] = 7
235>>> C["string"] = "seven"
236>>> C["number"].value
2377
238>>> C["string"].value
239'seven'
240>>> C
241Set-Cookie: number="I7\012.";
242Set-Cookie: string=seven;
243\end{verbatim}