lkrequest 0.2.0__tar.gz → 0.2.1__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.
- {lkrequest-0.2.0 → lkrequest-0.2.1}/.gitignore +1 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/CHANGELOG.md +33 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/Cargo.lock +95 -184
- {lkrequest-0.2.0 → lkrequest-0.2.1}/Cargo.toml +6 -1
- {lkrequest-0.2.0 → lkrequest-0.2.1}/PKG-INFO +10 -4
- {lkrequest-0.2.0 → lkrequest-0.2.1}/README-zh.md +9 -3
- {lkrequest-0.2.0 → lkrequest-0.2.1}/README.md +9 -3
- {lkrequest-0.2.0 → lkrequest-0.2.1}/benchmarks/bench_latency.py +6 -2
- {lkrequest-0.2.0 → lkrequest-0.2.1}/benchmarks/bench_memory.py +4 -2
- {lkrequest-0.2.0 → lkrequest-0.2.1}/benchmarks/bench_throughput.py +4 -2
- {lkrequest-0.2.0 → lkrequest-0.2.1}/benchmarks/requirements.txt +1 -2
- {lkrequest-0.2.0 → lkrequest-0.2.1}/justfile +4 -4
- {lkrequest-0.2.0 → lkrequest-0.2.1}/pyproject.toml +2 -1
- {lkrequest-0.2.0 → lkrequest-0.2.1}/python/lkrequest/__init__.py +10 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/python/lkrequest/_lkrequest.pyi +110 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/python/lkrequest/blocking.py +8 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/client.rs +139 -7
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/fingerprint.rs +63 -3
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/lib.rs +8 -0
- lkrequest-0.2.1/src/network_partition.rs +212 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/quic.rs +9 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/types.rs +88 -2
- {lkrequest-0.2.0 → lkrequest-0.2.1}/tests/conftest.py +90 -1
- {lkrequest-0.2.0 → lkrequest-0.2.1}/tests/test_followup_features.py +264 -1
- {lkrequest-0.2.0 → lkrequest-0.2.1}/tests/test_local_server.py +174 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/.editorconfig +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/.github/workflows/ci.yml +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/CONTRIBUTING.md +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/LICENSE +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/NOTICE +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/SECURITY.md +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/benchmarks/README.md +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/build.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/accept_encoding.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/authentication.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/basic_requests.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/browser_fingerprints.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/certificate_config.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/client_pool.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/connection_prewarming.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/cookie_management.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/custom_fingerprint.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/error_handling.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/event_hooks.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/fingerprint_validation.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/http_methods.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/logging_config.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/metrics.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/middleware.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/multipart_upload.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/pool_stats.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/proxy_pool.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/redirect_history.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/response_inspection.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/retry_strategies.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/session_pool.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/streaming_response.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/timeout_config.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/examples/websocket.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/python/lkrequest/pcap.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/rustfmt.toml +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/bridge.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/client_pool.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/error.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/hsts.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/metrics.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/middleware.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/multipart.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/priority.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/protocol.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/proxy.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/randomize.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/response.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/retry.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/session.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/session_pool.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/src/websocket.rs +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/tests/test_advanced.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/tests/test_client.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/tests/test_package_metadata.py +0 -0
- {lkrequest-0.2.0 → lkrequest-0.2.1}/tests/test_stub_parity.py +0 -0
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
All important changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## lkrequest-py 0.2.1
|
|
6
|
+
|
|
7
|
+
Adds the Chrome 152 preset and browser network session policies, and picks up a
|
|
8
|
+
large upstream RFC-compliance pass. Several fixes below change observable
|
|
9
|
+
behaviour — the ECH, retry, redirect, cookie and connection-limit entries are
|
|
10
|
+
the ones most likely to affect existing code.
|
|
11
|
+
|
|
12
|
+
### 🚀 Features
|
|
13
|
+
- **Chrome 152 Preset** — Added `Client.chrome_152()`, `BlockingClient.chrome_152()`, `TlsProfile.chrome_152()`, `TlsProfile.chrome_152_quic()`, `H2Profile.chrome_152()`, `QuicProfile.chrome_152()`, and the `"chrome_152"` TLS/H2/QUIC profile names. Chrome 152 is currently the only preset that applies GREASE to `signature_algorithms`, and it carries the new trust anchor IDs extension. HTTP/2 is unchanged from Chrome 151; the QUIC capture drops the `google_initial_rtt` transport parameter (`0x3127`).
|
|
14
|
+
- **Browser Network Session Policies** — Added `TlsSessionResumptionPolicy` (`BROWSER_DEFAULT` / `DISABLED` / `enabled(max_tickets_per_server)`), `TlsSessionCachePartitionPolicy` (`UNPARTITIONED` / `TOP_LEVEL_SITE` / `TOP_LEVEL_AND_FRAME_SITE` / `CHROMIUM` / `FIREFOX`), and `NetworkPartitionContext(top_level_site, frame_site)`. Set the first two via `Client(tls_session_resumption_policy=..., tls_session_cache_partition_policy=...)` and pass the third to `session(network_partition_context=...)` to reproduce a browser's per-site ticket isolation. These control whether tickets are *stored* and how the cache is keyed; `SessionResumptionConfig` continues to control which resumption modes the ClientHello *advertises*.
|
|
15
|
+
- **HTTP/2 DATA Frame Policy** — Added `Client(h2_data_frame_policy=...)` with `H2DataFramePolicy.BROWSER_DEFAULT`, `.PEER_MAX_FRAME_SIZE`, `.fixed_payload(n)`, and `.socket_write_aligned(n)`, choosing how request bodies are split into DATA frames. The default keeps the browser preset's native framing, since frame sizes are themselves an observable fingerprint trait.
|
|
16
|
+
- **Strict TLS close_notify** — Added `Client(require_close_notify=True)` and a matching read-only property. When enabled, a response body truncated by a bare socket EOF — with no TLS `close_notify` alert — is reported as an error instead of being accepted as a complete body. One part applies regardless of the flag: the read loop now stops at `close_notify` instead of reading on, because anything arriving after it did not come from the peer — those bytes were previously appended to the response body.
|
|
17
|
+
- **Trust Anchor IDs Extension** — Added `ExtType.TRUST_ANCHOR_IDS` and a new `ExtensionSpec` source: `ExtensionSpec(ExtType.TRUST_ANCHOR_IDS, source="trust_anchor_ids", trust_anchor_ids=[...], shuffle=False)`, with `trust_anchor_ids` and `shuffle` readable back off the spec.
|
|
18
|
+
- **DNS-over-HTTPS Feature** — Upstream moved the DoH resolvers behind a `doh` Cargo feature. The published wheels enable it, so `dns="google_https"`, `"cloudflare_https"` and `"quad9_https"` keep working exactly as before; a reduced-feature source build now rejects those three names with an actionable error instead of a generic "unknown DNS config".
|
|
19
|
+
|
|
20
|
+
### 🐞 Fixes
|
|
21
|
+
- **A Rejected ECH No Longer Falls Through In The Clear** — when a server did not accept Encrypted ClientHello, the handshake previously carried on and handed back a connection whose real server name had never been protected, so the request ECH existed to hide went out in the open. The handshake now aborts before any traffic keys exist, and the session redials once with the `retry_configs` the server supplied — the same thing a browser does, so routine ECH key rotation stays transparent. Retrying *without* ECH is deliberately not a fallback. This affects clients that never set `ech_config=`, because ECH is enabled automatically from DNS HTTPS records; a rejection that cannot be retried now surfaces as `TlsError`. GREASE ECH is unaffected.
|
|
22
|
+
- **Status-Code Retries Are Gated On Replay Safety** — a non-idempotent request answered with a status in the retry set was replayed even though the answer proves the server received it, so a `POST` answered `502` was sent twice. Such a method is now retried only on a status that says it was *not* applied (`429`, `503`); `502`, `504` and the Cloudflare `520`–`530` range are returned to the caller instead. Safe methods are unaffected, and passing `idempotency=Idempotency.Idempotent` on the request restores the old behaviour per call.
|
|
23
|
+
- **Only Real Redirect Statuses Are Followed** — `300`, `304`, `305` and `306` are no longer treated as redirects. Previously a `304 Not Modified` or a `305 Use Proxy` could send the client chasing a `Location` header it should have ignored. `301`, `302`, `303`, `307` and `308` are unaffected.
|
|
24
|
+
- **Cookie Name Prefixes Enforced** — Cookies named with the `__Secure-` or `__Host-` prefix are now rejected unless they satisfy the prefix rules (`Secure`, and for `__Host-` also a `/` path with no `Domain`). A server can no longer set a lookalike cookie that client code would reasonably trust.
|
|
25
|
+
- **Secure Cookies Ignored Over Plain HTTP** — A `Set-Cookie` carrying `Secure` received over a plain-HTTP channel is now discarded rather than stored.
|
|
26
|
+
- **Sessions Are No Longer Capped At 64 Connections** — The implicit per-session ceiling made unrelated high-concurrency workloads fail with `session connection limit reached`. The default is now unbounded; set `max_connections_per_session` explicitly to impose a budget.
|
|
27
|
+
- **Multi-Layer Content-Encoding Is Decoded** — A response carrying stacked encodings (for example `Content-Encoding: gzip, br`) is now fully decoded instead of being returned partly compressed. The zlib-wrapped form of `deflate` is also accepted, matching what browsers tolerate.
|
|
28
|
+
- **WebSocket Handshakes And Close Codes Are Validated** — the upgrade response was checked only for a `101`, which on its own proves nothing; a wrong or missing `Sec-WebSocket-Accept` merely logged a warning. RFC 6455 §4.1 makes that, a missing or wrong `Upgrade`/`Connection`, and any unoffered extension or subprotocol grounds for failing the connection, and all are enforced now. Enforcing it also uncovered that `Sec-WebSocket-Accept` was being computed with a GUID that is not the one §1.3 specifies, so the token never matched a conforming server — harmless while the check only warned. On the sending side, `1005`, `1006` and `1015` may never appear on the wire (§7.4.1) and are now rejected locally, along with over-long close reasons, instead of producing an invalid frame.
|
|
29
|
+
- **HSTS Is Learned Only From Secure Transport** — `Strict-Transport-Security` is no longer recorded from a plain-HTTP response, and never for IP-literal hosts.
|
|
30
|
+
- **Multipart Bodies Match Chrome** — Boundary generation and parameter escaping now follow Chrome's format. A `Content-Type` containing CR or LF is rejected outright, since — unlike the quoted `Content-Disposition` parameters, which are escaped — it cannot be encoded safely and would be a live header-injection vector.
|
|
31
|
+
- **Redirect Method Rewriting Follows The Spec** — The request method is now rewritten only in the cases the specification calls for, so `307` and `308` correctly preserve the original method and body.
|
|
32
|
+
- **Graceful HTTP/2 GOAWAY Is Honoured** — a graceful shutdown carries `NO_ERROR` and therefore set no connection error, while the draining check keyed off "has an error". The driver kept opening streams on a connection the peer had already promised to refuse. Google and Cloudflare send these routinely for connection turnover, so this showed up as sporadic failures under sustained load; queued requests now fail over to a fresh connection.
|
|
33
|
+
- **Alternative Services No Longer Supply The TLS Identity** — an Alt-Svc entry or DNS HTTPS record says *where* to send packets, but the endpoint must still prove it may serve the origin. The advertised host was used as the SNI and certificate name, so the alternative authenticated as itself. Besides the trust problem this broke conforming deployments outright, since an HTTPS RR `TargetName` is typically a CDN-internal name serving the origin's certificate.
|
|
34
|
+
- **Certificates Compressed With zstd Decompress** — `compress_certificate` advertises zlib, brotli and zstd (the Firefox 147 profile offers all three), but only zlib and brotli could be decoded, so a server that picked zstd failed the handshake. All three are handled now (RFC 8879).
|
|
35
|
+
- **Coalesced TLS Post-Handshake Messages Are Reassembled** — post-handshake messages follow the same framing as the handshake: several may share one record, and one may span several. Each record was treated as exactly one message, so a `KeyUpdate` sharing a record with a `NewSessionTicket` was silently dropped — read keys were never rotated and every record after it failed to decrypt — and coalesced tickets past the first were lost.
|
|
36
|
+
- **Protocol Hardening Across TLS, HTTP/2, QUIC And Alt-Svc** — Picks up a broad upstream compliance pass: TLS 1.2 renegotiation is refused with a fatal alert, the record layer and session-ticket trust are bounded, servers can no longer select parameters the client never offered, HTTP/2 enforces response pseudo-header rules and closes connections on peer protocol errors, `record_size_limit` is honoured when sending (RFC 8449), draft HTTP/3 Alt-Svc advertisements are ignored, and SOCKS5 authentication replies are version-checked.
|
|
37
|
+
|
|
5
38
|
## lkrequest-py 0.2.0
|
|
6
39
|
|
|
7
40
|
### 🚀 Features
|