Esempio n. 1
0
def comment(include_parens=False):
    inner = recursive() > named(u'comment', RFC(7230))
    inner.rec = '(' + string(ctext | quoted_pair(sensible_for=u'()\\') |
                             inner) + ')'
    if not include_parens:
        inner = (lambda s: s[1:-1]) << inner
    return inner > named(u'comment', RFC(7230))
Esempio n. 2
0
def test_parser_edge_cases():
    # Our parser implementation is general enough that
    # some of its branches are not being exercised by our regular tests,
    # so I had to come up with these contrived examples to test them.

    p = many(rfc7230.tchar)                            > named(u'p')
    p1 = '1' * p                                       > named(u'p1')
    p2 = '11' * p * skip('\n')                         > named(u'p2')
    assert parse(p1 | p2, b'11abc') == (u'1', [u'1', u'a', u'b', u'c'])
    assert parse(p1 | p2, b'11abc\n') == (u'11', [u'a', u'b', u'c'])

    p = recursive()                                    > named(u'p')
    p.rec = (rfc7230.tchar * p | subst(None) << empty)
    assert parse(p, b'abc') == (u'a', (u'b', (u'c', None)))

    p = literal('ab')                                  > named(u'p')
    p0 = subst(u'') << empty | p                       > named(u'p0')
    p1 = 'xab' * p0                                    > named(u'p1')
    p2 = 'x' * string(p0) * '!'                        > named(u'p2')
    assert parse(p1 | p2, b'xabab') == (u'xab', u'ab')
    assert parse(p1 | p2, b'xabab!') == (u'x', u'abab', u'!')

    p = empty | literal('a')                           > named(u'p')
    p0 = p * 'x'                                       > named(u'x')
    assert parse(p0, b'x') == u'x'
Esempio n. 3
0
def test_parser_edge_cases():
    # Our parser implementation is general enough that
    # some of its branches are not being exercised by our regular tests,
    # so I had to come up with these contrived examples to test them.

    p = many(rfc7230.tchar)                            > named(u'p')
    p1 = '1' * p                                       > named(u'p1')
    p2 = '11' * p * skip('\n')                         > named(u'p2')
    assert parse(p1 | p2, b'11abc') == (u'1', [u'1', u'a', u'b', u'c'])
    assert parse(p1 | p2, b'11abc\n') == (u'11', [u'a', u'b', u'c'])

    p = recursive()                                    > named(u'p')
    p.rec = (rfc7230.tchar * p | subst(None) << empty)
    assert parse(p, b'abc') == (u'a', (u'b', (u'c', None)))

    p = literal('ab')                                  > named(u'p')
    p0 = subst(u'') << empty | p                       > named(u'p0')
    p1 = 'xab' * p0                                    > named(u'p1')
    p2 = 'x' * string(p0) * '!'                        > named(u'p2')
    assert parse(p1 | p2, b'xabab') == (u'xab', u'ab')
    assert parse(p1 | p2, b'xabab!') == (u'x', u'abab', u'!')

    p = empty | literal('a')                           > named(u'p')
    p0 = p * 'x'                                       > named(u'x')
    assert parse(p0, b'x') == u'x'
Esempio n. 4
0
def comment(include_parens=False):
    inner = recursive() > named(u'comment', RFC(7230))
    inner.rec = '(' + string(ctext | quoted_pair(sensible_for=u'()\\')
                             | inner) + ')'
    if not include_parens:
        inner = (lambda s: s[1:-1]) << inner
    return inner > named(u'comment', RFC(7230))
Esempio n. 5
0
def preference_parameter(head=False):
    # The head (first) ``preference-parameter`` of a ``preference``
    # contains the actual preference name, which we want to annotate.
    name_cls = Preference if head else CaseInsensitive
    return (_normalize_empty_value <<
            (parameter(name_cls=name_cls) | name_cls << token)) > named(
                u'preference-parameter', RFC(7240, errata=4439), is_pivot=True)
