Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Response.clone does not clone in-progress streaming body #6348

Closed
robere2 opened this issue Oct 6, 2023 · 12 comments · Fixed by #13744
Closed

Response.clone does not clone in-progress streaming body #6348

robere2 opened this issue Oct 6, 2023 · 12 comments · Fixed by #13744
Labels
bug Something isn't working web-api Something that relates to a standard Web API

Comments

@robere2
Copy link

robere2 commented Oct 6, 2023

What version of Bun is running?

1.0.4

What platform is your computer?

Linux 5.10.60.1-microsoft-standard-WSL2 x86_64 x86_64

What steps can reproduce the bug?

Calling the clone() method on a Response object should return an identical Response object, including the body. Instead, it returns a Response that's missing the body, but otherwise identical in every other way (that I've found).

Minimal reproducible example:

const res = await fetch("https:/");
console.log("Clone Response length:", (await res.clone().text()).length)
console.log("Main Response length:", (await res.text()).length)

What is the expected behavior?

The program should output two lines to the console, and each should contain the same integer number.

What do you see instead?

The first line will contain the number "0" while the second line contains the expected value.

Additional information

No response

@robere2 robere2 added the bug Something isn't working label Oct 6, 2023
@Hanaasagi
Copy link
Collaborator

Related to #4765

@Electroid
Copy link
Contributor

Duplicate of #4765

@Electroid Electroid marked this as a duplicate of #4765 Oct 9, 2023
@Electroid Electroid added the web-api Something that relates to a standard Web API label Oct 9, 2023
@dangeredwolf
Copy link

dangeredwolf commented Jan 22, 2024

Regression of #913, related to #6969. Also seems to be a duplicate of #1381 and #2477. This is a pretty big issue breaking a lot of things, I hope someone will finally pay attention to it because of how many things this bug effects. There's already an open PR for it, #1693, oh, and in #6468 as well!

@liz3
Copy link
Contributor

liz3 commented Jan 22, 2024

Theres a open pr for ages but the maintainers don't prio such fixes over other things:
#6468

@BoltDoggy
Copy link

BoltDoggy commented Mar 12, 2024

Maybe Polyfill

Request.prototype.clone = function (this: Request) {
  const { body } = this;
  const teedX = body?.tee();
  Object.defineProperty(this, "body", {
    get() {
      return teedX?.[0] || null;
    },
  });  return new Request(this, {
    body: teedX?.[1] || null,
  });
};

More Idea

Request.prototype.breakClone = function (this: Request) {
  const {
    url,
    method,
    headers,
    cache,
    credentials,
    destination,
    integrity,
    keepalive,
    mode,
    redirect,
    referrer,
    referrerPolicy,
    signal,
    bodyUsed,
    body,
    clone,
  } = this;
  const teedX = body?.tee();
  const arrayBufferPromise = new Response(teedX?.[0]).arrayBuffer();
  const teedY = teedX?.[1].tee();
  Object.defineProperty(this, "body", {
    get() {
      return teedY?.[0] || null;
    },
  });
  return {
    url,
    method,
    headers,
    cache,
    credentials,
    destination,
    integrity,
    keepalive,
    mode,
    redirect,
    referrer,
    referrerPolicy,
    signal,
    bodyUsed,
    body: teedY?.[1] || null,
    clone,
    arrayBuffer: async () => arrayBufferPromise,
    json: async () => new Response(await arrayBufferPromise).json(),
    text: async () => new Response(await arrayBufferPromise).text(),
    blob: async () => new Response(await arrayBufferPromise).blob(),
    formData: async () => new Response(await arrayBufferPromise).formData(),
  };
};

@vitch
Copy link
Contributor

vitch commented Jul 22, 2024

I've just run into this...

I was trying to show the text() of a Response if response.json() failed.

This gives an error:

try {
  let responseData = await response.json();
} catch (e) {
  let text = await response.text();
  // ...
}

Body already used

According to this SO answer using response.clone() is the correct way around this. But in bun 1.1.20 it's failing for me and the cloneed body() is an empty string...

@bholmesdev
Copy link

We've run into this issue when implementing our Actions pattern in Astro. We rely on clone() to internally handle incoming requests, and allow the user to read that body from their request handler as well. This bug is unfortunately a blocker for those using the latest version of Astro with Bun.

I'd love to see a fix implemented for this!

@mangs
Copy link
Contributor

mangs commented Aug 13, 2024

@bholmesdev This is the PR adding this functionality, I'm blocked on this too. #12473

@jadbox
Copy link

jadbox commented Aug 14, 2024

This is a blocker for us as we also need to clone the request for our tooling, including for @bholmesdev Astro Actions.

@jadbox
Copy link

jadbox commented Aug 18, 2024

I'm not sure if this helps, but I have a small update from Jarred on a Bun/Astro workaround until request cloning is fixed.

Screenshot_20240818-090649.png

@QuentinDutot
Copy link

Got the same error while trying to use bun with h3 (v2)

await request.json() // works
await request.clone().json() // doesn't work
await new Request(request).json() // doesn't work

@Jarred-Sumner Jarred-Sumner changed the title Response clone method does not clone the body Response.clone does not clone in-progress streaming body Aug 29, 2024
Jarred-Sumner added a commit that referenced this issue Sep 5, 2024
Fixes #6348
Fixes #1381
Fixes #2477
Fixes #2644
Fixes #10789
Fixes #4161
@Jarred-Sumner
Copy link
Collaborator

The fix for this will be included in Bun v1.1.27

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working web-api Something that relates to a standard Web API
Projects
None yet
Development

Successfully merging a pull request may close this issue.