diff options
| author | Ira Lun <sammyrosajoe@gmail.com> | 2017-08-29 19:27:34 +0100 |
|---|---|---|
| committer | Ira Lun <sammyrosajoe@gmail.com> | 2017-08-29 19:48:37 +0100 |
| commit | 0d909b83e449e06ec71a89c18a96a4bf21406eda (patch) | |
| tree | 3317e32bdfc61debd52e2a5baf6bc57a186307da /src | |
| parent | 897da0ef7d586c755841051fb28fcdd0632231d6 (diff) | |
| download | webob-0d909b83e449e06ec71a89c18a96a4bf21406eda.tar.gz | |
Rewrite AcceptEncoding class and add docs and tests.
Diffstat (limited to 'src')
| -rw-r--r-- | src/webob/acceptparse.py | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/src/webob/acceptparse.py b/src/webob/acceptparse.py index 62fa9a5..7c286d6 100644 --- a/src/webob/acceptparse.py +++ b/src/webob/acceptparse.py @@ -292,11 +292,75 @@ class AcceptCharset(Accept): yield ('iso-8859-1', 1) -class AcceptEncoding(Accept): +class AcceptEncoding(object): """ - Represents an ``Accept-Encoding`` header. + Represent an ``Accept-Encoding`` header. + + Base class for :class:`AcceptEncodingValidHeader`, + :class:`AcceptEncodingNoHeader`, and :class:`AcceptEncodingInvalidHeader`. """ + # RFC 7231 Section 3.1.2.1 "Content Codings": + # content-coding = token + # Section 5.3.4 "Accept-Encoding": + # Accept-Encoding = #( codings [ weight ] ) + # codings = content-coding / "identity" / "*" + codings_re = token_re + # "identity" (case-insensitive) and "*" are both already included in token + # rule + codings_n_weight_re = _item_n_weight_re(item_re=codings_re) + codings_n_weight_compiled_re = re.compile(codings_n_weight_re) + accept_encoding_compiled_re = _list_0_or_more__compiled_re( + element_re=codings_n_weight_re, + ) + + @classmethod + def _python_value_to_header_str(cls, value): + if isinstance(value, str): + header_str = value + else: + if hasattr(value, 'items'): + value = sorted( + value.items(), + key=lambda item: item[1], + reverse=True, + ) + if isinstance(value, (tuple, list)): + result = [] + for item in value: + if isinstance(item, (tuple, list)): + item = _item_qvalue_pair_to_header_element(pair=item) + result.append(item) + header_str = ', '.join(result) + else: + header_str = str(value) + return header_str + + @classmethod + def parse(cls, value): + """ + Parse an ``Accept-Encoding`` header. + + :param value: (``str``) header value + :return: If `value` is a valid ``Accept-Encoding`` header, returns an + iterator of (codings, quality value) tuples, as parsed from + the header from left to right. + :raises ValueError: if `value` is an invalid header + """ + # Check if header is valid + # Using Python stdlib's `re` module, there is currently no way to check + # the match *and* get all the groups using the same regex, so we have + # to use one regex to check the match, and another to get the groups. + if cls.accept_encoding_compiled_re.match(value) is None: + raise ValueError('Invalid value for an Accept-Encoding header.') + def generator(value): + for match in (cls.codings_n_weight_compiled_re.finditer(value)): + codings = match.group(1) + qvalue = match.group(2) + qvalue = float(qvalue) if qvalue else 1.0 + yield (codings, qvalue) + return generator(value=value) + class AcceptLanguage(object): """ |
