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

v17.7.0 release proposal #42254

Merged
merged 81 commits into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
a4969d5
doc: add release key for Bryan English
bengl Feb 24, 2022
f7ea75f
lib: add legacy built-in functions to primordials
aduh95 Feb 21, 2022
e3347db
meta: remove collaborator
Trott Feb 21, 2022
9930146
test: increase Fibonacci argument to 40
Trott Feb 21, 2022
3789d66
doc: add missing api entries on performance
legendecas Feb 16, 2022
a2926c4
net: add new options to `net.Socket` and `net.Server`
ShogunPanda Feb 22, 2022
8b531da
doc: clarify supported versus enabled TLS ciphers
tniessen Feb 22, 2022
0ce00ca
doc: move bnoordhuis back to collaborators
bnoordhuis Feb 22, 2022
288f627
crypto: clarify `require("crypto").getRandomValues` is Node.js specific
aduh95 Feb 22, 2022
bd04fc8
doc: clarify persistent ref behavior
mhdawson Feb 17, 2022
03ebca8
build: update feature close action for testing
mhdawson Feb 22, 2022
d6b1a4a
repl: remove preview when press escape
meixg Feb 19, 2022
482b220
test: validate `EventEmitterAsyncResource` methods throw on invalid this
kuriyosh Feb 22, 2022
eb622a0
doc: add meixg to triagers
meixg Feb 23, 2022
e0448da
meta: move one or more collaborators to emeritus
nodejs-github-bot Feb 23, 2022
7ed2c19
meta: correct link to feature request document
SimenB Feb 23, 2022
7c49785
process: fix named report export
madflow Feb 4, 2022
26fe61b
doc: document change to IncomingMessage.headers enumerability
ArnoldZokas Feb 23, 2022
8431fb9
stream: port more test262 tests
benjamingr Feb 23, 2022
96510b3
module: prefer async/await in https imports
benjamingr Feb 12, 2022
86248f1
src: allow preventing InitializeInspector in env
codebytere Feb 23, 2022
8b94ea6
doc,tools: improve navigability of API docs
ShogunPanda Feb 24, 2022
f107f8b
node-api: fix typo in `node_api.cc`
austinkelleher Feb 24, 2022
d0f68a3
test: deflake test-common-expect-warning
lpinca Feb 18, 2022
a32ec98
doc: make building with ninja more discoverable
bavulapati Feb 25, 2022
53338fe
stream: allow returning null from pipeline tail
ronag Feb 25, 2022
769e2a4
deps: V8: cherry-pick b66334313c8b
luyahan Feb 21, 2022
1359f60
deps: V8: cherry-pick 77d515484864
luyahan Feb 21, 2022
ec4c0de
build: last test of the stale feature action
mhdawson Feb 22, 2022
2e1231b
errors: do not access .stack in debug
bcoe Feb 25, 2022
3fc3f52
build: add corepack to the auto-updated dependencies
arcanis Feb 25, 2022
ccacf99
deps: upgrade npm to 8.5.2
npm-robot Feb 24, 2022
c72c3f4
perf_hooks: do not return all entries with getEntriesBy[Name|Type]
meixg Feb 26, 2022
5d010bc
doc: remove repeated a word
apeltop Feb 26, 2022
384872f
lib: clean after the cancel algorithm throw error
MoonBall Feb 26, 2022
2b35422
crypto: add KeyObject.prototype.equals method
panva Feb 26, 2022
c9ea6a9
crypto: validate `this` value for `webcrypto.getRandomValues`
aduh95 Feb 26, 2022
28f6364
tools: update eslint to 8.10.0
nodejs-github-bot Feb 27, 2022
cad7dde
meta: update AUTHORS
nodejs-github-bot Feb 27, 2022
2bc136d
esm: fix relative imports for https
bmeck Feb 27, 2022
0b8efea
deps: update nghttp2 to 1.47.0
yashLadha Feb 27, 2022
576c1ae
fs: adjust default `length` for `fs.readSync` and fsPromises/`read`
LiviaMedeiros Feb 27, 2022
3366618
src: simplify GetExponentString
tniessen Feb 27, 2022
07de4ed
src: do not ignore return value of BIO_reset
tniessen Feb 27, 2022
382ffda
src: simplify arg type of AddFingerprintDigest
tniessen Feb 27, 2022
97f5ced
src: prefer bool over int in crypto_common
tniessen Feb 27, 2022
f0558d8
src: simplify TLSWrap::SetSession
tniessen Feb 27, 2022
4c9f2b5
src: combine GetCurveASN1Name and GetCurveNistName
tniessen Feb 27, 2022
0413736
http: add default argument for Agent.prototype.getName
xtx1130 Feb 27, 2022
d05758f
buffer: improve blob read performance
meixg Feb 27, 2022
41b6d9e
tools: update lint-md rollup dependencies
nodejs-github-bot Feb 27, 2022
853cbd9
build: increase max ops for stale feature action
mhdawson Feb 25, 2022
4e9fac6
build: fix usage of input in feature action
mhdawson Feb 28, 2022
ce86fc3
doc: remove reference to obsolete security program
Trott Mar 1, 2022
f21fbee
test: update V8 trace events test expectations
nickie Feb 24, 2022
ce40927
src: remove dead code in AddFingerprintDigest
tniessen Mar 1, 2022
9bc7a95
http2: close stream and session on frameError
RafaelGSS Mar 2, 2022
3df001f
doc: add JakobJingleheimer to collaborators list
JakobJingleheimer Mar 2, 2022
84859c4
doc: fix typos
apeltop Mar 2, 2022
ee02739
doc: add missing single-quotes to `http.OutgoingMessage`
juanarbol Mar 1, 2022
9aeda47
url: fix url.parse() for @hostname
Trott Feb 26, 2022
06e5c0e
stream: use .chunk when calling adapters's writev
meixg Mar 3, 2022
6a74fa9
doc: add next-10 to strategic initiatives
mhdawson Mar 1, 2022
0bbb447
build: drop shortened URL from lint-commit-message
richardlau Mar 3, 2022
04d2c74
doc: use parenthesis instead of em dash
aduh95 Mar 3, 2022
ceb47d1
test: fix test-process-env-tz.js by using RegExp
XadillaX Mar 4, 2022
8dd4878
esm: fix base URL for network imports
bmeck Feb 25, 2022
a6c1abf
doc: add note about nghttp2 hd pair size
RafaelGSS Mar 5, 2022
05c3ff5
doc: clarify that some modules don't work when compiled without ssl
aduh95 Mar 5, 2022
7f1c83e
loader: fix esm resolve for symlink file
meixg Mar 6, 2022
5b23e67
meta: update AUTHORS
nodejs-github-bot Mar 6, 2022
0abc20b
src: skip revoke_data_object if uuid is not found
meixg Mar 6, 2022
0be3c61
test: cover 32-bit sizes in generatePrime
tniessen Mar 6, 2022
c01134e
tools: update lint-md-dependencies to rollup@2.69.1
nodejs-github-bot Mar 6, 2022
555da9b
doc: remove "considered" for clarity
Trott Mar 6, 2022
1de8087
http2: add edge case to GOAWAY request
RafaelGSS Mar 6, 2022
6183749
doc: remove erroneous comma in cluster explainer
tniessen Mar 7, 2022
ecb5980
url, src: modify one `special_back_slash`
XadillaX Feb 24, 2022
98b1be0
src: return proper URLs from node_api_get_module_file_name
addaleax Jan 29, 2022
fc7d429
doc: update stale feature messages
mhdawson Mar 4, 2022
05c2520
2022-03-09, Version 17.7.0 (Current)
sxa Mar 8, 2022
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
Prev Previous commit
Next Next commit
module: prefer async/await in https imports
PR-URL: #41950
Fixes: #41950
Reviewed-By: Guy Bedford <guybedford@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
benjamingr authored and sxa committed Mar 7, 2022
commit 96510b3411dbb03c5f69f17683c76a5cc6013b1d
172 changes: 68 additions & 104 deletions lib/internal/modules/esm/fetch_module.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
'use strict';
const {
ArrayPrototypePush,
Promise,
ObjectPrototypeHasOwnProperty,
PromisePrototypeThen,
PromiseResolve,
SafeMap,
StringPrototypeEndsWith,
StringPrototypeSlice,
StringPrototypeStartsWith,
} = primordials;
const {
Buffer: {
concat: BufferConcat
}
Buffer: { concat: BufferConcat },
} = require('buffer');
const {
ERR_NETWORK_IMPORT_DISALLOWED,
ERR_NETWORK_IMPORT_BAD_RESPONSE,
ERR_MODULE_NOT_FOUND,
} = require('internal/errors').codes;
const { URL } = require('internal/url');
const net = require('net');

