Mercurial > p > roundup > code
changeset 3916:57ad3e2c2545
handle bad cookies
Roundup's cgi gets all cookies from all apps on the same server. some
apps aren't as well behaved as roundup and generate cookies that do
not follow the spec perfectly. This causes python's Cookie module to
throw an exception when trying to parse them. In the spirit of being
liberal in what we accept, we create a LiberalCookie class that can
handle those out-of-spec cookies and allow roundup to continue onward.
[SF#1691708]
code from S. Woodside
| author | Justus Pendleton <jpend@users.sourceforge.net> |
|---|---|
| date | Sat, 22 Sep 2007 21:20:57 +0000 |
| parents | 6b3919328381 |
| children | 1f3310c0a100 |
| files | roundup/cgi/client.py |
| diffstat | 1 files changed, 40 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/roundup/cgi/client.py Sat Sep 22 07:25:35 2007 +0000 +++ b/roundup/cgi/client.py Sat Sep 22 21:20:57 2007 +0000 @@ -1,4 +1,4 @@ -# $Id: client.py,v 1.237 2007-09-12 16:16:49 jpend Exp $ +# $Id: client.py,v 1.238 2007-09-22 21:20:57 jpend Exp $ """WWW request handler (also used in the stand-alone server). """ @@ -7,6 +7,7 @@ import base64, binascii, cgi, codecs, mimetypes, os import random, re, rfc822, stat, time, urllib, urlparse import Cookie, socket, errno +from Cookie import CookieError, BaseCookie, SimpleCookie from roundup import roundupdb, date, hyperdb, password from roundup.cgi import templating, cgitb, TranslationService @@ -46,12 +47,47 @@ return match.group(1) return '<%s>'%match.group(2) + error_message = ""'''<html><head><title>An error has occurred</title></head> <body><h1>An error has occurred</h1> <p>A problem was encountered processing your request. The tracker maintainers have been notified of the problem.</p> </body></html>''' + +class LiberalCookie(SimpleCookie): + ''' Python's SimpleCookie throws an exception if the cookie uses invalid + syntax. Other applications on the same server may have done precisely + this, preventing roundup from working through no fault of roundup. + Numerous other python apps have run into the same problem: + + trac: http://trac.edgewall.org/ticket/2256 + mailman: http://bugs.python.org/issue472646 + + This particular implementation comes from trac's solution to the + problem. Unfortunately it requires some hackery in SimpleCookie's + internals to provide a more liberal __set method. + ''' + def load(self, rawdata, ignore_parse_errors=True): + if ignore_parse_errors: + self.bad_cookies = [] + self._BaseCookie__set = self._loose_set + SimpleCookie.load(self, rawdata) + if ignore_parse_errors: + self._BaseCookie__set = self._strict_set + for key in self.bad_cookies: + del self[key] + + _strict_set = BaseCookie._BaseCookie__set + + def _loose_set(self, key, real_value, coded_value): + try: + self._strict_set(key, real_value, coded_value) + except CookieError: + self.bad_cookies.append(key) + dict.__setitem__(self, key, None) + + class Client: '''Instantiate to handle one CGI request. @@ -181,7 +217,9 @@ self.charset = self.STORAGE_CHARSET # parse cookies (used in charset and session lookups) - self.cookie = Cookie.SimpleCookie(self.env.get('HTTP_COOKIE', '')) + # use our own LiberalCookie to handle bad apps on the same + # server that have set cookies that are out of spec + self.cookie = LiberalCookie(self.env.get('HTTP_COOKIE', '')) self.user = None self.userid = None
