Skip to content
This repository has been archived by the owner on Mar 29, 2022. It is now read-only.

Commit

Permalink
Updates for RFC 8288 replacing RFC 5988
Browse files Browse the repository at this point in the history
  • Loading branch information
vfaronov committed Feb 2, 2018
1 parent 65bc52b commit 682146f
Show file tree
Hide file tree
Showing 17 changed files with 227 additions and 171 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Added
-----
- Checks for quoted commas and semicolons that might confuse a naive parser
(notices `1299`_, `1300`_).
- New checks for Link headers according to `RFC 8288`_ (notices `1307`_,
`1308`_, `1309`_).
- Checks for `immutable responses`_ (notices `1301`_, `1302`_, `1303`_).
- `Early hints`_ are now recognized (due to their idiosyncratic semantics,
they avoid many checks that are applied to all other responses).
Expand All @@ -34,6 +36,10 @@ Added
.. _1304: http://httpolice.readthedocs.io/page/notices.html#1304
.. _1305: http://httpolice.readthedocs.io/page/notices.html#1305
.. _1306: http://httpolice.readthedocs.io/page/notices.html#1306
.. _1307: http://httpolice.readthedocs.io/page/notices.html#1307
.. _1308: http://httpolice.readthedocs.io/page/notices.html#1308
.. _1309: http://httpolice.readthedocs.io/page/notices.html#1309
.. _RFC 8288: https://tools.ietf.org/html/rfc8288
.. _immutable responses: https://tools.ietf.org/html/rfc8246
.. _Early hints: https://tools.ietf.org/html/rfc8297

Expand Down
2 changes: 1 addition & 1 deletion httpolice/known/header.csv
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Label,,,,4229,,,,,,,,,,,,,,,,,
Last-Modified,,,,7232,2.2,,,,rfc7232,Last_Modified,True,,,,False,True,standard,,,True,single
Link,,"Not sure if this makes any sense on requests.
With the `anchor` parameter, perhaps.
Leaving undefined for now.",,8288,3,,,,rfc5988,Link,,,True,True,,True,standard,False,False,,multi
Leaving undefined for now.",,8288,3,,,,rfc8288,Link,,,True,True,,True,standard,False,False,,multi
Location,,,,7231,7.1.2,,,,rfc7231,Location,,True,,,False,True,standard,,,,single
Lock-Token,,,,4918,,,,,,,,,,,,,standard,,,,
MIME-Version,,,,7231,,A.1,,,,,,,,,,,standard,False,False,,
Expand Down
34 changes: 31 additions & 3 deletions httpolice/notices.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1632,13 +1632,13 @@ One non-obvious thing is how references work

<error id="1225">
<title>Duplicate ‘<var ref="name"/>’ parameter in <var ref="place"/></title>
<explain>According to <rfc num="5988" sect="5"/>, the ‘<var ref="name"/>’ parameter must not occur more than once in a single link.</explain>
<explain>According to <rfc num="8288" sect="3"/>, the ‘<var ref="name"/>’ parameter must not occur more than once in a single link.</explain>
</error>

<comment id="1226">
<title>Deprecated ‘rev’ parameter in <var ref="place"/></title>
<rfc num="5988" sect="5.3">
"rev" is deprecated by this
<rfc num="8288" sect="3.3">
rev is deprecated by this
specification because it often confuses authors and readers; in most
cases, using a separate relation type is preferable.
</rfc>
Expand Down Expand Up @@ -2233,4 +2233,32 @@ One non-obvious thing is how references work
</rfc>
</error>

<comment id="1307">
<title>Unquoted ‘title’ parameter in <var ref="place"/> may cause problems</title>
<rfc num="8288" sect="3">
Previous definitions of the Link header did not equate the token and
quoted-string forms explicitly; the title parameter was always
quoted, and the hreflang parameter was always a token. Senders
wishing to maximize interoperability will send them in those forms.
</rfc>
</comment>

<comment id="1308">
<title>Quoted ‘hreflang’ parameter in <var ref="place"/> may cause problems</title>
<rfc num="8288" sect="3">
Previous definitions of the Link header did not equate the token and
quoted-string forms explicitly; the title parameter was always
quoted, and the hreflang parameter was always a token. Senders
wishing to maximize interoperability will send them in those forms.
</rfc>
</comment>

<error id="1309">
<title>Missing ‘rel’ parameter in <var ref="place"/></title>
<rfc num="8288" sect="3.3">
The rel parameter MUST be
present
</rfc>
</error>

</notices>
15 changes: 7 additions & 8 deletions httpolice/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,16 +609,15 @@ def string_excluding(terminal, excluding):
(case-insensitive).
This is used where the grammar special-cases certain strings. For example,
consider RFC 5988. Strictly speaking, the string::
consider RFC 6266. Strictly speaking, the string::
hreflang="Hello world!"
filename*=qwertyuiop
matches the ``link-param`` rule, because it matches ``link-extension``.
But the spec obviously intends that an "hreflang" parameter must only have
a language tag as a value, as it is special-cased in the definition
of ``link-param``. Therefore, in our code for ``link-extension``, we
exclude "hreflang" and other special cases from the allowed values
of ``parmname``.
matches the ``disposition-param`` production, because it matches
``disp-ext-param``. But the spec obviously intends that a "filename*"
parameter only be an ``ext-value``, as it is special-cased
in ``filename-param``. Therefore, in our code for ``disp-ext-param``, we
exclude "filename*" from the allowed parameter names.
This only works when the excluded strings are relatively few and short.
Expand Down
2 changes: 1 addition & 1 deletion httpolice/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ class HSTSDirective(CaseInsensitive):

