boring-http 2.0.1__tar.gz → 2.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boring_http-2.0.1 → boring_http-2.0.2}/PKG-INFO +3 -3
- {boring_http-2.0.1 → boring_http-2.0.2}/README.md +2 -2
- {boring_http-2.0.1 → boring_http-2.0.2}/pyproject.toml +1 -1
- {boring_http-2.0.1 → boring_http-2.0.2}/pyproject.toml.orig +1 -1
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/pool.py +2 -1
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/timing.py +3 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/websocket.py +2 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/__init__.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/client.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/codings.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/cookies.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/errors.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/hpack.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/hpack_tables.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/http1.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/http2.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/http3.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/message.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/py.typed +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/qpack.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/qpack_tables.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/quic/__init__.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/quic/connection.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/quic/packet.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/quic/protocol.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/quic/recovery.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/quic/streams.py +0 -0
- {boring_http-2.0.1 → boring_http-2.0.2}/src/boring_http/revocation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: boring-http
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Asyncio HTTP client on BoringSSL: HTTP/1.1, HTTP/2 and HTTP/3 over QUIC v1 and v2, WebSocket on all three, HTTP and SOCKS proxies, headers in your order
|
|
5
5
|
Requires-Dist: boring-ssl2>=1.2.0
|
|
6
6
|
Requires-Dist: ssl2>=2.0.1
|
|
@@ -98,7 +98,7 @@ async def main() -> None:
|
|
|
98
98
|
asyncio.run(main())
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
A single number sets every phase and the total, so the request gives up after that many seconds whatever it was doing. With a `Timeout` the phases are separate: `read` is the longest wait for the next bytes, `total` caps the whole exchange including redirects, and the error names whichever ran out.
|
|
101
|
+
A single number sets every phase and the total, so the request gives up after that many seconds whatever it was doing. With a `Timeout` the phases are separate: `connect` covers opening a connection, the proxy, TCP and the TLS or QUIC handshake included, `read` is the longest wait for the next bytes, `total` caps the whole exchange including redirects, and the error names whichever ran out.
|
|
102
102
|
|
|
103
103
|
## HTTP/3
|
|
104
104
|
|
|
@@ -453,7 +453,7 @@ async def main() -> None:
|
|
|
453
453
|
asyncio.run(main())
|
|
454
454
|
```
|
|
455
455
|
|
|
456
|
-
Over HTTP/1.1 this is the Upgrade handshake. Over HTTP/2 and HTTP/3 it is Extended CONNECT when the server advertises `SETTINGS_ENABLE_CONNECT_PROTOCOL`, otherwise the client opens an HTTP/1.1 connection for it. `subprotocols=[...]` offers subprotocols; `websocket.subprotocol` is the one chosen.
|
|
456
|
+
Over HTTP/1.1 this is the Upgrade handshake. Over HTTP/2 and HTTP/3 it is Extended CONNECT when the server advertises `SETTINGS_ENABLE_CONNECT_PROTOCOL`, otherwise the client opens an HTTP/1.1 connection for it. `subprotocols=[...]` offers subprotocols; `websocket.subprotocol` is the one chosen. The `total` of `timeout` covers the handshake only; afterwards `read` and `write` still limit each wait, so `Timeout(read=None)` lets `receive()` wait through any silence.
|
|
457
457
|
|
|
458
458
|
## uvloop
|
|
459
459
|
|
|
@@ -88,7 +88,7 @@ async def main() -> None:
|
|
|
88
88
|
asyncio.run(main())
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
A single number sets every phase and the total, so the request gives up after that many seconds whatever it was doing. With a `Timeout` the phases are separate: `read` is the longest wait for the next bytes, `total` caps the whole exchange including redirects, and the error names whichever ran out.
|
|
91
|
+
A single number sets every phase and the total, so the request gives up after that many seconds whatever it was doing. With a `Timeout` the phases are separate: `connect` covers opening a connection, the proxy, TCP and the TLS or QUIC handshake included, `read` is the longest wait for the next bytes, `total` caps the whole exchange including redirects, and the error names whichever ran out.
|
|
92
92
|
|
|
93
93
|
## HTTP/3
|
|
94
94
|
|
|
@@ -443,7 +443,7 @@ async def main() -> None:
|
|
|
443
443
|
asyncio.run(main())
|
|
444
444
|
```
|
|
445
445
|
|
|
446
|
-
Over HTTP/1.1 this is the Upgrade handshake. Over HTTP/2 and HTTP/3 it is Extended CONNECT when the server advertises `SETTINGS_ENABLE_CONNECT_PROTOCOL`, otherwise the client opens an HTTP/1.1 connection for it. `subprotocols=[...]` offers subprotocols; `websocket.subprotocol` is the one chosen.
|
|
446
|
+
Over HTTP/1.1 this is the Upgrade handshake. Over HTTP/2 and HTTP/3 it is Extended CONNECT when the server advertises `SETTINGS_ENABLE_CONNECT_PROTOCOL`, otherwise the client opens an HTTP/1.1 connection for it. `subprotocols=[...]` offers subprotocols; `websocket.subprotocol` is the one chosen. The `total` of `timeout` covers the handshake only; afterwards `read` and `write` still limit each wait, so `Timeout(read=None)` lets `receive()` wait through any silence.
|
|
447
447
|
|
|
448
448
|
## uvloop
|
|
449
449
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "boring-http"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.2"
|
|
4
4
|
description = "Asyncio HTTP client on BoringSSL: HTTP/1.1, HTTP/2 and HTTP/3 over QUIC v1 and v2, WebSocket on all three, HTTP and SOCKS proxies, headers in your order"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "boring-http"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.2"
|
|
4
4
|
description = "Asyncio HTTP client on BoringSSL: HTTP/1.1, HTTP/2 and HTTP/3 over QUIC v1 and v2, WebSocket on all three, HTTP and SOCKS proxies, headers in your order"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
@@ -68,7 +68,8 @@ class Pool:
|
|
|
68
68
|
await limit.acquire()
|
|
69
69
|
await self._total.acquire()
|
|
70
70
|
try:
|
|
71
|
-
|
|
71
|
+
async with deadline.phase("connect"):
|
|
72
|
+
connection = await self._connector(url, proxy, quic)
|
|
72
73
|
except BaseException:
|
|
73
74
|
limit.release()
|
|
74
75
|
self._total.release()
|
|
@@ -45,6 +45,9 @@ class Deadline:
|
|
|
45
45
|
def phase(self, name: Phase) -> PhaseTimer:
|
|
46
46
|
return PhaseTimer(self, name)
|
|
47
47
|
|
|
48
|
+
def drop_total(self) -> None:
|
|
49
|
+
self._end = None
|
|
50
|
+
|
|
48
51
|
def limit(self, name: Phase) -> tuple[float | None, bool]:
|
|
49
52
|
# the total budget wins when it leaves less time than the phase's own limit, and the error then names the total
|
|
50
53
|
limit = self._limits[name]
|
|
@@ -37,6 +37,8 @@ class WebSocket:
|
|
|
37
37
|
) -> None:
|
|
38
38
|
self._transport = transport
|
|
39
39
|
self._buffer = bytearray(leftover)
|
|
40
|
+
# the total covered the handshake; from here each read and write keeps only its phase limit
|
|
41
|
+
deadline.drop_total()
|
|
40
42
|
self._deadline = deadline
|
|
41
43
|
self._limit = max_message_size
|
|
42
44
|
self._fragments: list[bytes] = []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|