Esempio n. 6
0
def preference_parameter(head=False):
    # The head (first) ``preference-parameter`` of a ``preference``
    # contains the actual preference name, which we want to annotate.
    name_cls = Preference if head else CaseInsensitive
    return (
        _normalize_empty_value << (parameter(name_cls=name_cls) |
                                   name_cls << token)
    ) > named(u'preference-parameter', RFC(7240, errata=4439), is_pivot=True)
Esempio n. 7
0
def transfer_coding(no_trailers=False, no_q=False):
    exclude = _built_in_codings
    if no_trailers:
        exclude = exclude + ['trailers']
    r = transfer_extension(exclude, no_q)
    for name in _built_in_codings:
        r = r | _empty_params << (TransferCoding << literal(name))
    return r > named(u'transfer-coding', RFC(7230), is_pivot=True)
Esempio n. 8
0
def transfer_coding(no_trailers=False, no_q=False):
    exclude = _built_in_codings
    if no_trailers:
        exclude = exclude + ['trailers']
    r = transfer_extension(exclude, no_q)
    for name in _built_in_codings:
        r = r | _empty_params << (TransferCoding << literal(name))
    return r > named(u'transfer-coding', RFC(7230), is_pivot=True)
Esempio n. 9
0
def quoted_pair(sensible_for):
    # In RFC 7230, ``<quoted-pair>`` is a single rule,
    # but we parametrize it to report no. 1017 depending on the context.
    @can_complain
    def check_sensible(complain, c):
        if c not in sensible_for:
            complain(1017, char=c)
        return c
    return (check_sensible << skip('\\') * (HTAB | SP | VCHAR | obs_text)
            > named(u'quoted-pair', RFC(7230)))
Esempio n. 10
0
def quoted_pair(sensible_for):
    # In RFC 7230, ``<quoted-pair>`` is a single rule,
    # but we parametrize it to report no. 1017 depending on the context.
    @can_complain
    def check_sensible(complain, c):
        if c not in sensible_for:
            complain(1017, char=c)
        return c

    return (check_sensible << skip('\\') *
            (HTAB | SP | VCHAR | obs_text) > named(u'quoted-pair', RFC(7230)))
Esempio n. 11
0
def media_range(no_q=False):
    return Parametrized << (
        (
            literal('*/*') |
            type_ + '/' + '*' |
            MediaType << type_ + '/' + subtype
        ) *
        (
            MultiDict << many(
                skip(OWS * ';' * OWS) *
                parameter(exclude=['q'] if no_q else [])
            )
        )
    ) > named(u'media-range', RFC(7231), is_pivot=True)
Esempio n. 12
0
def link_extension(exclude_builtin):
    if exclude_builtin:
        exclude1 = [name for name in _builtin_params if not name.endswith('*')]
        exclude2 = [name.rstrip('*')
                    for name in _builtin_params if name.endswith('*')]
    else:       # pragma: no cover
        exclude1 = exclude2 = None
    return (
        (
            (CaseInsensitive << parmname__excluding(exclude1)) *
            maybe(skip(OWS * '=' * OWS) * (ptoken | quoted_string))
        ) |
        (
            (CaseInsensitive << ext_name_star__excluding(exclude2)) *
            skip(OWS * '=' * OWS) * ext_value
        )
    ) > named(u'link-extension', RFC(5988), is_pivot=True)
Esempio n. 13
0
def link_extension(exclude_builtin):
    if exclude_builtin:
        exclude1 = [name for name in _builtin_params if not name.endswith('*')]
        exclude2 = [name.rstrip('*')
                    for name in _builtin_params if name.endswith('*')]
    else:
        exclude1 = exclude2 = None
    return (
        (
            (CaseInsensitive << parmname__excluding(exclude1)) *
            maybe(skip(OWS * '=' * OWS) * (ptoken | quoted_string))
        ) |
        (
            (CaseInsensitive << ext_name_star__excluding(exclude2)) *
            skip(OWS * '=' * OWS) * ext_value
        )
    ) > named(u'link-extension', RFC(5988), is_pivot=True)