class RelationType(CaseInsensitive):

"""A registered link relation type (RFC 5988 Section 4)."""
"""A registered link relation type (RFC 8288 Section 2.1)."""

__slots__ = ()

Expand Down
17 changes: 16 additions & 1 deletion httpolice/syntax/common.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# -*- coding: utf-8; -*-

from httpolice.citation import RFC
from httpolice.parse import auto, fill_names, octet, octet_range
from httpolice.known import media
from httpolice.parse import auto, can_complain, fill_names, octet, octet_range
from httpolice.structure import MediaType


ALPHA = octet_range(0x41, 0x5A) | octet_range(0x61, 0x7A) > auto
Expand All @@ -14,4 +16,17 @@
SP = octet(0x20) > auto
VCHAR = octet_range(0x21, 0x7E) > auto


_BAD_MEDIA_TYPES = {
MediaType(u'plain/text'): media.text_plain,
MediaType(u'text/json'): media.application_json,
}

@can_complain
def check_media_type(complain, mtype):
if mtype in _BAD_MEDIA_TYPES:
complain(1282, bad=mtype, good=_BAD_MEDIA_TYPES[mtype])
return mtype


fill_names(globals(), RFC(5234))
119 changes: 0 additions & 119 deletions httpolice/syntax/rfc5988.py

This file was deleted.

19 changes: 3 additions & 16 deletions httpolice/syntax/rfc7231.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
from datetime import date, datetime, time

from httpolice.citation import RFC
from httpolice.known import media
from httpolice.parse import (auto, can_complain, fill_names, literal, many,
maybe, maybe_str, named, octet, pivot, skip,
string1, string_times, subst)
from httpolice.structure import (CaseInsensitive, Charset, ContentCoding,
MediaType, MultiDict, Parametrized,
ProductName, Unavailable, Versioned, okay)
from httpolice.syntax.common import DIGIT, SP
from httpolice.syntax.common import DIGIT, SP, check_media_type
from httpolice.syntax.rfc3986 import URI_reference, absolute_URI
from httpolice.syntax.rfc4647 import language_range
from httpolice.syntax.rfc5646 import Language_Tag as language_tag
Expand All @@ -27,18 +26,6 @@
u'Sep', u'Oct', u'Nov', u'Dec']


_BAD_MEDIA_TYPES = {
MediaType(u'plain/text'): media.text_plain,
MediaType(u'text/json'): media.application_json,
}

@can_complain
def _check_media_type(complain, mtype):
if mtype in _BAD_MEDIA_TYPES:
complain(1282, bad=mtype, good=_BAD_MEDIA_TYPES[mtype])
return mtype


def parameter(exclude=None, name_cls=CaseInsensitive):
return (
(name_cls << token__excluding(exclude or [])) *
Expand All @@ -48,7 +35,7 @@ def parameter(exclude=None, name_cls=CaseInsensitive):
type_ = token > pivot
subtype = token > pivot
media_type = Parametrized << (
(_check_media_type << (MediaType << type_ + '/' + subtype)) *
(check_media_type << (MediaType << type_ + '/' + subtype)) *
(MultiDict << many(skip(OWS * ';' * OWS) * parameter()))) > pivot

content_coding = ContentCoding << token > pivot
Expand Down Expand Up @@ -195,7 +182,7 @@ def media_range(no_q=False):
(
literal('*/*') |
type_ + '/' + '*' |
_check_media_type << (MediaType << type_ + '/' + subtype)
check_media_type << (MediaType << type_ + '/' + subtype)
) *
(
MultiDict << many(
Expand Down
11 changes: 3 additions & 8 deletions httpolice/syntax/rfc8187.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from httpolice.util.moves import unquote_to_bytes as pct_decode

from httpolice.citation import RFC
from httpolice.parse import (auto, can_complain, fill_names, maybe, named,
pivot, skip, string, string1, string_excluding)
from httpolice.parse import (auto, can_complain, fill_names, maybe, pivot,
skip, string, string1)
from httpolice.structure import CaseInsensitive, ExtValue
from httpolice.syntax.common import ALPHA, DIGIT, HEXDIG
from httpolice.syntax.rfc5646 import Language_Tag as language
Expand All @@ -14,12 +14,7 @@
attr_char = (ALPHA | DIGIT |
'!' | '#' | '$' | '&' | '+' | '-' | '.' |
'^' | '_' | '`' | '|' | '~') > auto

def parmname__excluding(exclude):
return (string_excluding(attr_char, [''] + exclude)
> named(u'parmname', RFC(8187), is_pivot=True))

parmname = parmname__excluding([])
parmname = string(attr_char) > pivot

# We don't need to special-case "UTF-8", simplify.
mime_charsetc = (ALPHA | DIGIT |
Expand Down

0 comments on commit 682146f

Please sign in to comment.