Parses a typical multi-valued and parametrised HTTP header (e.g. Accept headers) and returns a list of values and parameters. For non-standard or broken input, this implementation may return partial results. :param h: A header string (e.g. ``text/html,text/plain;q=0.9,*/*;q=0.8``) :
(h)
| 3006 | _hsplit = re.compile('(?:(?:"((?:[^"\\\\]|\\\\.)*)")|([^;,=]+))([;,=]?)').findall |
| 3007 | |
| 3008 | def _parse_http_header(h): |
| 3009 | """ Parses a typical multi-valued and parametrised HTTP header (e.g. Accept headers) and returns a list of values |
| 3010 | and parameters. For non-standard or broken input, this implementation may return partial results. |
| 3011 | :param h: A header string (e.g. ``text/html,text/plain;q=0.9,*/*;q=0.8``) |
| 3012 | :return: List of (value, params) tuples. The second element is a (possibly empty) dict. |
| 3013 | """ |
| 3014 | values = [] |
| 3015 | if '"' not in h: # INFO: Fast path without regexp (~2x faster) |
| 3016 | for value in h.split(','): |
| 3017 | parts = value.split(';') |
| 3018 | values.append((parts[0].strip(), {})) |
| 3019 | for attr in parts[1:]: |
| 3020 | name, value = attr.split('=', 1) |
| 3021 | values[-1][1][name.strip()] = value.strip() |
| 3022 | else: |
| 3023 | lop, key, attrs = ',', None, {} |
| 3024 | for quoted, plain, tok in _hsplit(h): |
| 3025 | value = plain.strip() if plain else quoted.replace('\\"', '"') |
| 3026 | if lop == ',': |
| 3027 | attrs = {} |
| 3028 | values.append((value, attrs)) |
| 3029 | elif lop == ';': |
| 3030 | if tok == '=': |
| 3031 | key = value |
| 3032 | else: |
| 3033 | attrs[value] = '' |
| 3034 | elif lop == '=' and key: |
| 3035 | attrs[key] = value |
| 3036 | key = None |
| 3037 | lop = tok |
| 3038 | return values |
| 3039 | |
| 3040 | |
| 3041 | def _parse_qsl(qs): |