Repository navigation
fix(net): write IETF data stream headers in one write - #6504
Conversation
Quest-Claim: 5209bb6520989d29
imquic parses a SUBGROUP_HEADER or FETCH_HEADER only from the first read of a stream and drops the rest when the header arrives split. The JS publisher wrote the header one field per write, so imquic received no objects from @moq/net over WebTransport. Write each header, stream type included, as one chunk, matching the Rust publisher and the one-write control messages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Outcome: cause found and reproduced. imquic drops a SUBGROUP_HEADER (and FETCH_HEADER) that arrives across more than one stream read, and @moq/net 0.4.4 wrote the header one field per write. This PR writes both headers in one write; the case passes against imquic with it and fails without it. Kept as a draft: posting the drafted imquic issue and keeping the change are maintainer decisions (see the body). (Written by Claude Opus 5.5) |
# Conflicts: # quest/m1/interop-coverage/js-imquic-objects.md # quest/m1/interop-coverage/runner-cases.md
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 15 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Merging. The maintainer settled both decisions recorded in the description: the imquic issue is filed as meetecho/imquic#43, and the single-write header is kept. CI passed 11/11, Codex reacted 👍 on this head, and (Written by Claude Opus 5.5) |
Works on quest/m1/interop-coverage/js-imquic-objects.md.
Cause
The runner's moq-dev-js
data-subgroup-basicgets no objects from imquic (draft-22, WebTransport). imquic is at fault, reported as meetecho/imquic#43:imquic_moq_parse_messagecreates a data stream on its first chunk, but only allocates the stream's buffer once the SUBGROUP_HEADER has parsed. When the header arrives across more than one read, the parse returns "need more data", the bytes are dropped, and every later chunk is appended to a NULL buffer (a silent no-op). At FIN the relay surfaces an empty object with alias 0 and logsNo track found for that subscription. FETCH_HEADER takes the same path. Still present on imquicmainatade3937.@moq/net0.4.4 writes the header one field perwrite(), and the@moq/web-transportpolyfill sent them as separate STREAM frames. The Rust publisher buffers the header, which is why moq-dev-rs passes.Change
Group.encode(SUBGROUP_HEADER) andFetchHeader.encodenow write the stream type and header in one write, like the one-write control messages from moq-dev/moq#6255. The fetch path no longer writes its stream type separately. The bytes on the wire are unchanged. The quest is rewritten to what remains: rechecking the cell once imquic or the runner's client moves. The interop audit lists the imquic issue with the other upstream reports.Consumer: every JS publisher talking moq-transport, here the runner's moq-dev-js client against imquic.
Public API: none (
ietf/wire types are internal). Wire: none.Verification
Against the runner's
ghcr.io/englishm/moq-interop-runner-imquic-moq-relay:latestlocally and the registeredhttps://lminiero.it:9000:Group.encodewrites once: passes 3/3 locally and againstlminiero.it.main's API: passes 3/3 with this PR, fails 2/2 without it.Decisions
Checks
just check: pass (after mergingmain).bun test src/ietfinjs/net: 803 pass.just test interop --all: pass (164 cases, none failed or skipped).Follow-ups
main,request(path, { announced: true })over moq-transport asks SUBSCRIBE_NAMESPACE for the exact path, and imquic never answers with the shorter routing prefix the publisher announced, so the runner case stalls before it subscribes. 0.4.4 asked for the scoped prefix. The runner client hits this when it moves past 0.4.4. Tracked in the quest's Remaining list.js -> rustfailed on drafts 14, 16, and 18 injust test interop --versions ietfonmainlocally before this change too (the JS publisher ends the catalog track with PUBLISH_DONE straight after SUBSCRIBE_OK). Check the nightly before planning.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code