Skip to content

Commit

Permalink
esm: treat 307 and 308 as redirects in HTTPS imports
Browse files Browse the repository at this point in the history
Per RFC 7231 and 7238, HTTP `307` and `308` status code are also for
redirect responses.

Fixes: #43679
Refs: https://datatracker.ietf.org/doc/html/rfc7231#section-6.4.7
Refs: https://datatracker.ietf.org/doc/html/rfc7238

PR-URL: #43689
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Zijian Liu <lxxyxzj@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
  • Loading branch information
kidonng authored and targos committed Jul 20, 2022
1 parent 6269549 commit 2d51256
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions lib/internal/modules/esm/fetch_module.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ function createUnzip() {
return createUnzip();
}

/**
* Redirection status code as per section 6.4 of RFC 7231:
* https://datatracker.ietf.org/doc/html/rfc7231#section-6.4
* and RFC 7238:
* https://datatracker.ietf.org/doc/html/rfc7238
* @param {number} statusCode
* @returns {boolean}
*/
function isRedirect(statusCode) {
switch (statusCode) {
case 300: // Multiple Choices
case 301: // Moved Permanently
case 302: // Found
case 303: // See Other
case 307: // Temporary Redirect
case 308: // Permanent Redirect
return true;
default:
return false;
}
}

/**
* @param {URL} parsed
* @returns {Promise<CacheEntry> | CacheEntry}
Expand All @@ -107,9 +129,8 @@ 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 hasLocation = ObjectPrototypeHasOwnProperty(res.headers, 'location');
if (isRedirect && hasLocation) {
if (isRedirect(res.statusCode) && hasLocation) {
const location = new URL(res.headers.location, parsed);
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
throw new ERR_NETWORK_IMPORT_DISALLOWED(
Expand All @@ -127,7 +148,7 @@ function fetchWithRedirects(parsed) {
err.message = `Cannot find module '${parsed.href}', HTTP 404`;
throw err;
}
if (res.statusCode > 303 || res.statusCode < 200) {
if (res.statusCode < 200 || res.statusCode >= 400) {
throw new ERR_NETWORK_IMPORT_DISALLOWED(
res.headers.location,
parsed.href,
Expand Down

0 comments on commit 2d51256

Please sign in to comment.