Skip to content

improperly teeing streams in .clone() #5358

Description

@KhafraDev

#rs-tee (webstreams) (this is how ReadableStream.prototype.tee is implemented):

Return ? ReadableStreamTee(this, false).

#concept-body-clone (fetch):

Let « out1, out2 » be the result of teeing body’s stream.

"teeing" links to #readablestream-tee (webstreams) (how .clone() tees the streams):

return ? ReadableStreamTee(stream, true).

... which has the note:

Because we pass true as the second argument to ReadableStreamTee, the second branch returned will have its chunks cloned ... from those of the first branch. This prevents consumption of one of the branches from interfering with the other.

Originally posted by @KhafraDev in #5318 (comment)

We need access to ReadableStreamTee from node core. https://github.com/nodejs/node/blob/4219808375c022da1defb4e402fb785f91c6ed50/lib/internal/webstreams/readablestream.js#L1696

const c = new AbortController();

const r = await fetch(
  new URL("/", globalThis.location?.href ?? "https://example.com/"),
  { signal: c.signal },
);

const r2 = r.clone(); // Clone it.

c.abort();

console.log((await r2.text()).slice(0, 100)); // This shouldn't throw

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions