You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Slice E of #182. Now that BodyReader: http_body::Body (6fb9c1b) and http::serve / http::fetch use Body directly (Slices C, D), the bespoke pump tasks that bridge channel-backed bodies into hyper become deletable. This slice removes the redundant pumps and lets BodyReader flow through Body::new directly into hyper's request/response.
This is the cleanup that turns "FFI plumbing exists alongside HTTP plumbing" into "FFI plumbing wraps HTTP plumbing".
Evidence
crates/iroh-http-core/src/stream.rs:600-997 defines pump_quic_recv_to_body, pump_body_to_quic_send, pump_duplex, plus pump_hyper_body_to_channel / pump_hyper_body_to_channel_limited in client.rs.
After Slice C, hyper polls BodyReader directly via its http_body::Body impl on the serve path — pump_hyper_body_to_channel becomes redundant on that path.
After Slice D, the same applies to pump_hyper_body_to_channel_limited on the fetch path.
The remaining legitimate uses (Session uni/bidi streams that pump raw QUIC bytes through user-visible BodyReader/BodyWriter handles) stay — they are part of the FFI session API contract, not redundant.
Remediation
Audit each pump function's call sites after Slices C and D have landed:
pump_hyper_body_to_channel / pump_hyper_body_to_channel_limited: expected to be deletable. Hyper now polls BodyReader directly via http_body::Body.
pump_quic_recv_to_body / pump_body_to_quic_send: still needed for Session::create_uni_stream / Session::next_uni_stream / Session::create_bidi_stream etc., where the FFI surface gives JS a BodyReader/BodyWriter handle directly.
pump_duplex: dead — raw_connect was dropped (8754da4), no other callers.
Delete the redundant pumps. Keep the ones with legitimate session-API call sites.
Where pumps remain, ensure they live in ffi/pumps.rs (after Slice A) — they are FFI plumbing, not HTTP plumbing.
Verify BodyReader::poll_frame correctness under hyper's drive: the existing implementation polls a pending future and recreates it on Pending drop. tokio mpsc recv is cancellation-safe; this is correct, but add a regression test that drives BodyReader through hyper end-to-end so the property is locked in.
Backpressure: BodyReader channel capacity (DEFAULT_CHANNEL_CAPACITY = 32) is the only buffer between QUIC and hyper. Confirm no perf regression on large body streaming via the existing benchmarks.
pump_duplex is deleted (no callers after raw_connect removal).
Remaining pumps (pump_quic_recv_to_body, pump_body_to_quic_send) live in ffi/pumps.rs with call sites only in mod ffi (Session API).
End-to-end test: a 10 MiB body streamed through http::serve → http::fetch round-trips correctly with bounded memory (no hidden buffering).
Benchmark suite shows no regression on body throughput vs. pre-slice baseline.
tests/architecture.rs is extended to enforce the canonical root layout end-to-end:
The walker covers src/ (not just src/http/).
It asserts the only entries directly under crates/iroh-http-core/src/ are lib.rs, endpoint.rs, http/, ffi/ — any other file or folder fails the test.
The TEMPORARY_EXCEPTIONS allowlist for the http → ffi import ban is empty. Slices C and D remove the three remaining entries (http/client.rs, http/server/mod.rs, http/session.rs); this slice removes any leftovers and asserts the empty list as a hard invariant.
Strictly depends on Slices C and D being merged first. Until then, the call-site analysis is hypothetical.
If during the audit a fourth use case for the pumps surfaces that we missed, surface it in #182 — it may indicate Slices C/D didn't deliver the promised body unification and need follow-up before this slice can land.
Summary
Slice E of #182. Now that
BodyReader: http_body::Body(6fb9c1b) andhttp::serve/http::fetchuseBodydirectly (Slices C, D), the bespoke pump tasks that bridge channel-backed bodies into hyper become deletable. This slice removes the redundant pumps and letsBodyReaderflow throughBody::newdirectly into hyper's request/response.This is the cleanup that turns "FFI plumbing exists alongside HTTP plumbing" into "FFI plumbing wraps HTTP plumbing".
Evidence
crates/iroh-http-core/src/stream.rs:600-997definespump_quic_recv_to_body,pump_body_to_quic_send,pump_duplex, pluspump_hyper_body_to_channel/pump_hyper_body_to_channel_limitedinclient.rs.BodyReaderdirectly via itshttp_body::Bodyimpl on the serve path —pump_hyper_body_to_channelbecomes redundant on that path.pump_hyper_body_to_channel_limitedon the fetch path.BodyReader/BodyWriterhandles) stay — they are part of the FFI session API contract, not redundant.Remediation
pump_hyper_body_to_channel/pump_hyper_body_to_channel_limited: expected to be deletable. Hyper now pollsBodyReaderdirectly viahttp_body::Body.pump_quic_recv_to_body/pump_body_to_quic_send: still needed forSession::create_uni_stream/Session::next_uni_stream/Session::create_bidi_streametc., where the FFI surface gives JS aBodyReader/BodyWriterhandle directly.pump_duplex: dead —raw_connectwas dropped (8754da4), no other callers.ffi/pumps.rs(after Slice A) — they are FFI plumbing, not HTTP plumbing.BodyReader::poll_framecorrectness under hyper's drive: the existing implementation polls apendingfuture and recreates it onPendingdrop. tokio mpscrecvis cancellation-safe; this is correct, but add a regression test that drivesBodyReaderthrough hyper end-to-end so the property is locked in.BodyReaderchannel capacity (DEFAULT_CHANNEL_CAPACITY = 32) is the only buffer between QUIC and hyper. Confirm no perf regression on large body streaming via the existing benchmarks.Acceptance criteria
pump_hyper_body_to_channelandpump_hyper_body_to_channel_limitedare deleted (or, if any legitimate caller remains, the rationale is documented in a comment that references this slice and epic: clean Rust core — mod http / mod ffi split + dynamic stack (supersedes ADR-014 drift) #182).pump_duplexis deleted (no callers afterraw_connectremoval).pump_quic_recv_to_body,pump_body_to_quic_send) live inffi/pumps.rswith call sites only inmod ffi(Session API).http::serve→http::fetchround-trips correctly with bounded memory (no hidden buffering).tests/architecture.rsis extended to enforce the canonical root layout end-to-end:src/(not justsrc/http/).crates/iroh-http-core/src/arelib.rs,endpoint.rs,http/,ffi/— any other file or folder fails the test.TEMPORARY_EXCEPTIONSallowlist for thehttp → ffiimport ban is empty. Slices C and D remove the three remaining entries (http/client.rs,http/server/mod.rs,http/session.rs); this slice removes any leftovers and asserts the empty list as a hard invariant.npm run cigreen; 92 interop pairs pass.Subsumes
http_body::Body/Sinkthe canonical primitive) — close as part of this slice.Notes
Strictly depends on Slices C and D being merged first. Until then, the call-site analysis is hypothetical.
If during the audit a fourth use case for the pumps surfaces that we missed, surface it in #182 — it may indicate Slices C/D didn't deliver the promised body unification and need follow-up before this slice can land.
References
6fb9c1b(BodyReader: impl http_body::Body)