SVN: r25347 - in trunk/quixote: . doc

Neil Schemenauer <nascheme-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Thu, 14 Oct 2004 13:34:29 -0400
Newsgroups gmane.comp.web.quixote.cvs
Message-ID <[email protected]>
Author: nascheme
Date: 2004-10-14 13:33:36 -0400 (Thu, 14 Oct 2004)
New Revision: 25347

Removed:
   trunk/quixote/doc/ZPL.txt
Modified:
   trunk/quixote/README
   trunk/quixote/http_request.py
   trunk/quixote/http_response.py
Log:
Rewrite parse_cookie() and rename it to parse_cookies().  When
generating cookies, escape quote characters that appear in cookie
values.  Remove Zope Public License and Zope license notes.  There is
essentially no Zope code remaining in Quixote.


Modified: trunk/quixote/README
===================================================================
--- trunk/quixote/README	2004-10-14 17:30:50 UTC (rev 25346)
+++ trunk/quixote/README	2004-10-14 17:33:36 UTC (rev 25347)
@@ -1,8 +1,8 @@
 Quixote
 =======
 
-Quixote is yet another framework for developing Web applications in
-Python.  The design goals were:
+Quixote is framework for developing Web applications in Python.  The
+design goals were:
 
   1) To allow easy development of Web applications where the
      emphasis is more on complicated programming logic than
@@ -25,20 +25,8 @@
 implementable in a week or two.  The initial version of Quixote was
 indeed cranked out in about that time -- thank you, Python!
 
-We've tried to reuse as much existing code as possible:
-
-  * The HTTPRequest and HTTPResponse classes are distantly
-    derived from their namesakes in Zope, but we've removed
-    huge amounts of Zope-specific code.
-
-  * The quixote.fcgi module is derived from Robin Dunn's FastCGI module,
-    available at
-      http://alldunn.com/python/#fcgi
-
-Quixote requires Python 2.1 or greater to run.  We only test Quixote
-with Python 2.3, but it should still work with 2.1 and 2.2.
-
-For installation instructions, see the doc/INSTALL.txt file (or
+Quixote requires Python 2.3 or greater to run.  For installation
+instructions, see the doc/INSTALL.txt file (or
 http://www.mems-exchange.org/software/quixote/doc/INSTALL.html).
 
 If you're switching to a newer version of Quixote from an older
@@ -128,7 +116,7 @@
 Authors, copyright, and license
 ===============================
 
-Copyright (c) 2000-2003 CNRI.
+Copyright (c) 2000-2004 CNRI.
 
 Quixote was primarily written by Andrew Kuchling, Neil Schemenauer, and
 Greg Ward.
@@ -136,8 +124,9 @@
 Overall, Quixote is covered by the CNRI Open Source License Agreement;
 see LICENSE for details.
 
-Portions of Quixote are derived from Zope, and are also covered by the
-ZPL (Zope Public License); see ZPL.txt.
+The quixote.fcgi module is derived from Robin Dunn's FastCGI module,
+available at http://alldunn.com/python/#fcgi.  Refer to the fcgi.py
+file for licensing terms.
 
 Full acknowledgments are in the ACKS file.
 
@@ -148,9 +137,8 @@
 The Quixote home page is:
     http://www.mems-exchange.org/software/quixote/
 
-You'll find the latest stable release there.  The current development
-code is also available via CVS; for instructions, see
-    http://www.mems-exchange.org/software/quixote/cvs.html
+You'll find the latest stable release there.  The development snapshots
+are also made available at times.
 
 Discussion of Quixote occurs on the quixote-users mailing list:
     http://mail.mems-exchange.org/mailman/listinfo/quixote-users/
@@ -158,9 +146,3 @@
 To follow development at the most detailed level by seeing every CVS
 checkin, join the quixote-checkins mailing list:
     http://mail.mems-exchange.org/mailman/listinfo/quixote-checkins/
-
-
--- 
-A.M. Kuchling    <akuchlin-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]>
-Neil Schemenauer <nascheme-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]>
-Greg Ward        <gward-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]>

