blob: 18468e747fd9ab08c0f050d1b6de6045ea30d05b [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
Eric S. Raymond83210262001-01-10 19:34:52 +000011cookies, an HTTP state management mechanism. It supports both simple
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000012string-only cookies, and provides an abstraction for having any serializable
13data-type as cookie value.
14
Andrew M. Kuchling120beb62000-08-20 23:33:50 +000015The module formerly strictly applied the parsing rules described in in
16the \rfc{2109} and \rfc{2068} specifications. It has since been discovered
17that MSIE 3.0x doesn't follow the character rules outlined in those
18specs. As a result, the parsing rules used are a bit less strict.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000019
20\begin{excdesc}{CookieError}
Fred Drakee5c73522000-08-19 16:54:57 +000021Exception failing because of \rfc{2109} invalidity: incorrect
22attributes, incorrect \code{Set-Cookie} header, etc.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000023\end{excdesc}
24
Fred Drakee5c73522000-08-19 16:54:57 +000025\begin{classdesc}{BaseCookie}{\optional{input}}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000026This class is a dictionary-like object whose keys are strings and
27whose values are \class{Morsel}s. Note that upon setting a key to
28a value, the value is first converted to a \class{Morsel} containing
29the key and the value.
30
Fred Drake58c95392001-06-29 16:21:47 +000031If \var{input} is given, it is passed to the \method{load()} method.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000032\end{classdesc}
33
Fred Drakee5c73522000-08-19 16:54:57 +000034\begin{classdesc}{SimpleCookie}{\optional{input}}
Fred Drake58c95392001-06-29 16:21:47 +000035This class derives from \class{BaseCookie} and overrides
36\method{value_decode()} and \method{value_encode()} to be the identity
37and \function{str()} respectively.
Fred Drakee5c73522000-08-19 16:54:57 +000038\end{classdesc}
39
40\begin{classdesc}{SerialCookie}{\optional{input}}
Fred Drake58c95392001-06-29 16:21:47 +000041This class derives from \class{BaseCookie} and overrides
42\method{value_decode()} and \method{value_encode()} to be the
43\function{pickle.loads()} and \function{pickle.dumps()}.
Andrew M. Kuchling120beb62000-08-20 23:33:50 +000044
Barry Warsaw0c0565d2001-11-16 22:28:17 +000045\strong{Do not use this class!} Reading pickled values from untrusted
46cookie data is a huge security hole, as pickle strings can be crafted
47to cause arbitrary code to execute on your server. It is supported
48for backwards compatibility only, and may eventually go away.
Fred Drakee5c73522000-08-19 16:54:57 +000049\end{classdesc}
50
51\begin{classdesc}{SmartCookie}{\optional{input}}
Fred Drake58c95392001-06-29 16:21:47 +000052This class derives from \class{BaseCookie}. It overrides
53\method{value_decode()} to be \function{pickle.loads()} if it is a
54valid pickle, and otherwise the value itself. It overrides
55\method{value_encode()} to be \function{pickle.dumps()} unless it is a
56string, in which case it returns the value itself.
Fred Drakee5c73522000-08-19 16:54:57 +000057
Barry Warsaw0c0565d2001-11-16 22:28:17 +000058\strong{Note:} The same security warning from \class{SerialCookie}
59applies here.
Fred Drakee5c73522000-08-19 16:54:57 +000060\end{classdesc}
61
Barry Warsaw0c0565d2001-11-16 22:28:17 +000062A further security note is warranted. For backwards compatibility,
63the \module{Cookie} module exports a class named \class{Cookie} which
64is just an alias for \class{SmartCookie}. This is probably a mistake
65and will likely be removed in a future version. You should not use
66the \class{Cookie} class in your applications, for the same reason why
67you should not use the \class{SerialCookie} class.
68
Fred Drakee5c73522000-08-19 16:54:57 +000069
70\begin{seealso}
71 \seerfc{2109}{HTTP State Management Mechanism}{This is the state
72 management specification implemented by this module.}
73\end{seealso}
74
75
76\subsection{Cookie Objects \label{cookie-objects}}
77
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000078\begin{methoddesc}[BaseCookie]{value_decode}{val}
79Return a decoded value from a string representation. Return value can
80be any type. This method does nothing in \class{BaseCookie} --- it exists
81so it can be overridden.
82\end{methoddesc}
83
84\begin{methoddesc}[BaseCookie]{value_encode}{val}
85Return an encoded value. \var{val} can be any type, but return value
86must be a string. This method does nothing in \class{BaseCookie} --- it exists
87so it can be overridden
88
Fred Drake58c95392001-06-29 16:21:47 +000089In general, it should be the case that \method{value_encode()} and
90\method{value_decode()} are inverses on the range of \var{value_decode}.
91\end{methoddesc}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000092
Fred Drakee5c73522000-08-19 16:54:57 +000093\begin{methoddesc}[BaseCookie]{output}{\optional{attrs\optional{, header\optional{, sep}}}}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000094Return a string representation suitable to be sent as HTTP headers.
Fred Drake58c95392001-06-29 16:21:47 +000095\var{attrs} and \var{header} are sent to each \class{Morsel}'s
96\method{output()} method. \var{sep} is used to join the headers
97together, and is by default a newline.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +000098\end{methoddesc}
99
Fred Drakee5c73522000-08-19 16:54:57 +0000100\begin{methoddesc}[BaseCookie]{js_output}{\optional{attrs}}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000101Return an embeddable JavaScript snippet, which, if run on a browser which
102supports JavaScript, will act the same as if the HTTP headers was sent.
103
104The meaning for \var{attrs} is the same as in \method{output()}.
105\end{methoddesc}
106
107\begin{methoddesc}[BaseCookie]{load}{rawdata}
108If \var{rawdata} is a string, parse it as an \code{HTTP_COOKIE} and add
109the values found there as \class{Morsel}s. If it is a dictionary, it
Fred Drakee5c73522000-08-19 16:54:57 +0000110is equivalent to:
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000111
112\begin{verbatim}
Fred Drakee5c73522000-08-19 16:54:57 +0000113for k, v in rawdata.items():
114 cookie[k] = v
115\end{verbatim}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000116\end{methoddesc}
117
Fred Drakee5c73522000-08-19 16:54:57 +0000118
119\subsection{Morsel Objects \label{morsel-objects}}
120
121\begin{classdesc}{Morsel}{}
122Abstract a key/value pair, which has some \rfc{2109} attributes.
123
124Morsels are dictionary-like objects, whose set of keys is constant ---
125the valid \rfc{2109} attributes, which are
126
127\begin{itemize}
128\item \code{expires}
129\item \code{path}
130\item \code{comment}
131\item \code{domain}
132\item \code{max-age}
133\item \code{secure}
134\item \code{version}
135\end{itemize}
136
137The keys are case-insensitive.
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000138\end{classdesc}
139
Fred Drakee5c73522000-08-19 16:54:57 +0000140\begin{memberdesc}[Morsel]{value}
141The value of the cookie.
142\end{memberdesc}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000143
Fred Drakee5c73522000-08-19 16:54:57 +0000144\begin{memberdesc}[Morsel]{coded_value}
145The encoded value of the cookie --- this is what should be sent.
146\end{memberdesc}
Moshe Zadka1b07f2b2000-08-19 14:11:41 +0000147
Fred Drakee5c73522000-08-19 16:54:57 +0000148\begin{memberdesc}[Morsel]{key}
149The name of the cookie.
150\end{memberdesc}
151
152\begin{methoddesc}[Morsel]{set}{key, value, coded_value}
153Set the \var{key}, \var{value} and \var{coded_value} members.
154\end{methoddesc}
155
156\begin{methoddesc}[Morsel]{isReservedKey}{K}
157Whether \var{K} is a member of the set of keys of a \class{Morsel}.
158\end{methoddesc}
159
160\begin{methoddesc}[Morsel]{output}{\optional{attrs\optional{, header}}}
161Return a string representation of the Morsel, suitable
162to be sent as an HTTP header. By default, all the attributes are included,
163unless \var{attrs} is given, in which case it should be a list of attributes
164to use. \var{header} is by default \code{"Set-Cookie:"}.
165\end{methoddesc}
166
167\begin{methoddesc}[Morsel]{js_output}{\optional{attrs}}
168Return an embeddable JavaScript snippet, which, if run on a browser which
169supports JavaScript, will act the same as if the HTTP header was sent.
170
171The meaning for \var{attrs} is the same as in \method{output()}.
Fred Drake58c95392001-06-29 16:21:47 +0000172\end{methoddesc}
Fred Drakee5c73522000-08-19 16:54:57 +0000173
174\begin{methoddesc}[Morsel]{OutputString}{\optional{attrs}}
175Return a string representing the Morsel, without any surrounding HTTP
176or JavaScript.
177
178The meaning for \var{attrs} is the same as in \method{output()}.
179\end{methoddesc}
180
181
182\subsection{Example \label{cookie-example}}
183
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000184The following example demonstrates how to use the \module{Cookie} module.
Fred Drakee5c73522000-08-19 16:54:57 +0000185
186\begin{verbatim}
187>>> import Cookie
188>>> C = Cookie.SimpleCookie()
189>>> C = Cookie.SerialCookie()
190>>> C = Cookie.SmartCookie()
Fred Drakee5c73522000-08-19 16:54:57 +0000191>>> C["fig"] = "newton"
192>>> C["sugar"] = "wafer"
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000193>>> print C # generate HTTP headers
194Set-Cookie: sugar=wafer;
195Set-Cookie: fig=newton;
196>>> print C.output() # same thing
Fred Drakee5c73522000-08-19 16:54:57 +0000197Set-Cookie: sugar=wafer;
198Set-Cookie: fig=newton;
199>>> C = Cookie.SmartCookie()
200>>> C["rocky"] = "road"
201>>> C["rocky"]["path"] = "/cookie"
202>>> print C.output(header="Cookie:")
203Cookie: rocky=road; Path=/cookie;
204>>> print C.output(attrs=[], header="Cookie:")
205Cookie: rocky=road;
206>>> C = Cookie.SmartCookie()
207>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000208>>> print C
Fred Drakee5c73522000-08-19 16:54:57 +0000209Set-Cookie: vienna=finger;
210Set-Cookie: chips=ahoy;
211>>> C = Cookie.SmartCookie()
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000212>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
213>>> print C
Fred Drakee5c73522000-08-19 16:54:57 +0000214Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;";
215>>> C = Cookie.SmartCookie()
216>>> C["oreo"] = "doublestuff"
217>>> C["oreo"]["path"] = "/"
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000218>>> print C
219Set-Cookie: oreo=doublestuff; Path=/;
Fred Drakee5c73522000-08-19 16:54:57 +0000220>>> C = Cookie.SmartCookie()
221>>> C["twix"] = "none for you"
222>>> C["twix"].value
223'none for you'
224>>> C = Cookie.SimpleCookie()
225>>> C["number"] = 7 # equivalent to C["number"] = str(7)
226>>> C["string"] = "seven"
227>>> C["number"].value
228'7'
229>>> C["string"].value
230'seven'
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000231>>> print C
Fred Drakee5c73522000-08-19 16:54:57 +0000232Set-Cookie: number=7;
233Set-Cookie: string=seven;
234>>> C = Cookie.SerialCookie()
235>>> C["number"] = 7
236>>> C["string"] = "seven"
237>>> C["number"].value
2387
239>>> C["string"].value
240'seven'
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000241>>> print C
Fred Drakee5c73522000-08-19 16:54:57 +0000242Set-Cookie: number="I7\012.";
243Set-Cookie: string="S'seven'\012p1\012.";
244>>> C = Cookie.SmartCookie()
245>>> C["number"] = 7
246>>> C["string"] = "seven"
247>>> C["number"].value
2487
249>>> C["string"].value
250'seven'
Ka-Ping Yee3a9582f2001-01-18 07:50:17 +0000251>>> print C
Fred Drakee5c73522000-08-19 16:54:57 +0000252Set-Cookie: number="I7\012.";
253Set-Cookie: string=seven;
254\end{verbatim}