Esempio n. 14
0
    # RFC 7240 Section 2: "Empty or zero-length values on both
    # the preference token and within parameters are equivalent
    # to no value being specified at all."
    (name, value) = x if isinstance(x, tuple) else (x, None)
    return Parametrized(name, None if value == u'' else value)

def preference_parameter(head=False):
    # The head (first) ``preference-parameter`` of a ``preference``
    # contains the actual preference name, which we want to annotate.
    name_cls = Preference if head else CaseInsensitive
    return (
        _normalize_empty_value << (parameter(name_cls=name_cls) |
                                   name_cls << token)
    ) > named(u'preference-parameter', RFC(7240, errata=4439), is_pivot=True)

preference = Parametrized << (
    preference_parameter(head=True) *
    many(skip(OWS * ';') * maybe(skip(OWS) * preference_parameter()))
) > named(u'preference', RFC(7240, errata=4439), is_pivot=True)

Prefer = comma_list1(preference)                                        > pivot

Preference_Applied = comma_list1(preference_parameter(head=True))       > pivot


return_ = CaseInsensitive << (literal('representation') | 'minimal')    > pivot
wait = delay_seconds                                                    > auto
handling = CaseInsensitive << (literal('strict') | 'lenient')           > pivot

fill_names(globals(), RFC(7240))
Esempio n. 15
0
def transfer_extension(exclude=None, no_q=False):
    return Parametrized << (
        (TransferCoding << token__excluding(exclude or [])) *
        (MultiDict << many(skip(OWS * ';' * OWS) * transfer_parameter(no_q)))
    ) > named(u'transfer-extension', RFC(7230), is_pivot=True)
Esempio n. 16
0
def transfer_parameter(no_q=False):
    return (
        (token__excluding(['q']) if no_q else token) *
        skip(BWS * '=' * BWS) * (token | quoted_string)
    ) > named(u'transfer-parameter', RFC(7230), is_pivot=True)
Esempio n. 17
0
def ext_name_star__excluding(exclude):
    return (parmname__excluding(exclude) + '*'
            > named(u'ext-name-star', RFC(5988)))
Esempio n. 18
0
def comma_list1(element):
    return _collect_elements << (
        many(subst(None) << ',' * OWS) +
        ((lambda x: [x]) << group(element)) +
        many(skip(OWS * ',') * maybe(skip(OWS) * element))
    ) > named(u'1#rule', RFC(7230, section=(7,)))
Esempio n. 19
0
def comma_list(element):
    # RFC Errata ID: 5257
    return _collect_elements << (maybe(group(element) * skip(OWS)) % many(
        skip(literal(',') * OWS) * maybe(group(element) * skip(OWS)))) > named(
            u'#rule', RFC(7230, section=u'7'))
Esempio n. 20
0
def comma_list(element):
    # RFC Errata ID: 5257
    return _collect_elements << (
        maybe(group(element) * skip(OWS)) %
        many(skip(literal(',') * OWS) * maybe(group(element) * skip(OWS)))
    ) > named(u'#rule', RFC(7230, section=u'7'))
Esempio n. 21
0
def parmname__excluding(exclude):
    return (string_excluding(attr_char, [''] + exclude)
            > named(u'parmname', RFC(5987), is_pivot=True))
Esempio n. 22
0
def parmname__excluding(exclude):
    return (string_excluding(attr_char, [''] + exclude) > named(
        u'parmname', RFC(5987), is_pivot=True))
Esempio n. 23
0
def transfer_extension(exclude=None, no_q=False):
    return Parametrized << (
        (TransferCoding << token__excluding(exclude or [])) *
        (MultiDict << many(skip(OWS * ';' * OWS) * transfer_parameter(no_q)))
    ) > named(u'transfer-extension', RFC(7230), is_pivot=True)
Esempio n. 24
0
def transfer_parameter(no_q=False):
    return ((token__excluding(['q']) if no_q else token) *
            skip(BWS * '=' * BWS) * (token | quoted_string)) > named(
                u'transfer-parameter', RFC(7230), is_pivot=True)
