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

Fix null status body response #172

Merged

Conversation

GregBrimble
Copy link
Member

import { fetch } from '@miniflare/core'

await fetch('https://some/url/which/returns/304')

fails because response.body always returns a ReadableStream, but the new Response() constructor expects null when setting some status codes.

Copy link
Contributor

@mrbbot mrbbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! This will close #165. Do you have time to write a test too: https://github.com/cloudflare/miniflare/blob/master/packages/core/test/standards/http.spec.ts? 🙂

res = new Response(baseRes.body, baseRes);
// https://fetch.spec.whatwg.org/#null-body-status
res = new Response(
[101, 204, 205, 304].includes(baseRes.status) ? null : baseRes.body,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: nullBodyStatus is defined earlier on in this file. This doesn't include 101, that should probably be added.

Suggested change
[101, 204, 205, 304].includes(baseRes.status) ? null : baseRes.body,
nullBodyStatus.includes(baseRes.status) ? null : baseRes.body,

@@ -796,7 +796,11 @@ export async function fetch(
headers,
});
} else {
res = new Response(baseRes.body, baseRes);
// https://fetch.spec.whatwg.org/#null-body-status
res = new Response(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disclaimer: I am very new to miniflare, so feel free to ignore my comment.

Nitpick: there are so many things happening in this function.
This is already an improvement in readability IMO:

const body = [101, 204, 205, 304].includes(baseRes.status) ? null : baseRes.body;
res = new Response(body, baseRes);

but the whole if/else could be moved to a separate function that would simply return the new response

function toHybridResponse(baseRes: Response): Response { // or any other naming that fits the project conventions
  if (baseRes.type !== "opaqueredirect") {
    const body = [101, 204, 205, 304].includes(baseRes.status) ? null : baseRes.body;
    return new Response(body, baseRes);
  }

  // Unpack opaque responses. This restriction isn't needed server-side,
  // and Cloudflare doesn't support Response types anyway.
  // @ts-expect-error symbol properties are not included in type definitions
  const internalResponse = baseRes[fetchSymbols.kState].internalResponse;
  const headersList = internalResponse.headersList;
  assert(headersList.length % 2 === 0);
  const headers = new Headers();
  for (let i = 0; i < headersList.length; i += 2) {
    headers.append(headersList[i], headersList[i + 1]);
  }
  // Cloudflare returns a body here, but undici aborts the stream so
  // unfortunately it's unusable :(
  return new Response(null, {
    status: internalResponse.status,
    statusText: internalResponse.statusText,
    headers,
  });
}

Copy link

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@mrbbot mrbbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 😃

@mrbbot mrbbot merged commit d21ba5f into cloudflare:master Feb 7, 2022
@mrbbot
Copy link
Contributor

mrbbot commented Feb 7, 2022

Hey! 👋 I've just released version 2.3.0 including this PR. You can find the full changelog here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants