Read environment, fixing HTTP variables
()
| 32 | or (k.startswith('REDIRECT_') and _needs_transcode(k[9:])) |
| 33 | |
| 34 | def read_environ(): |
| 35 | """Read environment, fixing HTTP variables""" |
| 36 | enc = sys.getfilesystemencoding() |
| 37 | esc = 'surrogateescape' |
| 38 | try: |
| 39 | ''.encode('utf-8', esc) |
| 40 | except LookupError: |
| 41 | esc = 'replace' |
| 42 | environ = {} |
| 43 | |
| 44 | # Take the basic environment from native-unicode os.environ. Attempt to |
| 45 | # fix up the variables that come from the HTTP request to compensate for |
| 46 | # the bytes->unicode decoding step that will already have taken place. |
| 47 | for k, v in os.environ.items(): |
| 48 | if _needs_transcode(k): |
| 49 | |
| 50 | # On win32, the os.environ is natively Unicode. Different servers |
| 51 | # decode the request bytes using different encodings. |
| 52 | if sys.platform == 'win32': |
| 53 | software = os.environ.get('SERVER_SOFTWARE', '').lower() |
| 54 | |
| 55 | # On IIS, the HTTP request will be decoded as UTF-8 as long |
| 56 | # as the input is a valid UTF-8 sequence. Otherwise it is |
| 57 | # decoded using the system code page (mbcs), with no way to |
| 58 | # detect this has happened. Because UTF-8 is the more likely |
| 59 | # encoding, and mbcs is inherently unreliable (an mbcs string |
| 60 | # that happens to be valid UTF-8 will not be decoded as mbcs) |
| 61 | # always recreate the original bytes as UTF-8. |
| 62 | if software.startswith('microsoft-iis/'): |
| 63 | v = v.encode('utf-8').decode('iso-8859-1') |
| 64 | |
| 65 | # Apache mod_cgi writes bytes-as-unicode (as if ISO-8859-1) direct |
| 66 | # to the Unicode environ. No modification needed. |
| 67 | elif software.startswith('apache/'): |
| 68 | pass |
| 69 | |
| 70 | # Python 3's http.server.CGIHTTPRequestHandler decodes |
| 71 | # using the urllib.unquote default of UTF-8, amongst other |
| 72 | # issues. |
| 73 | elif ( |
| 74 | software.startswith('simplehttp/') |
| 75 | and 'python/3' in software |
| 76 | ): |
| 77 | v = v.encode('utf-8').decode('iso-8859-1') |
| 78 | |
| 79 | # For other servers, guess that they have written bytes to |
| 80 | # the environ using stdio byte-oriented interfaces, ending up |
| 81 | # with the system code page. |
| 82 | else: |
| 83 | v = v.encode(enc, 'replace').decode('iso-8859-1') |
| 84 | |
| 85 | # Recover bytes from unicode environ, using surrogate escapes |
| 86 | # where available (Python 3.1+). |
| 87 | else: |
| 88 | v = v.encode(enc, esc).decode('iso-8859-1') |
| 89 | |
| 90 | environ[k] = v |
| 91 | return environ |
no test coverage detected