diff --git a/Doc/lib/libcookie.tex b/Doc/lib/libcookie.tex new file mode 100644 index 00000000000..19b5e078baf --- /dev/null +++ b/Doc/lib/libcookie.tex @@ -0,0 +1,232 @@ +\section{\module{Cookie} --- + RFC2109 HTTP State Management (AKA Cookies) Support} +\declaremodule{standard}{Cookie} + +\moduleauthor{Timothy O'Malley}{timo@alum.mit.edu} +\sectionauthor{Moshe Zadka}{moshez@zadka.site.co.il} + +\modulesynopsis{Support HTTP State Management (Cookies)} + +The \module{Cookie} module defines classes for abstracting the concept of +Cookies, an HTTP state management mechanism. It supports both simplistic +string-only cookies, and provides an abstraction for having any serializable +data-type as cookie value. + +\subsection{Example \label{cookie-example}} + +The following example demonstrates how to open a can of spam using the +\module{spam} module. + +\begin{verbatim} + >>> import Cookie + >>> C = Cookie.SimpleCookie() + >>> C = Cookie.SerialCookie() + >>> C = Cookie.SmartCookie() + >>> C = Cookie.Cookie() # backwards compatible alias for SmartCookie + >>> C = Cookie.SmartCookie() + >>> C["fig"] = "newton" + >>> C["sugar"] = "wafer" + >>> C # generate HTTP headers + Set-Cookie: sugar=wafer; + Set-Cookie: fig=newton; + >>> C = Cookie.SmartCookie() + >>> C["rocky"] = "road" + >>> C["rocky"]["path"] = "/cookie" + >>> print C.output(header="Cookie:") + Cookie: rocky=road; Path=/cookie; + >>> print C.output(attrs=[], header="Cookie:") + Cookie: rocky=road; + >>> C = Cookie.SmartCookie() + >>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header) + >>> C + Set-Cookie: vienna=finger; + Set-Cookie: chips=ahoy; + >>> C = Cookie.SmartCookie() + >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";') + >>> C + Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;"; + >>> C = Cookie.SmartCookie() + >>> C["oreo"] = "doublestuff" + >>> C["oreo"]["path"] = "/" + >>> C + Set-Cookie: oreo="doublestuff"; Path=/; + >>> C = Cookie.SmartCookie() + >>> C["twix"] = "none for you" + >>> C["twix"].value + 'none for you' + >>> C = Cookie.SimpleCookie() + >>> C["number"] = 7 # equivalent to C["number"] = str(7) + >>> C["string"] = "seven" + >>> C["number"].value + '7' + >>> C["string"].value + 'seven' + >>> C + Set-Cookie: number=7; + Set-Cookie: string=seven; + >>> C = Cookie.SerialCookie() + >>> C["number"] = 7 + >>> C["string"] = "seven" + >>> C["number"].value + 7 + >>> C["string"].value + 'seven' + >>> C + Set-Cookie: number="I7\012."; + Set-Cookie: string="S'seven'\012p1\012."; + >>> C = Cookie.SmartCookie() + >>> C["number"] = 7 + >>> C["string"] = "seven" + >>> C["number"].value + 7 + >>> C["string"].value + 'seven' + >>> C + Set-Cookie: number="I7\012."; + Set-Cookie: string=seven; +\end{verbatim} + +\begin{excdesc}{CookieError} +Exception failing because of RFC2109 invalidity: incorrect attributes, +incorrect \code{Set-Cookie} header, etc. +\end{excdesc} + +%\subsection{Morsel Objects} +%\label{morsel-objects} + +\begin{classdesc}{Morsel}{} +Abstract a key/value pair, which has some RFC2109 attributes. + +Morsels are dictionary-like objects, whose set of keys is constant --- +the valid RFC2109 attributes, which are + +\begin{itemize} + \item \code{expires} + \item \code{path} + \item \code{comment} + \item \code{domain} + \item \code{max-age} + \item \code{secure} + \item \code{version} + \end{itemize} +\end{itemize} + +The keys are case-insensitive. +\end{classdesc} + +\begin{memberdesc}[Morsel]{value} +The value of the cookie. +\end{methoddesc} + +\begin{memberdesc}[Morsel]{coded_value} +The encoded value of the cookie --- this is what should be sent. +\end{methoddesc} + + +\begin{memberdesc}[Morsel]{key} +The name of the cookie. +\end{methoddesc} + +\begin{methodesc}[Morsel]{set}{key, value, coded_value} +Set the \var{key}, \var{value} and \var{coded_value} members. +\end{methoddesc} + +\begin{methoddesc}[Morsel]{isReservedKey}{K} +Whether \var{K} is a member of the set of keys of a \class{Morsel}. +\end{methoddesc} + +\begin{methoddesc}[Morsel]{output}{\opt{attrs, \opt{header}} +Return a string representation of the Morsel, suitable +to be sent as an HTTP header. By default, all the attributes are included, +unless \var{attrs} is given, in which case it should be a list of attributes +to use. \var{header} is by default \code{"Set-Cookie:"}. +\end{methoddesc} + +\begin{methoddesc}[Morsel]{js_output}{\opt{attrs}} +Return an embeddable JavaScript snippet, which, if run on a browser which +supports JavaScript, will act the same as if the HTTP header was sent. + +The meaning for \var{attrs} is the same as in \method{output()}. +\end{methoddesc}. + +\begin{methoddesc}[Morsel]{OutputString}{\opt{attrs}} +Return a string representing the Morsel, without any surrounding HTTP +or JavaScript. + +The meaning for \var{attrs} is the same as in \method{output()}. +\end{methoddesc} + +# This used to be strict parsing based on the RFC2109 and RFC2068 +# specifications. I have since discovered that MSIE 3.0x doesn't +# follow the character rules outlined in those specs. As a +# result, the parsing rules here are less strict. + +\begin{classdesc}{BaseCookie}{\opt{input}} +This class is a dictionary-like object whose keys are strings and +whose values are \class{Morsel}s. Note that upon setting a key to +a value, the value is first converted to a \class{Morsel} containing +the key and the value. + +If \var{input} is given, it is passed to the \method{load} method. +\end{classdesc} + +\begin{methoddesc}[BaseCookie]{value_decode}{val} +Return a decoded value from a string representation. Return value can +be any type. This method does nothing in \class{BaseCookie} --- it exists +so it can be overridden. +\end{methoddesc} + +\begin{methoddesc}[BaseCookie]{value_encode}{val} +Return an encoded value. \var{val} can be any type, but return value +must be a string. This method does nothing in \class{BaseCookie} --- it exists +so it can be overridden + +In general, it should be the case that \method{value_encode} and +\method{value_decode} are inverses on the range of \var{value_decode}. +\end{methoddesc}. + +\begin{methoddesc}[BaseCookie]{output}{\opt{attrs\opt{, header\opt{, sep}}}} +Return a string representation suitable to be sent as HTTP headers. +\var{attrs} and \var{header} are sent to each \class{Morsel}'s \method{output} +method. \var{sep} is used to join the headers together, and is by default +a newline. +\end{methoddesc} + +\begin{methoddesc}[BaseCookie]{js_output}{\opt{attrs}} +Return an embeddable JavaScript snippet, which, if run on a browser which +supports JavaScript, will act the same as if the HTTP headers was sent. + +The meaning for \var{attrs} is the same as in \method{output()}. +\end{methoddesc} + +\begin{methoddesc}[BaseCookie]{load}{rawdata} +If \var{rawdata} is a string, parse it as an \code{HTTP_COOKIE} and add +the values found there as \class{Morsel}s. If it is a dictionary, it +is equivalent to calling + +\begin{verbatim} +map(BaseCookie.__setitem__, rawdata.keys(), rawdata.values()) +\end{varbatim} +\end{methoddesc} + +\begin{classdesc}{SimpleCookie}{\opt{input}} +This class derives from \class{BaseCookie} and overrides \method{value_decode} +and \method{value_encode} to be the identity and \function{str()} respectively. +\end{classdesc} + +\begin{classdesc}{SerialCookie}{\opt{input}} +This class derives from \class{BaseCookie} and overrides \method{value_decode} +and \method{value_encode} to be the \function{pickle.loads()} and +\function{pickle.dumps}. Note that using this class is a security hole, +as arbitrary client-code can be run on \function{pickle.loads()}. +\end{classdesc} + +\begin{classdesc}{SmartCookie}{\opt{input}} +This class derives from \class{BaseCookie}. It overrides \method{value_decode} +to be \function{pickle.loads()} if it is a valid pickle, and otherwise +the value itself. It overrides \method{value_encode} to be +\function{pickle.dumps()} unless it is a string, in which case it returns +the value itself. + +The same security warning from \class{SerialCookie} applies here. +\end{classdesc}