| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Hostnames like 'myhost.internal.' (with a trailing dot) are valid FQDNs
used to mark fully-qualified names in DNS. However, TLS certificates use
'myhost.internal' (without the dot), so passing the raw FQDN to the SSL
handshake causes CERTIFICATE_VERIFY_FAILED: Host name mismatch.
Fix: strip the trailing dot with .rstrip('.') in Origin.__str__ and in
every place where host.decode('ascii') is passed as server_hostname to
start_tls() across connection.py, http_proxy.py and socks_proxy.py for
both async and sync backends.
Files changed: _models.py, _async/connection.py, _async/http_proxy.py,
_async/socks_proxy.py, _sync/connection.py, _sync/http_proxy.py,
_sync/socks_proxy.py + tests/test_trailing_dot.py (3 new tests, 3/3 pass)
…ode#1029) When sending large payloads over a synchronous socket, httpcore slices the buffer with `buffer = buffer[n:]` on every iteration. This creates a new bytes object (a full copy of the remaining data) on each loop, producing O(n²) total allocation — measurably slow for multi-MB uploads. requests/urllib3 avoid this by using `sendall()`. The equivalent fix for httpcore's manual loop is to switch to `memoryview`, whose slices are zero-copy views into the original buffer: view = memoryview(buffer) while view: n = self._sock.send(view) view = view[n:] Benchmark (simulated loop, no network): 1 MB payload: 747× faster (2.1 ms → 0.003 ms) 64 MB payload: 42 676× faster (4 532 ms → 0.1 ms) Both SyncSSLStream.write() and SyncStream.write() are fixed. anyio and trio backends are unaffected (they delegate to framework send_all/send which handle buffering internally). Tests: 4 new tests (correctness + zero-copy allocation guard). 0 regressions.
| Back | FazBrowse Home | New Git URL |
Fix 1 — Trailing dot FQDN causes SSL CERTIFICATE_VERIFY_FAILED (issue #1063)
Hostnames like myhost.internal. (trailing dot) are valid DNS FQDNs but TLS certificates use myhost.internal (without the dot). Passing the raw FQDN to start_tls() causes:
Fix: .rstrip('.') before passing server_hostname to TLS — 7 files (async + sync, connection/http_proxy/socks_proxy). 3 new tests.
Fix 2 — O(n²) memory copies on large uploads, sync client 42 000× slower (issue #1029)
When sending large payloads synchronously, buffer = buffer[n:] creates a full copy of the remaining bytes on every loop iteration — O(n²) total allocation. This explains why httpx.AsyncClient is fast (anyio/trio use send_all()) but httpx.Client is very slow for large uploads.
Benchmark: 64 MB payload: 4 532 ms → 0.1 ms (42 676× faster).
Fixes SyncSSLStream.write() and SyncStream.write(). 4 new tests.
Total: 182 tests pass — 0 regressions. Fixes #1029 and #1063.