summaryrefslogtreecommitdiffstats
path: root/Lib/cgi.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/cgi.py')
-rwxr-xr-xLib/cgi.py144
1 files changed, 62 insertions, 82 deletions
diff --git a/Lib/cgi.py b/Lib/cgi.py
index f31938b..db10a62 100755
--- a/Lib/cgi.py
+++ b/Lib/cgi.py
@@ -38,9 +38,19 @@ from operator import attrgetter
import sys
import os
import urllib
-import mimetools
-import rfc822
import UserDict
+import urlparse
+
+from warnings import filterwarnings, catch_warnings, warn
+with catch_warnings():
+ if sys.py3kwarning:
+ filterwarnings("ignore", ".*mimetools has been removed",
+ DeprecationWarning)
+ import mimetools
+ if sys.py3kwarning:
+ filterwarnings("ignore", ".*rfc822 has been removed", DeprecationWarning)
+ import rfc822
+
try:
from cStringIO import StringIO
except ImportError:
@@ -162,75 +172,24 @@ def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0):
else:
qs = ""
environ['QUERY_STRING'] = qs # XXX Shouldn't, really
- return parse_qs(qs, keep_blank_values, strict_parsing)
-
+ return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
-def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
- """Parse a query given as a string argument.
- Arguments:
+# parse query string function called from urlparse,
+# this is done in order to maintain backward compatiblity.
- qs: URL-encoded query string to be parsed
-
- keep_blank_values: flag indicating whether blank values in
- URL encoded queries should be treated as blank strings.
- A true value indicates that blanks should be retained as
- blank strings. The default false value indicates that
- blank values are to be ignored and treated as if they were
- not included.
+def parse_qs(qs, keep_blank_values=0, strict_parsing=0):
+ """Parse a query given as a string argument."""
+ warn("cgi.parse_qs is deprecated, use urlparse.parse_qs \
+ instead", PendingDeprecationWarning, 2)
+ return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
- strict_parsing: flag indicating what to do with parsing errors.
- If false (the default), errors are silently ignored.
- If true, errors raise a ValueError exception.
- """
- dict = {}
- for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
- if name in dict:
- dict[name].append(value)
- else:
- dict[name] = [value]
- return dict
def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
- """Parse a query given as a string argument.
-
- Arguments:
-
- qs: URL-encoded query string to be parsed
-
- keep_blank_values: flag indicating whether blank values in
- URL encoded queries should be treated as blank strings. A
- true value indicates that blanks should be retained as blank
- strings. The default false value indicates that blank values
- are to be ignored and treated as if they were not included.
-
- strict_parsing: flag indicating what to do with parsing errors. If
- false (the default), errors are silently ignored. If true,
- errors raise a ValueError exception.
-
- Returns a list, as G-d intended.
- """
- pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
- r = []
- for name_value in pairs:
- if not name_value and not strict_parsing:
- continue
- nv = name_value.split('=', 1)
- if len(nv) != 2:
- if strict_parsing:
- raise ValueError, "bad query field: %r" % (name_value,)
- # Handle case of a control-name with no equal sign
- if keep_blank_values:
- nv.append('')
- else:
- continue
- if len(nv[1]) or keep_blank_values:
- name = urllib.unquote(nv[0].replace('+', ' '))
- value = urllib.unquote(nv[1].replace('+', ' '))
- r.append((name, value))
-
- return r
-
+ """Parse a query given as a string argument."""
+ warn("cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead",
+ PendingDeprecationWarning, 2)
+ return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing)
def parse_multipart(fp, pdict):
"""Parse multipart input.
@@ -330,16 +289,28 @@ def parse_multipart(fp, pdict):
return partdict
+def _parseparam(s):
+ while s[:1] == ';':
+ s = s[1:]
+ end = s.find(';')
+ while end > 0 and s.count('"', 0, end) % 2:
+ end = s.find(';', end + 1)
+ if end < 0:
+ end = len(s)
+ f = s[:end]
+ yield f.strip()
+ s = s[end:]
+
def parse_header(line):
"""Parse a Content-type like header.
Return the main content-type and a dictionary of options.
"""
- plist = [x.strip() for x in line.split(';')]
- key = plist.pop(0).lower()
+ parts = _parseparam(';' + line)
+ key = parts.next()
pdict = {}
- for p in plist:
+ for p in parts:
i = p.find('=')
if i >= 0:
name = p[:i].strip().lower()
@@ -456,6 +427,7 @@ class FieldStorage:
self.strict_parsing = strict_parsing
if 'REQUEST_METHOD' in environ:
method = environ['REQUEST_METHOD'].upper()
+ self.qs_on_post = None
if method == 'GET' or method == 'HEAD':
if 'QUERY_STRING' in environ:
qs = environ['QUERY_STRING']
@@ -474,6 +446,8 @@ class FieldStorage:
headers['content-type'] = "application/x-www-form-urlencoded"
if 'CONTENT_TYPE' in environ:
headers['content-type'] = environ['CONTENT_TYPE']
+ if 'QUERY_STRING' in environ:
+ self.qs_on_post = environ['QUERY_STRING']
if 'CONTENT_LENGTH' in environ:
headers['content-length'] = environ['CONTENT_LENGTH']
self.fp = fp or sys.stdin
@@ -607,37 +581,35 @@ class FieldStorage:
"""Dictionary style keys() method."""
if self.list is None:
raise TypeError, "not indexable"
- keys = []
- for item in self.list:
- if item.name not in keys: keys.append(item.name)
- return keys
+ return list(set(item.name for item in self.list))
def has_key(self, key):
"""Dictionary style has_key() method."""
if self.list is None:
raise TypeError, "not indexable"
- for item in self.list:
- if item.name == key: return True
- return False
+ return any(item.name == key for item in self.list)
def __contains__(self, key):
"""Dictionary style __contains__ method."""
if self.list is None:
raise TypeError, "not indexable"
- for item in self.list:
- if item.name == key: return True
- return False
+ return any(item.name == key for item in self.list)
def __len__(self):
"""Dictionary style len(x) support."""
return len(self.keys())
+ def __nonzero__(self):
+ return bool(self.list)
+
def read_urlencoded(self):
"""Internal: read data in query string format."""
qs = self.fp.read(self.length)
+ if self.qs_on_post:
+ qs += '&' + self.qs_on_post
self.list = list = []
- for key, value in parse_qsl(qs, self.keep_blank_values,
- self.strict_parsing):
+ for key, value in urlparse.parse_qsl(qs, self.keep_blank_values,
+ self.strict_parsing):
list.append(MiniFieldStorage(key, value))
self.skip_lines()
@@ -649,6 +621,12 @@ class FieldStorage:
if not valid_boundary(ib):
raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
self.list = []
+ if self.qs_on_post:
+ for key, value in urlparse.parse_qsl(self.qs_on_post,
+ self.keep_blank_values, self.strict_parsing):
+ self.list.append(MiniFieldStorage(key, value))
+ FieldStorageClass = None
+
klass = self.FieldStorageClass or self.__class__
part = klass(self.fp, {}, ib,
environ, keep_blank_values, strict_parsing)
@@ -807,8 +785,10 @@ class FormContentDict(UserDict.UserDict):
form.dict == {key: [val, val, ...], ...}
"""
- def __init__(self, environ=os.environ):
- self.dict = self.data = parse(environ=environ)
+ def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0):
+ self.dict = self.data = parse(environ=environ,
+ keep_blank_values=keep_blank_values,
+ strict_parsing=strict_parsing)
self.query_string = environ['QUERY_STRING']