Skip to content

Commit

Permalink
Cool URI don't change... except when they do.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaugustin committed Aug 12, 2024
1 parent ab93b1e commit 0ddd688
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 61 deletions.
18 changes: 9 additions & 9 deletions src/websockets/asyncio/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ async def recv(self, decode: bool | None = None) -> Data:
A string (:class:`str`) for a Text_ frame or a bytestring
(:class:`bytes`) for a Binary_ frame.
.. _Text: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Binary: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
.. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
You may override this behavior with the ``decode`` argument:
Expand Down Expand Up @@ -253,8 +253,8 @@ async def recv_streaming(self, decode: bool | None = None) -> AsyncIterator[Data
An iterator of strings (:class:`str`) for a Text_ frame or
bytestrings (:class:`bytes`) for a Binary_ frame.
.. _Text: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Binary: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
.. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
You may override this behavior with the ``decode`` argument:
Expand Down Expand Up @@ -290,16 +290,16 @@ async def send(self, message: Data | Iterable[Data] | AsyncIterable[Data]) -> No
bytes-like object (:class:`bytes`, :class:`bytearray`, or
:class:`memoryview`) is sent as a Binary_ frame.
.. _Text: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Binary: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
.. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
:meth:`send` also accepts an iterable or an asynchronous iterable of
strings, bytestrings, or bytes-like objects to enable fragmentation_.
Each item is treated as a message fragment and sent in its own frame.
All items must be of the same type, or else :meth:`send` will raise a
:exc:`TypeError` and the connection will be closed.
.. _fragmentation: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.4
.. _fragmentation: https://datatracker.ietf.org/doc/html/rfc6455#section-5.4
:meth:`send` rejects dict-like objects because this is often an error.
(If you really want to send the keys of a dict-like object as fragments,
Expand Down Expand Up @@ -524,7 +524,7 @@ async def ping(self, data: Data | None = None) -> Awaitable[None]:
"""
Send a Ping_.
.. _Ping: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.2
.. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2
A ping may serve as a keepalive or as a check that the remote endpoint
received all messages up to this point
Expand Down Expand Up @@ -574,7 +574,7 @@ async def pong(self, data: Data = b"") -> None:
"""
Send a Pong_.
.. _Pong: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.3
.. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3
An unsolicited pong may serve as a unidirectional heartbeat.
Expand Down
4 changes: 2 additions & 2 deletions src/websockets/extensions/permessage_deflate.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class ClientPerMessageDeflateFactory(ClientExtensionFactory):
Parameters behave as described in `section 7.1 of RFC 7692`_.
.. _section 7.1 of RFC 7692: https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1
.. _section 7.1 of RFC 7692: https://datatracker.ietf.org/doc/html/rfc7692#section-7.1
Set them to :obj:`True` to include them in the negotiation offer without a
value or to an integer value to include them with this value.
Expand Down Expand Up @@ -462,7 +462,7 @@ class ServerPerMessageDeflateFactory(ServerExtensionFactory):
Parameters behave as described in `section 7.1 of RFC 7692`_.
.. _section 7.1 of RFC 7692: https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1
.. _section 7.1 of RFC 7692: https://datatracker.ietf.org/doc/html/rfc7692#section-7.1
Set them to :obj:`True` to include them in the negotiation offer without a
value or to an integer value to include them with this value.
Expand Down
18 changes: 9 additions & 9 deletions src/websockets/headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def build_host(host: str, port: int, secure: bool) -> str:
Build a ``Host`` header.
"""
# https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.2
# https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
# IPv6 addresses must be enclosed in brackets.
try:
address = ipaddress.ip_address(host)
Expand All @@ -59,8 +59,8 @@ def build_host(host: str, port: int, secure: bool) -> str:


# To avoid a dependency on a parsing library, we implement manually the ABNF
# described in https://www.rfc-editor.org/rfc/rfc6455.html#section-9.1 and
# https://www.rfc-editor.org/rfc/rfc7230.html#appendix-B.
# described in https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 and
# https://datatracker.ietf.org/doc/html/rfc7230#appendix-B.


def peek_ahead(header: str, pos: int) -> str | None:
Expand Down Expand Up @@ -183,7 +183,7 @@ def parse_list(
InvalidHeaderFormat: On invalid inputs.
"""
# Per https://www.rfc-editor.org/rfc/rfc7230.html#section-7, "a recipient
# Per https://datatracker.ietf.org/doc/html/rfc7230#section-7, "a recipient
# MUST parse and ignore a reasonable number of empty list elements";
# hence while loops that remove extra delimiters.

Expand Down Expand Up @@ -320,7 +320,7 @@ def parse_extension_item_param(
if peek_ahead(header, pos) == '"':
pos_before = pos # for proper error reporting below
value, pos = parse_quoted_string(header, pos, header_name)
# https://www.rfc-editor.org/rfc/rfc6455.html#section-9.1 says:
# https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 says:
# the value after quoted-string unescaping MUST conform to
# the 'token' ABNF.
if _token_re.fullmatch(value) is None:
Expand Down Expand Up @@ -489,7 +489,7 @@ def build_www_authenticate_basic(realm: str) -> str:
realm: Identifier of the protection space.
"""
# https://www.rfc-editor.org/rfc/rfc7617.html#section-2
# https://datatracker.ietf.org/doc/html/rfc7617#section-2
realm = build_quoted_string(realm)
charset = build_quoted_string("UTF-8")
return f"Basic realm={realm}, charset={charset}"
Expand Down Expand Up @@ -539,8 +539,8 @@ def parse_authorization_basic(header: str) -> tuple[str, str]:
InvalidHeaderValue: On unsupported inputs.
"""
# https://www.rfc-editor.org/rfc/rfc7235.html#section-2.1
# https://www.rfc-editor.org/rfc/rfc7617.html#section-2
# https://datatracker.ietf.org/doc/html/rfc7235#section-2.1
# https://datatracker.ietf.org/doc/html/rfc7617#section-2
scheme, pos = parse_token(header, 0, "Authorization")
if scheme.lower() != "basic":
raise exceptions.InvalidHeaderValue(
Expand Down Expand Up @@ -580,7 +580,7 @@ def build_authorization_basic(username: str, password: str) -> str:
This is the reverse of :func:`parse_authorization_basic`.
"""
# https://www.rfc-editor.org/rfc/rfc7617.html#section-2
# https://datatracker.ietf.org/doc/html/rfc7617#section-2
assert ":" not in username
user_pass = f"{username}:{password}"
basic_credentials = base64.b64encode(user_pass.encode()).decode()
Expand Down
14 changes: 7 additions & 7 deletions src/websockets/http11.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def d(value: bytes) -> str:
return value.decode(errors="backslashreplace")


# See https://www.rfc-editor.org/rfc/rfc7230.html#appendix-B.
# See https://datatracker.ietf.org/doc/html/rfc7230#appendix-B.

# Regex for validating header names.

Expand Down Expand Up @@ -122,7 +122,7 @@ def parse(
ValueError: If the request isn't well formatted.
"""
# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.1.1
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.1

# Parsing is simple because fixed values are expected for method and
# version and because path isn't checked. Since WebSocket software tends
Expand All @@ -146,7 +146,7 @@ def parse(

headers = yield from parse_headers(read_line)

# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.3.3
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3

if "Transfer-Encoding" in headers:
raise NotImplementedError("transfer codings aren't supported")
Expand Down Expand Up @@ -227,7 +227,7 @@ def parse(
ValueError: If the response isn't well formatted.
"""
# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.1.2
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2

try:
status_line = yield from parse_line(read_line)
Expand Down Expand Up @@ -255,7 +255,7 @@ def parse(

headers = yield from parse_headers(read_line)

# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.3.3
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3

if "Transfer-Encoding" in headers:
raise NotImplementedError("transfer codings aren't supported")
Expand Down Expand Up @@ -324,7 +324,7 @@ def parse_headers(
ValueError: If the request isn't well formatted.
"""
# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.2

# We don't attempt to support obsolete line folding.

Expand Down Expand Up @@ -378,7 +378,7 @@ def parse_line(
line = yield from read_line(MAX_LINE_LENGTH)
except RuntimeError:
raise exceptions.SecurityError("line too long")
# Not mandatory but safe - https://www.rfc-editor.org/rfc/rfc7230.html#section-3.5
# Not mandatory but safe - https://datatracker.ietf.org/doc/html/rfc7230#section-3.5
if not line.endswith(b"\r\n"):
raise EOFError("line without CRLF")
return line[:-2]
10 changes: 5 additions & 5 deletions src/websockets/legacy/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def d(value: bytes) -> str:
return value.decode(errors="backslashreplace")


# See https://www.rfc-editor.org/rfc/rfc7230.html#appendix-B.
# See https://datatracker.ietf.org/doc/html/rfc7230#appendix-B.

# Regex for validating header names.

Expand Down Expand Up @@ -64,7 +64,7 @@ async def read_request(stream: asyncio.StreamReader) -> tuple[str, Headers]:
ValueError: If the request isn't well formatted.
"""
# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.1.1
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.1

# Parsing is simple because fixed values are expected for method and
# version and because path isn't checked. Since WebSocket software tends
Expand Down Expand Up @@ -111,7 +111,7 @@ async def read_response(stream: asyncio.StreamReader) -> tuple[int, str, Headers
ValueError: If the response isn't well formatted.
"""
# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.1.2
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2

# As in read_request, parsing is simple because a fixed value is expected
# for version, status_code is a 3-digit number, and reason can be ignored.
Expand Down Expand Up @@ -150,7 +150,7 @@ async def read_headers(stream: asyncio.StreamReader) -> Headers:
Non-ASCII characters are represented with surrogate escapes.
"""
# https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.2

# We don't attempt to support obsolete line folding.

Expand Down Expand Up @@ -195,7 +195,7 @@ async def read_line(stream: asyncio.StreamReader) -> bytes:
# Security: this guarantees header values are small (hard-coded = 8 KiB)
if len(line) > MAX_LINE_LENGTH:
raise SecurityError("line too long")
# Not mandatory but safe - https://www.rfc-editor.org/rfc/rfc7230.html#section-3.5
# Not mandatory but safe - https://datatracker.ietf.org/doc/html/rfc7230#section-3.5
if not line.endswith(b"\r\n"):
raise EOFError("line without CRLF")
return line[:-2]
26 changes: 13 additions & 13 deletions src/websockets/legacy/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ class WebSocketCommonProtocol(asyncio.Protocol):
especially in the presence of proxies with short timeouts on inactive
connections. Set ``ping_interval`` to :obj:`None` to disable this behavior.
.. _Ping: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.2
.. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2
If the corresponding Pong_ frame isn't received within ``ping_timeout``
seconds, the connection is considered unusable and is closed with code 1011.
This ensures that the remote endpoint remains responsive. Set
``ping_timeout`` to :obj:`None` to disable this behavior.
.. _Pong: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.3
.. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3
See the discussion of :doc:`timeouts <../../topics/timeouts>` for details.
Expand Down Expand Up @@ -447,7 +447,7 @@ def close_code(self) -> int | None:
WebSocket close code, defined in `section 7.1.5 of RFC 6455`_.
.. _section 7.1.5 of RFC 6455:
https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5
https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5
:obj:`None` if the connection isn't closed yet.
Expand All @@ -465,7 +465,7 @@ def close_reason(self) -> str | None:
WebSocket close reason, defined in `section 7.1.6 of RFC 6455`_.
.. _section 7.1.6 of RFC 6455:
https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.6
https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6
:obj:`None` if the connection isn't closed yet.
Expand Down Expand Up @@ -516,8 +516,8 @@ async def recv(self) -> Data:
A string (:class:`str`) for a Text_ frame. A bytestring
(:class:`bytes`) for a Binary_ frame.
.. _Text: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Binary: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
.. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
Raises:
ConnectionClosed: When the connection is closed.
Expand Down Expand Up @@ -583,16 +583,16 @@ async def send(
bytes-like object (:class:`bytes`, :class:`bytearray`, or
:class:`memoryview`) is sent as a Binary_ frame.
.. _Text: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Binary: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
.. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
:meth:`send` also accepts an iterable or an asynchronous iterable of
strings, bytestrings, or bytes-like objects to enable fragmentation_.
Each item is treated as a message fragment and sent in its own frame.
All items must be of the same type, or else :meth:`send` will raise a
:exc:`TypeError` and the connection will be closed.
.. _fragmentation: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.4
.. _fragmentation: https://datatracker.ietf.org/doc/html/rfc6455#section-5.4
:meth:`send` rejects dict-like objects because this is often an error.
(If you want to send the keys of a dict-like object as fragments, call
Expand Down Expand Up @@ -803,7 +803,7 @@ async def ping(self, data: Data | None = None) -> Awaitable[float]:
"""
Send a Ping_.
.. _Ping: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.2
.. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2
A ping may serve as a keepalive, as a check that the remote endpoint
received all messages up to this point, or to measure :attr:`latency`.
Expand Down Expand Up @@ -862,7 +862,7 @@ async def pong(self, data: Data = b"") -> None:
"""
Send a Pong_.
.. _Pong: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.3
.. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3
An unsolicited pong may serve as a unidirectional heartbeat.
Expand Down Expand Up @@ -1559,8 +1559,8 @@ def broadcast(
object (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) is sent
as a Binary_ frame.
.. _Text: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Binary: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
.. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
.. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6
:func:`broadcast` pushes the message synchronously to all connections even
if their write buffers are overflowing. There's no backpressure.
Expand Down
2 changes: 1 addition & 1 deletion src/websockets/legacy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ def process_origin(
"""
# "The user agent MUST NOT include more than one Origin header field"
# per https://www.rfc-editor.org/rfc/rfc6454.html#section-7.3.
# per https://datatracker.ietf.org/doc/html/rfc6454#section-7.3.
try:
origin = headers.get("Origin")
except MultipleValuesError as exc:
Expand Down
4 changes: 2 additions & 2 deletions src/websockets/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def close_code(self) -> int | None:
`WebSocket close code`_.
.. _WebSocket close code:
https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5
https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5
:obj:`None` if the connection isn't closed yet.
Expand All @@ -193,7 +193,7 @@ def close_reason(self) -> str | None:
`WebSocket close reason`_.
.. _WebSocket close reason:
https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.6
https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6
:obj:`None` if the connection isn't closed yet.
Expand Down
2 changes: 1 addition & 1 deletion src/websockets/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def process_origin(self, headers: Headers) -> Origin | None:
"""
# "The user agent MUST NOT include more than one Origin header field"
# per https://www.rfc-editor.org/rfc/rfc6454.html#section-7.3.
# per https://datatracker.ietf.org/doc/html/rfc6454#section-7.3.
try:
origin = headers.get("Origin")
except MultipleValuesError as exc:
Expand Down
Loading

0 comments on commit 0ddd688

Please sign in to comment.