https #6
No reviewers
Labels
No labels
claude:blocked
claude:done
claude:failed
claude:in-progress
claude:ready
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Catcrafts/Crafter.Network!6
Loading…
Reference in a new issue
No description provided.
Delete branch "claude/issue-3"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
HTTP/1.1 was plaintext-only, which left `https://` to either an HTTP/3 listener or a terminating proxy in front. Neither helps the callers this stack exists for — curl scripts, CI tooling, old proxies — so wrap the transport in libssl instead. Two new partitions: :Stream a ByteStream with per-call deadlines on both directions, plus the plaintext socket implementation. The HTTP/1.1 client and listener now hold a ByteStream& and never learn which transport they have, which is what lets one code path serve both schemes. :TLS TLSContext/TLSStream over OpenSSL 3, with credentials for both roles: chain and hostname verification on by default, private trust anchors, client certificates, mutual TLS, ALPN, and an in-process self-signed certificate for development. Both descriptors go non-blocking and every read and write is driven by poll() against a deadline. That is required for TLS — a blocking descriptor cannot express a handshake timeout — and it means a plaintext write can now time out too, instead of parking forever against a peer that stopped reading. ClientHTTP1 and ListenerHTTP1 gain credential-taking constructors; the existing ones still speak http://. The listener handshakes on the connection's own thread, so a peer that stalls mid-handshake costs one thread rather than the accept loop, and a failed handshake is counted rather than logged — on a public port it is ordinary traffic. MessageParser gains SetDefaultScheme so origin-form targets report the scheme the transport actually used; handlers shared with ListenerHTTP now see the same "https" they would over HTTP/3. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>ShouldSendRecieveHTTPS1 replays the plaintext round-trip over TLS, so a regression in the transport shows up as an HTTP failure rather than nothing at all, and adds what only exists under TLS: ALPN, scheme=https reaching handlers, a body spanning many records, and the two ways verification must fail — an untrusted self-signed certificate, and a trusted certificate presented for the wrong name. A plaintext peer knocking on the TLS port is asserted to be counted and shrugged off. ShouldInteropCurlHTTPS1 puts real implementations on the other end, since two OpenSSL peers can agree on a mistake. curl verifies our certificate with --cacert rather than --insecure, and an h2-only curl is asserted to be refused rather than mis-served. python3's http.server behind ssl.wrap_socket answers HTTP/1.0 with Connection: close, which frames the body by close_notify — the path a reader is most likely to get wrong. ShouldRequireClientCertificateHTTPS1 covers mutual TLS both ways, and drives TLSStream directly with hand-written HTTP/1.1 to keep the :TLS layer honest as something usable without :ClientHTTP1 on top. Also fix a delegation that `{}` no longer disambiguates now that a three-argument TLS constructor exists alongside the fallback one. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>