Deleted: trunk/quixote/doc/ZPL.txt
===================================================================
--- trunk/quixote/doc/ZPL.txt	2004-10-14 17:30:50 UTC (rev 25346)
+++ trunk/quixote/doc/ZPL.txt	2004-10-14 17:33:36 UTC (rev 25347)
@@ -1,59 +0,0 @@
-Zope Public License (ZPL) Version 2.0
------------------------------------------------
-
-This software is Copyright (c) Zope Corporation (tm) and
-Contributors. All rights reserved.
-
-This license has been certified as open source. It has also
-been designated as GPL compatible by the Free Software
-Foundation (FSF).
-
-Redistribution and use in source and binary forms, with or
-without modification, are permitted provided that the
-following conditions are met:
-
-1. Redistributions in source code must retain the above
-   copyright notice, this list of conditions, and the following
-   disclaimer.
-
-2. Redistributions in binary form must reproduce the above
-   copyright notice, this list of conditions, and the following
-   disclaimer in the documentation and/or other materials
-   provided with the distribution.
-
-3. The name Zope Corporation (tm) must not be used to
-   endorse or promote products derived from this software
-   without prior written permission from Zope Corporation.
-
-4. The right to distribute this software or to use it for
-   any purpose does not give you the right to use Servicemarks
-   (sm) or Trademarks (tm) of Zope Corporation. Use of them is
-   covered in a separate agreement (see
-   http://www.zope.com/Marks).
-
-5. If any files are modified, you must cause the modified
-   files to carry prominent notices stating that you changed
-   the files and the date of any change.
-
-Disclaimer
-
-  THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS''
-  AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
-  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
-  NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE
-  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-  DAMAGE.
-
-
-This software consists of contributions made by Zope
-Corporation and many individuals on behalf of Zope
-Corporation.  Specific attributions are listed in the
-accompanying credits file.

Modified: trunk/quixote/http_request.py
===================================================================
--- trunk/quixote/http_request.py	2004-10-14 17:30:50 UTC (rev 25346)
+++ trunk/quixote/http_request.py	2004-10-14 17:33:36 UTC (rev 25347)
@@ -3,27 +3,9 @@
 $Id$
 
 Provides the HTTPRequest class and related code for parsing HTTP
-requests, such as the FileUpload class.
-
-Derived from Zope's HTTPRequest module (hence the different
-copyright and license from the rest of Quixote).
+requests, such as the Upload class.
 """
 
-##############################################################################
-#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-
-__revision__ = "$Id$"
-
 import re
 import string
 import tempfile
@@ -41,7 +23,7 @@
 # These are needed by 'get_encoding()', to parse the "Accept-Encoding"
 # header.  LWS is linear whitespace; the latter two assume that LWS
 # has been removed.
-_http_lws_re = re.compile("(\r\n)?[ \t]+")
+_http_lws_re = re.compile(r"(\r\n)?[ \t]+")
 _http_list_re = re.compile(r",+")
 _http_encoding_re = re.compile(r"([^;]+)(;q=([\d.]+))?$")
 
@@ -53,7 +35,7 @@
 #
 # The user_agent RE is a simplification; it only looks for one "product",
 # possibly followed by a comment.
-_http_token_pat = r'[^\x00-\x20\(\)\<\>\@\,\;\:\\\"\/\[\]\?\=\{\}\x7F-\xFF]+'
+_http_token_pat = r"[\w!#$%&'*+.^`|~-]+"
 _http_product_pat = r'(%s)(?:/(%s))?' % (_http_token_pat, _http_token_pat)
 _http_product_re = re.compile(_http_product_pat)
 _comment_delim_re = re.compile(r';\s*')
@@ -165,7 +147,7 @@
 
         k = self.environ.get('HTTP_COOKIE', '')
         if k:
-            self.cookies = parse_cookie(k)
+            self.cookies = parse_cookies(k)
         else:
             self.cookies = {}
 
@@ -548,42 +530,39 @@
         return self.response.redirect(location, permanent)
 
 
-_qparm_re = re.compile(r'([\0- ]*'
-                       r'([^\0- ;,=\"]+)="([^"]*)"'
-                       r'([\0- ]*[;,])?[\0- ]*)')
-_parm_re = re.compile(r'([\0- ]*'
-                      r'([^\0- ;,="]+)=([^\0- ;,"]*)'
-                      r'([\0- ]*[;,])?[\0- ]*)')
+# See RFC 2109 for details.  Note that this parser is more liberal.
+_COOKIE_RE = re.compile(r"""
+                \s*
+                (?P<name>[^=;,\s]+)
+                \s*
+                (
+                    =
+                    \s*
+                    (
+                        (?P<qvalue> "(\\[\x00-\x7f] | [^"])*")
+                        |
+                        (?P<value> [^";,\s]*)
+                    )
+                )?
+                \s*
+                [;,]?
+                """, re.VERBOSE)
 
-def parse_cookie(text):
+def parse_cookies(text):
     result = {}
-
-    pos = 0
-    while 1:
-        mq = _qparm_re.match(text, pos)
-        m = _parm_re.match(text, pos)
-        if mq is not None:
-            # Match quoted correct cookies
-            name = mq.group(2)
-            value = mq.group(3)
-            pos = mq.end()
-        elif m is not None:
-            # Match evil MSIE cookies ;)
-            name = m.group(2)
-            value = m.group(3)
-            pos = m.end()
+    for m in _COOKIE_RE.finditer(text):
+        name = m.group('name')
+        if name[0] == '$':
+            # discard, we don't handle per cookie attributes (e.g. $Path)
+            continue
+        qvalue = m.group('qvalue')
+        if qvalue:
+            value = re.sub(r'\\(.)', r'\1', qvalue)[1:-1]
         else:
-            # this may be an invalid cookie.
-            # We'll simply bail without raising an error
-            # if the cookie is invalid.
-            return result
-
-        if not result.has_key(name):
-            result[name] = value
-
+            value = m.group('value') or ''
+        result[name] = value
     return result
 
-
 SAFE_CHARS = string.letters + string.digits + "-@&+=_., "
 _safe_trans = None
 

Modified: trunk/quixote/http_response.py
===================================================================
--- trunk/quixote/http_response.py	2004-10-14 17:30:50 UTC (rev 25346)
+++ trunk/quixote/http_response.py	2004-10-14 17:33:36 UTC (rev 25347)
@@ -3,26 +3,8 @@
 $Id$
 
 Provides the HTTPResponse class.
-
-Derived from Zope's HTTPResponse module (hence the different
-copyright and license from the rest of Quixote).
 """
 
-##############################################################################
-#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-
-__revision__ = "$Id$"
-
 import time
 from rfc822 import formatdate
 
@@ -300,33 +282,24 @@
         Build a list of "Set-Cookie" headers based on all cookies
         set with 'set_cookie()', and return that list.
         """
-        cookie_list = []
-        for (name, attrs) in self.cookies.items():
-
-            # Note that as of May 98, IE4 ignores cookies with
-            # quoted cookie attr values, so only the value part
-            # of name=value pairs may be quoted.
-
-            # 'chunks' is a list of "name=val" chunks; will be joined
-            # with "; " to create the "Set-cookie" header.
-            chunks = ['%s="%s"' % (name, attrs['value'])]
-
-            for (name, val) in attrs.items():
+        cookie_headers = []
+        for name, attrs in self.cookies.items():
+            value = str(attrs['value'])
+            if '"' in value:
+                value = value.replace('"', '\\"')
+            chunks = ['%s="%s"' % (name, value)]
+            for name, val in attrs.items():
                 name = name.lower()
                 if val is None:
                     continue
                 if name in ('expires', 'domain', 'path', 'max_age', 'comment'):
                     name = name.replace('_', '-')
-                    chunks.append("%s=%s" % (name, val))
+                    chunks.append('%s=%s' % (name, val))
                 elif name == 'secure' and val:
                     chunks.append("secure")
+            cookie_headers.append(("Set-Cookie", '; '.join(chunks)))
+        return cookie_headers
 
-            cookie_list.append(("Set-Cookie", ("; ".join(chunks))))
-
-        # Should really check size of cookies here!
-
-        return cookie_list
-
     def generate_headers(self):
         """generate_headers() -> [(name:string, value:string)]