Skip to content

feat(network): poll-driven HTTP server and client over TcpNetwork - #133

Merged
louisponet merged 1 commit into
mainfrom
lopo/http_server
Aug 24, 2026
Merged

feat(network): poll-driven HTTP server and client over TcpNetwork#133
louisponet merged 1 commit into
mainfrom
lopo/http_server

Conversation

@louisponet

Copy link
Copy Markdown
Contributor

Summary

Adds flux_network::http::HttpNetwork — a poll-driven HTTP/1.x layer on top of TcpNetwork. One instance runs server and client in a single event loop: it can listen for inbound requests and maintain persistent outbound endpoints, delivering parsed requests/responses as borrowed events through poll_with.

HTTP layer (http.rs, new)

  • Server: listen + HttpEvent::Request; responses via respond(token, status, headers, body), deferrable to a later poll (one pending request per connection, pipelined requests stay buffered behind it). Handles Expect: 100-continue, HEAD semantics, HTTP/1.0/1.1 keep-alive vs close, and protocol errors (400/413/431/501) before user code sees anything.
  • Client: connect + request(token, method, path, headers, body) (one in flight per endpoint); responses support Content-Length, chunked, and EOF-delimited bodies, with interim responses skipped.
  • Configurable head/body/header-count limits and idle timeout for accepted connections. Routing is intentionally left to the caller (match on request.method / request.path).
  • Head parsing uses httparse (new workspace dep); body/chunked handling is in-crate.

TcpNetwork changes (network.rs)

  • Per-group Framing: existing LengthPrefixed (default, unchanged) or new Raw passthrough. Raw groups cap read chunks at max_frame_size, stamp events with local receive time, and skip latency telemetry (no wire timestamps).
  • disconnect_when_drained(token): close after queued bytes flush (used for Connection: close responses); sends to a draining token are rejected.
  • ByteQueue remainder path generalized to an optional header prefix to serve both framings.

Testing

  • just fmt / just clippy clean (zero warnings).
  • New tests: 872-line HTTP integration suite (tests/http.rs), raw-framing suite (tests/tcp_network_raw.rs), and byte-queue unit tests.
  • cargo test --workspace --all-features --locked passes. Note: in repeated local runs the pre-existing tcp_multi_client_backpressure test flaked once under heavy machine load (fixed 5s deadline pushing 8MB through 1KB socket buffers); it exercises TcpConnector (connector.rs/stream.rs), which this PR does not touch, and passes on retry.

Introduce flux_network::http::HttpNetwork, a single-event-loop HTTP/1.x
layer on top of TcpNetwork. One instance can listen for inbound requests
and maintain persistent outbound endpoints; parsed requests and responses
are delivered borrowed through poll_with, and responses may be deferred
across polls (one pending request per connection, pipelining buffered).

Server side supports Content-Length request bodies, automatic
Expect: 100-continue, HEAD semantics, keep-alive/close negotiation, and
protocol errors (400/413/431/501) handled before user code. Client side
supports Content-Length, chunked, and EOF-delimited response bodies with
interim-response skipping. Head/body/header-count limits and an idle
timeout for accepted connections are configurable.

To carry HTTP on the wire, TcpNetwork gains a per-group Framing choice:
the existing length-prefixed framing (default) or new raw passthrough
which caps read chunks at max_frame_size and skips latency telemetry
(no send timestamps). Also adds disconnect_when_drained so a server can
flush a final response before closing, with sends rejected while
draining. The ByteQueue remainder path is generalized to optional
headers to serve both framings.

httparse (workspace dep) does head parsing; body handling stays in flux.
@louisponet
louisponet requested a review from a team August 24, 2026 16:13
@louisponet
louisponet merged commit 2a19164 into main Aug 24, 2026
3 checks passed
@louisponet
louisponet deleted the lopo/http_server branch August 24, 2026 20:04
@Bronek Bronek mentioned this pull request Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants