diff --git a/src/websockets/asyncio/connection.py b/src/websockets/asyncio/connection.py index 4f44d798c..0a3ddb9aa 100644 --- a/src/websockets/asyncio/connection.py +++ b/src/websockets/asyncio/connection.py @@ -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: @@ -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: @@ -290,8 +290,8 @@ 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_. @@ -299,7 +299,7 @@ async def send(self, message: Data | Iterable[Data] | AsyncIterable[Data]) -> No 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, @@ -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 @@ -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. diff --git a/src/websockets/extensions/permessage_deflate.py b/src/websockets/extensions/permessage_deflate.py index 579262f02..fea14131e 100644 --- a/src/websockets/extensions/permessage_deflate.py +++ b/src/websockets/extensions/permessage_deflate.py @@ -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. @@ -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. diff --git a/src/websockets/headers.py b/src/websockets/headers.py index bc42e0b72..0ffd65233 100644 --- a/src/websockets/headers.py +++ b/src/websockets/headers.py @@ -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) @@ -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: @@ -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. @@ -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: @@ -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}" @@ -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( @@ -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() diff --git a/src/websockets/http11.py b/src/websockets/http11.py index ed49fcbf9..b86c6ca4a 100644 --- a/src/websockets/http11.py +++ b/src/websockets/http11.py @@ -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. @@ -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 @@ -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") @@ -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) @@ -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") @@ -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. @@ -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] diff --git a/src/websockets/legacy/http.py b/src/websockets/legacy/http.py index b5df7e4c4..a7c8a927e 100644 --- a/src/websockets/legacy/http.py +++ b/src/websockets/legacy/http.py @@ -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. @@ -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 @@ -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. @@ -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. @@ -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] diff --git a/src/websockets/legacy/protocol.py b/src/websockets/legacy/protocol.py index 120ff8e73..6f8916576 100644 --- a/src/websockets/legacy/protocol.py +++ b/src/websockets/legacy/protocol.py @@ -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. @@ -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. @@ -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. @@ -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. @@ -583,8 +583,8 @@ 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_. @@ -592,7 +592,7 @@ async def send( 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 @@ -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`. @@ -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. @@ -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. diff --git a/src/websockets/legacy/server.py b/src/websockets/legacy/server.py index cd7980e00..d230f009e 100644 --- a/src/websockets/legacy/server.py +++ b/src/websockets/legacy/server.py @@ -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: diff --git a/src/websockets/protocol.py b/src/websockets/protocol.py index 7f2b45c74..917c19163 100644 --- a/src/websockets/protocol.py +++ b/src/websockets/protocol.py @@ -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. @@ -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. diff --git a/src/websockets/server.py b/src/websockets/server.py index 7211d3cbf..1b4c3bf29 100644 --- a/src/websockets/server.py +++ b/src/websockets/server.py @@ -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: diff --git a/src/websockets/sync/connection.py b/src/websockets/sync/connection.py index 2bcb3aa0e..a4826c785 100644 --- a/src/websockets/sync/connection.py +++ b/src/websockets/sync/connection.py @@ -189,8 +189,8 @@ def recv(self, timeout: float | 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 Raises: ConnectionClosed: When the connection is closed. @@ -222,8 +222,8 @@ def recv_streaming(self) -> Iterator[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 Raises: ConnectionClosed: When the connection is closed. @@ -250,8 +250,8 @@ def send(self, message: Data | Iterable[Data]) -> None: 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 of strings, bytestrings, or bytes-like objects to enable fragmentation_. Each item is treated as a @@ -259,7 +259,7 @@ def send(self, message: Data | Iterable[Data]) -> None: 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, @@ -425,7 +425,7 @@ def ping(self, data: Data | None = None) -> threading.Event: """ 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 @@ -470,7 +470,7 @@ 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. diff --git a/src/websockets/typing.py b/src/websockets/typing.py index 6360c7a0a..447fe79da 100644 --- a/src/websockets/typing.py +++ b/src/websockets/typing.py @@ -24,8 +24,8 @@ """Types supported in a WebSocket message: :class:`str` for a Text_ frame, :class:`bytes` for a Binary_. -.. _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 """ diff --git a/src/websockets/uri.py b/src/websockets/uri.py index 5cb38a9cc..82b35f92a 100644 --- a/src/websockets/uri.py +++ b/src/websockets/uri.py @@ -23,7 +23,7 @@ class WebSocketURI: username: Available when the URI contains `User Information`_. password: Available when the URI contains `User Information`_. - .. _User Information: https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.1 + .. _User Information: https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 """