const { once } = require('events');
const { compose } = require('stream');
/**
* @typedef CacheEntry
* @property {Promise<string> | string} resolvedHREF
Expand All @@ -32,6 +30,9 @@ const net = require('net');
* Only for GET requests, other requests would need new Map
* HTTP cache semantics keep diff caches
*
* It caches either the promise or the cache entry since import.meta.url needs
* the value synchronously for the response location after all redirects.
*
* Maps HREF to pending cache entry
* @type {Map<string, Promise<CacheEntry> | CacheEntry>}
*/
Expand All @@ -47,23 +48,23 @@ let HTTPSAgent;
function HTTPSGet(url, opts) {
const https = require('https'); // [1]
HTTPSAgent ??= new https.Agent({ // [2]
keepAlive: true
keepAlive: true,
});
return https.get(url, {
agent: HTTPSAgent,
...opts
...opts,
});
}

let HTTPAgent;
function HTTPGet(url, opts) {
const http = require('http'); // [1]
HTTPAgent ??= new http.Agent({ // [2]
keepAlive: true
keepAlive: true,
});
return http.get(url, {
agent: HTTPAgent,
...opts
...opts,
});
}

Expand Down Expand Up @@ -98,118 +99,79 @@ function fetchWithRedirects(parsed) {
return existing;
}
const handler = parsed.protocol === 'http:' ? HTTPGet : HTTPSGet;
const result = new Promise((fulfill, reject) => {
const result = (async () => {
const req = handler(parsed, {
headers: {
Accept: '*/*'
}
})
.on('error', reject)
.on('response', (res) => {
function dispose() {
req.destroy();
res.destroy();
}
if (res.statusCode >= 300 && res.statusCode <= 303) {
if (res.headers.location) {
dispose();
try {
const location = new URL(res.headers.location, parsed);
if (location.protocol !== 'http:' &&
location.protocol !== 'https:') {
reject(new ERR_NETWORK_IMPORT_DISALLOWED(
res.headers.location,
parsed.href,
'cannot redirect to non-network location'));
return;
}
return PromisePrototypeThen(
PromiseResolve(fetchWithRedirects(location)),
(entry) => {
cacheForGET.set(parsed.href, entry);
fulfill(entry);
});
} catch (e) {
dispose();
reject(e);
}
headers: { Accept: '*/*' },
});
// Note that `once` is used here to handle `error` and that it hits the
// `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) {
const location = new URL(res.headers.location, parsed);
if (location.protocol !== 'http:' && location.protocol !== 'https:') {
throw new ERR_NETWORK_IMPORT_DISALLOWED(
res.headers.location,
parsed.href,
'cannot redirect to non-network location'
);
}
const entry = await fetchWithRedirects(location);
cacheForGET.set(parsed.href, entry);
return entry;
}
if (res.statusCode === 404) {
const err = new ERR_MODULE_NOT_FOUND(parsed.href, null);
err.message = `Cannot find module '${parsed.href}', HTTP 404`;
throw err;
}
if (res.statusCode > 303 || res.statusCode < 200) {
dispose();
reject(
new ERR_NETWORK_IMPORT_BAD_RESPONSE(
parsed.href,
'HTTP response returned status code of ' + res.statusCode));
return;
throw new ERR_NETWORK_IMPORT_DISALLOWED(
res.headers.location,
parsed.href,
'cannot redirect to non-network location');
}
const { headers } = res;
const contentType = headers['content-type'];
if (!contentType) {
dispose();
reject(new ERR_NETWORK_IMPORT_BAD_RESPONSE(
throw new ERR_NETWORK_IMPORT_BAD_RESPONSE(
parsed.href,
'the \'Content-Type\' header is required'));
return;
"the 'Content-Type' header is required"
);
}
/**
* @type {CacheEntry}
*/
const entry = {
resolvedHREF: parsed.href,
headers: {
'content-type': res.headers['content-type']
'content-type': res.headers['content-type'],
},
body: new Promise((f, r) => {
const buffers = [];
let size = 0;
body: (async () => {
let bodyStream = res;
let onError;
if (res.headers['content-encoding'] === 'br') {
bodyStream = createBrotliDecompress();
onError = function onError(error) {
bodyStream.close();
dispose();
reject(error);
r(error);
};
res.on('error', onError);
res.pipe(bodyStream);
} else if (res.headers['content-encoding'] === 'gzip' ||
res.headers['content-encoding'] === 'deflate') {
bodyStream = createUnzip();
onError = function onError(error) {
bodyStream.close();
dispose();
reject(error);
r(error);
};
res.on('error', onError);
res.pipe(bodyStream);
} else {
onError = function onError(error) {
dispose();
reject(error);
r(error);
};
bodyStream = compose(res, createBrotliDecompress());
} else if (
res.headers['content-encoding'] === 'gzip' ||
res.headers['content-encoding'] === 'deflate'
) {
bodyStream = compose(res, createUnzip());
}
bodyStream.on('error', onError);
bodyStream.on('data', (d) => {
ArrayPrototypePush(buffers, d);
size += d.length;
});
bodyStream.on('end', () => {
const body = entry.body = /** @type {Buffer} */(
BufferConcat(buffers, size)
);
f(body);
});
}),
const buffers = await bodyStream.toArray();
const body = BufferConcat(buffers);
entry.body = body;
return body;
})(),
};
cacheForGET.set(parsed.href, entry);
fulfill(entry);
});
});
await entry.body;
return entry;
} finally {
req.destroy();
}
})();
cacheForGET.set(parsed.href, result);
return result;
}
Expand All @@ -226,8 +188,10 @@ allowList.addRange('127.0.0.1', '127.255.255.255');
*/
async function isLocalAddress(hostname) {
try {
if (StringPrototypeStartsWith(hostname, '[') &&
StringPrototypeEndsWith(hostname, ']')) {
if (
StringPrototypeStartsWith(hostname, '[') &&
StringPrototypeEndsWith(hostname, ']')
) {
hostname = StringPrototypeSlice(hostname, 1, -1);
}
const addr = await dnsLookup(hostname, { verbatim: true });
Expand Down Expand Up @@ -275,5 +239,5 @@ function fetchModule(parsed, { parentURL }) {
}

module.exports = {
fetchModule: fetchModule
fetchModule: fetchModule,
};
11 changes: 11 additions & 0 deletions test/es-module/test-http-imports.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ for (const { protocol, createServer } of [
const server = createServer(function(_req, res) {
const url = new URL(_req.url, host);
const redirect = url.searchParams.get('redirect');
if (url.pathname === '/not-found') {
res.writeHead(404);
res.end();
return;
}
if (redirect) {
const { status, location } = JSON.parse(redirect);
res.writeHead(status, {
Expand Down Expand Up @@ -165,6 +170,12 @@ for (const { protocol, createServer } of [
import(unsupportedMIME.href),
{ code: 'ERR_UNKNOWN_MODULE_FORMAT' }
);
const notFound = new URL(url.href);
notFound.pathname = '/not-found';
await assert.rejects(
import(notFound.href),
{ code: 'ERR_MODULE_NOT_FOUND' },
);

server.close();
}
Expand Down