From a34762ab857cc7e2fd37ac84ca5ccf58b2cfcbe6 Mon Sep 17 00:00:00 2001 From: bwarsaw Date: Fri, 8 Jan 1999 06:04:22 +0000 Subject: Changes to workaround some bogus clients which either don't include a content-type header, or include a bogus one. cgi.py FieldStorage.__init__(): if there is no content-type header, use text/plain for inner parts, but application/x-www-form-urlencoded for outer parts. Honor any existing content-type header. Lower down, if the content-type header is something we don't understand, default to text/plain for inner parts, but application/x-www-form-urlencoded for outer parts. This patch will be proposed for Python 1.5.2 driver run_main(): Play some games to get Mailman's special cgi.py module. We import it from Mailman.pythonlib.cgi, but then we jam this module into sys.modules['cgi'] so all those imports in all those Mailman.Cgi scripts get our special one (without having to hack all those scripts!) --- Mailman/pythonlib/cgi.py | 26 ++++++++++++++++++++++++-- scripts/driver | 10 ++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Mailman/pythonlib/cgi.py b/Mailman/pythonlib/cgi.py index 108310ebd..ab6dda843 100755 --- a/Mailman/pythonlib/cgi.py +++ b/Mailman/pythonlib/cgi.py @@ -828,9 +828,23 @@ class FieldStorage: self.filename = pdict['filename'] # Process content-type header - ctype, pdict = "text/plain", {} + # + # Honor any existing content-type header. But if there is no + # content-type header, use some sensible defaults. Assume + # outerboundary is "" at the outer level, but something non-false + # inside a multi-part. The default for an inner part is text/plain, + # but for an outer part it should be urlencoded. This should catch + # bogus clients which erroneously forget to include a content-type + # header. + # + # See below for what we do if there does exist a content-type header, + # but it happens to be something we don't understand. if self.headers.has_key('content-type'): ctype, pdict = parse_header(self.headers['content-type']) + elif self.outerboundary: + ctype, pdict = "text/plain", {} + else: + ctype, pdict = 'application/x-www-form-urlencoded', {} self.type = ctype self.type_options = pdict self.innerboundary = "" @@ -853,8 +867,16 @@ class FieldStorage: self.read_urlencoded() elif ctype[:10] == 'multipart/': self.read_multi(environ, keep_blank_values, strict_parsing) - else: + elif self.outerboundary: + # we're in an inner part, but the content-type wasn't something we + # understood. default to read_single() because the resulting + # FieldStorage won't be a mapping (and doesn't need to be). self.read_single() + else: + # we're in an outer part, but the content-type wasn't something we + # understood. we still want the resulting FieldStorage to be a + # mapping, so parse it as if it were urlencoded + self.read_urlencoded() def __repr__(self): """Return a printable representation.""" diff --git a/scripts/driver b/scripts/driver index 8b5c9a2a5..c09f2f576 100644 --- a/scripts/driver +++ b/scripts/driver @@ -87,6 +87,16 @@ def run_main(): manual_reprime=1, nofail=0, immediate=1) + # pre-load the `cgi' module. we do this because we're distributing a + # slightly different version than the standard Python module. it's + # essentially Python 1.5.2's module, with an experimental patch to + # handle clients that give bogus or non-existant content-type headers. + # + # we assign sys.modules['cgi'] to this special cgi module because we + # don't want to have to rewrite all the Mailman.Cgi modules to get the + # special one. + import Mailman.pythonlib.cgi + sys.modules['cgi'] = Mailman.pythonlib.cgi # The name of the module to run is passed in argv[1]. What we # actually do is import the module named by argv[1] that lives in the # Mailman.Cgi package. That module must have a main() function, which -- cgit v1.3.1