You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-commits@quetz.apache.org by gr...@apache.org on 2003/07/01 22:30:21 UTC
cvs commit: httpd-python/lib/python/mod_python Cookie.py
grisha 2003/07/01 13:30:21
Modified: Doc modpython4.tex
lib/python/mod_python Cookie.py
Log:
Cookie module documentation is now more or less complete along with some
examples. A couple of small things fixed in the Cookie module that were
discovered in the process of example testing.
Revision Changes Path
1.35 +157 -1 httpd-python/Doc/modpython4.tex
Index: modpython4.tex
===================================================================
RCS file: /home/cvs/httpd-python/Doc/modpython4.tex,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- modpython4.tex 30 Jun 2003 19:52:56 -0000 1.34
+++ modpython4.tex 1 Jul 2003 20:30:20 -0000 1.35
@@ -1479,7 +1479,7 @@
of the issues surrounding standardization of Cookies.}
\end{seealso}
-\subsection{Cookie classes\label{pyapi-cookie-classes}}
+\subsection{Classes\label{pyapi-cookie-classes}}
\begin{classdesc}{Cookie}{name, value\optional{, attributes}}
@@ -1488,13 +1488,169 @@
attributes defined in the Netscape specification and RFC2109 can by
supplied as keyword arguments.
+ The attributes of the class represent cookie attributes, and their
+ string representations become part of the string representation of
+ the cookie. The \class{Cookie} class restricts attribute names to
+ only valid values, specifically, only the following attributes are
+ allowed: \code{name, value, version, path, domain, secure, comment,
+ expires, max_age, commentURL, discard, port, __data__}.
+
+ The \code{__data__} attribute is a general-purpose dictionary that
+ can be used for storing arbitrary values, when necessary (This is
+ useful when subclassing \class{Cookie}).
+
+ The \member{expires} attribute is a property whose value is checked
+ upon setting to be in format \samp{Wdy, DD-Mon-YYYY HH:MM:SS GMT}
+ (as dictated per Netscape cookie specification), or a numeric value
+ representing time in seconds since Epoch (which will be
+ automatically correctly converted to GMT time string). An invalid
+ \code{expires} value will raise \exception{ValieError}.
+
+ When converted to a string, a \class{Cookie} will be in correct
+ format usable as value in a \samp{Cookie} or \samp{Set-Cookie}
+ header.
+
\begin{notice}
Unlike the Python Standard Library Cookie classes, this
class represents a single cookie (referred to as \dfn{Morsel} in
Python Standard Library).
\end{notice}
+ \begin{methoddesc}[Cookie]{parse}{string}
+ This is a class method that can be used to create a \class{Cookie}
+ instance from a cookie string \var{string} as passed in a header
+ value. During parsing, attribute names are converted to lower
+ case.
+
+ Because this is a class method, it must be called explicitely
+ specifying the class.
+
+ This method returns a dictionary of \class{Cookie} instances, not
+ a single \class{Cookie} instance.
+
+ Here is an example of getting a single \class{Cookie} instance:
+ \begin{verbatim}
+ mycookies = Cookie.parse("spam=eggs; expires=Sat, 14-Jun-2003 02:42:36 GMT")
+ spamcookie = mycookies["spam"]
+ \end{verbatim}
+
+ \begin{notice}
+ Because this method uses a dictionary, it is not possible to
+ have duplicate cookies. If you would like to have more than one
+ value in a single cookie, consider using a \class{MarshalCookie}.
+ \end{notice}
+
+ \end{methoddesc}
+
\end{classdesc}
+
+\begin{classdesc}{SignedCookie}{name, value, secret\optional{, attributes}}
+
+ This is a subclass of \class{Cookie}.
+
+ This class creates cookies whose name and value are automatically
+ signed using HMAC (md5) with a provided secret \var{secret}, which must be
+ a non-empty string.
+
+ \begin{methoddesc}[Cookie]{parse}{string}{secret}
+ This method acts the same way as \class{Cookie.parse()}, but also
+ verifies that the cookie is correctly signed. If the signature
+ cannot be verified, a \exception{CookieError} is raised.
+ \end{methoddesc}
+
+\end{classdesc}
+
+\begin{classdesc}{MarshalCookie}{name, value, secret\optional{, attributes}}
+
+ This is a subclass of \class{SignedCookie}. It allows for
+ \var{value} to be any marshallable objects. Core Python types such as
+ string, integer, list, etc. are all marshallable object. For a
+ complete list see
+ \citetitle[http://www.python.org/doc/current/lib/module-marshal.html]{marshal}
+ module documentation.
+
+ When parsing, the signature is checked first, so incorrectly signed cookies
+ will not be unmarshalled.
+
+\end{classdesc}
+
+\subsection{Functions\label{pyapi-cookie-func}}
+
+\begin{funcdesc}{setCookie}{req, cookie}
+ This is a convenience function for setting a cookie in request
+ headers. \var{req} is a mod_python \class{Request} object,
+ \var{cookie} is an object whose string representation is a valid
+ cookie. (Most often it is an instance of mod_python \class{Cookie}
+ or any of its subclasses).
+
+ This function will also set \samp{Cache-Control:
+ no-cache="set-cookie"} header to inform caches that the cookie value
+ should not be cached.
+\end{funcdesc}
+
+\begin{funcdesc}{getCookie}{req \optional{, Class, data}}
+ This is a convenience function for retrieving a cookie from incoming
+ headers. \var{req} is a mod_python \class{Request}
+ object. \var{Class} is a class whose \method{parse} method will be
+ used to parse the cookies, it defaults to \code{Cookie}. \var{Data}
+ is an optional argument which, if not \code{None}, will be passed as
+ the first argument to \method{parse} (This is useful for
+ \class{signedCookie} and \class{MarshalCookie} which require
+ \code{secret} as an additional argument to \method{parse}.
+\end{funcdesc}
+
+\subsection{Examples\label{pyapi-cookie-example}}
+
+This example sets a simple cookie which expires in 300 seconds:
+
+\begin{verbatim}
+from mod_python import Cookie, apache
+import time
+
+def handler(req):
+
+ cookie = Cookie.Cookie('eggs', 'spam')
+ cookie.expires = time.time() + 300
+ Cookie.setCookie(req, cookie)
+
+ req.write('This response contains a cookie!\n')
+ return apache.OK
+
+\end{verbatim}
+
+This example checks for incoming marshal cookie and displays it the
+client. If no incoming cookie is present a new marshal cookie is set.
+This example uses \samp{secret007} as the secret for HMAC signature.
+
+\begin{verbatim}
+from mod_python import apache, Cookie
+
+def handler(req):
+
+ try:
+ cookies = Cookie.getCookie(req, Cookie.MarshalCookie, \
+ 'secret007')
+ except Cookie.CookieError:
+ req.write('Cookie parsing error!\n')
+ return apache.OK
+
+ if cookies.has_key('spam'):
+ spamcookie = cookies['spam']
+ req.write('Great, a spam cookie was found: %s\n' \
+ % str(spamcookie))
+ req.write('Here is what it looks like decoded: %s=%s\n'
+ % (spamcookie.name, spamcookie.value))
+
+ else:
+
+ # MarshaCookie allows value to be any marshallable object
+ value = {'egg_count': 32, 'color': 'white'}
+ Cookie.setCookie(req, Cookie.MarshalCookie('spam', value, \
+ 'secret007'))
+ req.write('Spam cookie not found, but we just set one!\n')
+
+ return apache.OK
+\end{verbatim}
\section{\module{psp} -- Python Server Pages\label{pyapi-psp}}
\declaremodule[psp]{extension}{psp}
1.5 +4 -65 httpd-python/lib/python/mod_python/Cookie.py
Index: Cookie.py
===================================================================
RCS file: /home/cvs/httpd-python/lib/python/mod_python/Cookie.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Cookie.py 30 Jun 2003 18:04:35 -0000 1.4
+++ Cookie.py 1 Jul 2003 20:30:20 -0000 1.5
@@ -77,67 +77,6 @@
perhaps trying to be RFC-compliant (by automatically providing
Max-Age and Version) could be a waste of cookie space...
-
-Sample usage:
-
-A "Cookie" is a cookie, not a list of cookies as in std lib Cookie.py
-
-* making a cookie:
-
->>> c = Cookie("spam", "eggs")
->>> print c
-spam=eggs; version=1
->>> c.max_age = 3
->>> str(c)
-'spam=eggs; version=1; expires=Sat, 14-Jun-2003 02:42:36 GMT; max_age=3'
->>>
-
-* bogus attributes not allowed:
-
->>> c.eggs = 24
-Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- AttributeError: 'Cookie' object has no attribute 'eggs'
-
-* parsing (note the result is a dict of cookies)
-
->>> Cookie.parse(str(c))
-{'spam': <Cookie: spam=eggs; version=1; expires=Sat, 14-Jun-2003 02:42:36 GMT; max_age=3>}
->>>
-
-* signed cookies (uses hmac):
-
->>> sc = SignedCookie("spam", "eggs", "secret")
->>> print sc
-spam=da1170b718dfbad95c392db649d24898eggs; version=1
->>>
-
-* parsing signed cookies:
-
->>> SignedCookie.parse("secret", str(sc))
-{'spam': <SignedCookie: spam=da1170b718dfbad95c392db649d24898eggs; version=1>}
->>>
-
->>> SignedCookie.parse("evil", str(sc))
- [snip]
- Cookie.CookieError: Incorrectly Signed Cookie: spam=da1170b718dfbad95c392db649d24898eggs
->>>
-
-* marshal cookies (subclass of SignedCookie, so MUST be signed),
- also - this is marshal, not pickle (that would be too scary):
-
->>> mc = MarshalCookie("spam", {"eggs":24}, "secret")
->>> print mc
-spam=a90f71893109ca246ab68860f552302ce3MEAAAAZWdnc2kYAAAAMA==; version=1
->>>
-
->>> newmc = MarshalCookie.parse("secret", str(mc))
->>> print newmc["spam"]
-spam=a90f71893109ca246ab68860f552302ce3MEAAAAZWdnc2kYAAAAMA==; version=1
->>> newmc["spam"].value
-{'eggs': 24}
->>>
-
"""
import time
@@ -420,8 +359,8 @@
else:
# start a new cookie
- c = Class(key, val)
- result[key] = c
+ c = Class(l_key, val)
+ result[l_key] = c
return result
@@ -444,7 +383,7 @@
"""
if not req.headers_in.has_key("cookie"):
- return None
+ return {}
cookies = req.headers_in["cookie"]
if type(cookies) == type([]):