| | 1 | """ |
| | 2 | Provides updated (to 2.5.1) versions of the standard cgi.parse_qs, |
| | 3 | cgi.parse_qsl and cgi.parse_header functions for Python < 2.3.5. |
| | 4 | The last two have had bugfixes since then. |
| | 5 | """ |
| | 6 | |
| | 7 | # Relevant revisions from Python svn: |
| | 8 | # |
| | 9 | # 34965 = Python 2.3.3 |
| | 10 | # 35532 Change parse_qsl() to accept control-name's with no equal sign |
| | 11 | # (e.g., "name") when keep_blank_values is true. |
| | 12 | # 35974 = Python 2.3.4 |
| | 13 | # 36582 Don't return spurious empty fields if 'keep_empty_values' is True. |
| | 14 | # 36995 Let cgi.parse_header() properly unquote headers. |
| | 15 | # 37906 = Python 2.4 |
| | 16 | # 38447 = Python 2.3.5 |
| | 17 | |
| | 18 | import urllib |
| | 19 | |
| | 20 | def parse_qs(qs, keep_blank_values=0, strict_parsing=0): |
| | 21 | """Parse a query given as a string argument. |
| | 22 | |
| | 23 | Arguments: |
| | 24 | |
| | 25 | qs: URL-encoded query string to be parsed |
| | 26 | |
| | 27 | keep_blank_values: flag indicating whether blank values in |
| | 28 | URL encoded queries should be treated as blank strings. |
| | 29 | A true value indicates that blanks should be retained as |
| | 30 | blank strings. The default false value indicates that |
| | 31 | blank values are to be ignored and treated as if they were |
| | 32 | not included. |
| | 33 | |
| | 34 | strict_parsing: flag indicating what to do with parsing errors. |
| | 35 | If false (the default), errors are silently ignored. |
| | 36 | If true, errors raise a ValueError exception. |
| | 37 | """ |
| | 38 | dict = {} |
| | 39 | for name, value in parse_qsl(qs, keep_blank_values, strict_parsing): |
| | 40 | if name in dict: |
| | 41 | dict[name].append(value) |
| | 42 | else: |
| | 43 | dict[name] = [value] |
| | 44 | return dict |
| | 45 | |
| | 46 | def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): |
| | 47 | """Parse a query given as a string argument. |
| | 48 | |
| | 49 | Arguments: |
| | 50 | |
| | 51 | qs: URL-encoded query string to be parsed |
| | 52 | |
| | 53 | keep_blank_values: flag indicating whether blank values in |
| | 54 | URL encoded queries should be treated as blank strings. A |
| | 55 | true value indicates that blanks should be retained as blank |
| | 56 | strings. The default false value indicates that blank values |
| | 57 | are to be ignored and treated as if they were not included. |
| | 58 | |
| | 59 | strict_parsing: flag indicating what to do with parsing errors. If |
| | 60 | false (the default), errors are silently ignored. If true, |
| | 61 | errors raise a ValueError exception. |
| | 62 | |
| | 63 | Returns a list, as G-d intended. |
| | 64 | """ |
| | 65 | pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] |
| | 66 | r = [] |
| | 67 | for name_value in pairs: |
| | 68 | if not name_value and not strict_parsing: |
| | 69 | continue |
| | 70 | nv = name_value.split('=', 1) |
| | 71 | if len(nv) != 2: |
| | 72 | if strict_parsing: |
| | 73 | raise ValueError, "bad query field: %r" % (name_value,) |
| | 74 | # Handle case of a control-name with no equal sign |
| | 75 | if keep_blank_values: |
| | 76 | nv.append('') |
| | 77 | else: |
| | 78 | continue |
| | 79 | if len(nv[1]) or keep_blank_values: |
| | 80 | name = urllib.unquote(nv[0].replace('+', ' ')) |
| | 81 | value = urllib.unquote(nv[1].replace('+', ' ')) |
| | 82 | r.append((name, value)) |
| | 83 | |
| | 84 | return r |
| | 85 | |
| | 86 | def parse_header(line): |
| | 87 | """Parse a Content-type like header. |
| | 88 | |
| | 89 | Return the main content-type and a dictionary of options. |
| | 90 | |
| | 91 | """ |
| | 92 | plist = [x.strip() for x in line.split(';')] |
| | 93 | key = plist.pop(0).lower() |
| | 94 | pdict = {} |
| | 95 | for p in plist: |
| | 96 | i = p.find('=') |
| | 97 | if i >= 0: |
| | 98 | name = p[:i].strip().lower() |
| | 99 | value = p[i+1:].strip() |
| | 100 | if len(value) >= 2 and value[0] == value[-1] == '"': |
| | 101 | value = value[1:-1] |
| | 102 | value = value.replace('\\\\', '\\').replace('\\"', '"') |
| | 103 | pdict[name] = value |
| | 104 | return key, pdict |