Esempio n. 25
0
def ext_name_star__excluding(exclude):
    return (parmname__excluding(exclude) + '*'
            > named(u'ext-name-star', RFC(5988)))
Esempio n. 26
0
def comma_list1(element):
    return _collect_elements << (many(subst(None) << ',' * OWS) + (
        (lambda x: [x]) << group(element)) + many(
            skip(OWS * ',') * maybe(skip(OWS) * element))) > named(
                u'1#rule', RFC(7230, section=u'7'))
Esempio n. 27
0
def comma_list(element):
    return _collect_elements << maybe(
        (subst([None, None]) << literal(',') |
         (lambda x: [x]) << group(element)) +
        many(skip(OWS * ',') * maybe(skip(OWS) * element))
    ) > named(u'#rule', RFC(7230, section=(7,)))
Esempio n. 28
0
def media_range(no_q=False):
    return Parametrized << (
        (literal('*/*') | type_ + '/' + '*' | _check_media_type <<
         (MediaType << type_ + '/' + subtype)) * (MultiDict << many(
             skip(OWS * ';' * OWS) * parameter(exclude=['q'] if no_q else [])))
    ) > named(u'media-range', RFC(7231), is_pivot=True)
Esempio n. 29
0
def comma_list(element):
    return _collect_elements << maybe(
        (subst([None, None]) << literal(',') |
         (lambda x: [x]) << group(element)) +
        many(skip(OWS * ',') * maybe(skip(OWS) * element))) > named(
            u'#rule', RFC(7230, section=(7, )))
Esempio n. 30
0
def parameter(exclude=None):
    return ((CaseInsensitive << token__excluding(exclude or [])) * skip('=') *
            (token | quoted_string)) > named(
                u'parameter', RFC(7231), is_pivot=True)
Esempio n. 31
0
def parameter(exclude=None):
    return (
        (CaseInsensitive << token__excluding(exclude or [])) *
        skip('=') * (token | quoted_string)
    ) > named(u'parameter', RFC(7231), is_pivot=True)
Esempio n. 32
0
def extension_pragma(exclude_no_cache=False):
    return Parametrized << (
        (token__excluding(['no-cache']) if exclude_no_cache else token) *
        maybe(skip('=') * (token | quoted_string))) > named(
            u'extension-pragma', RFC(7234), is_pivot=True)
Esempio n. 33
0
def extension_pragma(exclude_no_cache=False):
    return Parametrized << (
        (token__excluding(['no-cache']) if exclude_no_cache else token) *
        maybe(skip('=') * (token | quoted_string))
    ) > named(u'extension-pragma', RFC(7234), is_pivot=True)
Esempio n. 34
0
def _normalize_empty_value(x):
    # RFC 7240 Section 2: "Empty or zero-length values on both
    # the preference token and within parameters are equivalent
    # to no value being specified at all."
    (name, value) = x if isinstance(x, tuple) else (x, None)
    return Parametrized(name, None if value == u'' else value)


def preference_parameter(head=False):
    # The head (first) ``preference-parameter`` of a ``preference``
    # contains the actual preference name, which we want to annotate.
    name_cls = Preference if head else CaseInsensitive
    return (_normalize_empty_value <<
            (parameter(name_cls=name_cls) | name_cls << token)) > named(
                u'preference-parameter', RFC(7240, errata=4439), is_pivot=True)


preference = Parametrized << (preference_parameter(head=True) * many(
    skip(OWS * ';') * maybe(skip(OWS) * preference_parameter()))) > named(
        u'preference', RFC(7240, errata=4439), is_pivot=True)

Prefer = comma_list1(preference) > pivot

Preference_Applied = comma_list1(preference_parameter(head=True)) > pivot

return_ = CaseInsensitive << (literal('representation') | 'minimal') > pivot
wait = delay_seconds > auto
handling = CaseInsensitive << (literal('strict') | 'lenient') > pivot

fill_names(globals(), RFC(7240))