Skip to content

quic: http/3 writer interface stream is closed with fin #63382

@martenrichter

Description

@martenrichter

While trying to do a sort of Webtransport client, I have issues with creating a bidirectional stream.
I do:

this.sessionInt
      .createBidirectionalStream({
        headers: {
          ':method': 'CONNECT',
          ':scheme': 'https',
          // this one depends on draft, draft14 says "webtransport", draft15 says "webtransport-h3"
          ':protocol': 'webtransport',
          ':path': path,
          ':authority': this.hostname + ':' + this.port
        },
        onheaders(headers) {
          headersReceivedResolve(headers)
        }
      })
      .then((stream) => {

where this.sessionInt is created through connect.
My plan was to later get a writer and write something.
However, I see on the non-node.js server immediately the arrival of a fin, signaling stream end.
Looking at the test mades so far:

const stream = await clientSession.createBidirectionalStream();
const w = stream.writer;

it seems to be a valid pattern to get the writer later.
After a few hours of debugging (I followed the handlers from nghttp3 up to the js side), I found the cause:

stream.sendHeaders(headers, { terminal: validatedBody === undefined });

The terminal flag , which send on nghttp3 level the fin, is sent depending on passed on body or not.
@jasnell
For me, it looks like an api design problem. As the opened stream can not know if it is planned to get a stream.writer. So I wonder why the tests worked? Probably a race condition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions