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

esm: treat 307 and 308 as redirects in HTTPS imports #43689

Merged
merged 4 commits into from
Jul 9, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions lib/internal/modules/esm/fetch_module.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ function fetchWithRedirects(parsed) {
// `finally` on network error/timeout.
const { 0: res } = await once(req, 'response');
try {
const isRedirect = res.statusCode >= 300 && res.statusCode <= 303;
const isRedirect = res.statusCode >= 300 && (
res.statusCode <= 303 ||
res.statusCode === 307 ||
res.statusCode === 308
);
kidonng marked this conversation as resolved.
Show resolved Hide resolved
const hasLocation = ObjectPrototypeHasOwnProperty(res.headers, 'location');
if (isRedirect && hasLocation) {
const location = new URL(res.headers.location, parsed);
Expand All @@ -127,7 +131,12 @@ function fetchWithRedirects(parsed) {
err.message = `Cannot find module '${parsed.href}', HTTP 404`;
throw err;
}
if (res.statusCode > 303 || res.statusCode < 200) {
if (
(
res.statusCode > 303 &&
res.statusCode !== 307 &&
res.statusCode !== 308
) || res.statusCode < 200) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This part makes me wonder if original flow is correct. If the response isRedirect && !hasLocation, shouldn't we throw? Especially if we deal with 300 Multiple Choices.
This concern is not blocking and can be addressed separately, the change itself LGTM.

Copy link
Member

Choose a reason for hiding this comment

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

I think if the server returns 300 Multiple Choices and no Location, it should be treated as unresolvable/fail (or follow the Location if provided).

Perhaps a custom loader should be used deal with Multiple Choices.

Copy link
Contributor

Choose a reason for hiding this comment

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

To be fair, I'm not even sure if there are reasonable use cases to import a body of response with any 2xx code other than 200.

Copy link
Member

Choose a reason for hiding this comment

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

I often get the body from a 201 as "a representation of the thing that was created".

Copy link
Contributor

@LiviaMedeiros LiviaMedeiros Jul 6, 2022

Choose a reason for hiding this comment

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

From a GET request? May I ask in which scenario it's required or has high probability of happening?

Copy link
Member

Choose a reason for hiding this comment

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

oh true, i wouldn't expect a 201 from a GET request :-) a 204 (no body) or 206 (partial body) maybe, though

Copy link
Contributor

Choose a reason for hiding this comment

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

206 probably shouldn't happen there (i.e. we don't send any Range so partial body is not what should be expected), 204 restricts having a body at all... Although yes, technically we can import {} from 'https://example.com/204-no-content.mjs'; and there's nothing really wrong about that. 😄

throw new ERR_NETWORK_IMPORT_DISALLOWED(
res.headers.location,
parsed.href,
Expand Down