lib: add fetch · nodejs/node@6ec2253 · GitHub
source link: https://github.com/nodejs/node/commit/6ec225392675c92b102d3caad02ee3a157c9d1b7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
add fetch · nodejs/node@6ec2253 · GitHub
Fixes: #19393 PR-URL: #41749 Refs: nodejs/undici#1183 Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Geoffrey Booth <[email protected]> Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Darshan Sen <[email protected]> Reviewed-By: Mestery <[email protected]> Reviewed-By: Mohammed Keyvanzadeh <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]> Reviewed-By: Myles Borins <[email protected]>
@@ -338,5 +338,9 @@ module.exports = {
atob: 'readable',
performance: 'readable',
structuredClone: 'readable',
fetch: 'readable',
Headers: 'readable',
Request: 'readable',
Response: 'readable',
},
};
@@ -634,6 +634,31 @@ The externally maintained libraries used by Node.js are:
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
- undici, located at deps/undici, is licensed as follows:
"""
MIT License
Copyright (c) Matteo Collina and Undici contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
- OpenSSL, located at deps/openssl, is licensed as follows:
"""
Apache License
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Matteo Collina and Undici contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Large diffs are not rendered by default.
@@ -280,6 +280,14 @@ effort to report stack traces relative to the original source file.
Overriding `Error.prepareStackTrace` prevents `--enable-source-maps` from
modifying the stack trace.
### `--experimental-fetch`
<!-- YAML
added: REPLACEME
-->
Enable experimental support for the [Fetch API][].
### `--experimental-import-meta-resolve`
<!-- YAML
@@ -1559,6 +1567,7 @@ Node.js options that are allowed are:
* `--enable-fips`
* `--enable-source-maps`
* `--experimental-abortcontroller`
* `--experimental-fetch`
* `--experimental-import-meta-resolve`
* `--experimental-json-modules`
* `--experimental-loader`
@@ -1952,6 +1961,7 @@ $ node --max-old-space-size=1536 index.js
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
[CommonJS]: modules.md
[ECMAScript module loader]: esm.md#loaders
[Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
[Modules loaders]: packages.md#modules-loaders
[OSSL_PROVIDER-legacy]: https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
[REPL]: repl.md
@@ -333,6 +333,17 @@ A browser-compatible implementation of the `EventTarget` class. See
This variable may appear to be global but is not. See [`exports`][].
## `fetch`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental. Enable this API with the [`--experimental-fetch`][]
> CLI flag.
A browser-compatible implementation of the [`fetch()`][] function.
## `global`
<!-- YAML
@@ -348,6 +359,17 @@ within the browser `var something` will define a new global variable. In
Node.js this is different. The top-level scope is not the global scope;
`var something` inside a Node.js module will be local to that module.
## Class `Headers`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental. Enable this API with the [`--experimental-fetch`][]
> CLI flag.
A browser-compatible implementation of {Headers}.
## `MessageChannel`
<!-- YAML
@@ -442,6 +464,28 @@ DataHandler.prototype.load = async function load(key) {
This variable may appear to be global but is not. See [`require()`][].
## `Response`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental. Enable this API with the [`--experimental-fetch`][]
> CLI flag.
A browser-compatible implementation of {Response}.
## `Request`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental. Enable this API with the [`--experimental-fetch`][]
> CLI flag.
A browser-compatible implementation of {Request}.
## `setImmediate(callback[, ...args])`
<!-- YAML
@@ -546,6 +590,7 @@ The object that acts as the namespace for all W3C
[WebAssembly][webassembly-org] related functionality. See the
[Mozilla Developer Network][webassembly-mdn] for usage and compatibility.
[`--experimental-fetch`]: cli.md#--experimental-fetch
[`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
[`DOMException`]: https://developer.mozilla.org/en-US/docs/Web/API/DOMException
[`EventTarget` and `Event` API]: events.md#eventtarget-and-event-api
@@ -565,6 +610,7 @@ The object that acts as the namespace for all W3C
[`clearTimeout`]: timers.md#cleartimeouttimeout
[`console`]: console.md
[`exports`]: modules.md#exports
[`fetch()`]: https://developer.mozilla.org/en-US/docs/Web/API/fetch
[`module`]: modules.md#module
[`perf_hooks.performance`]: perf_hooks.md#perf_hooksperformance
[`process.nextTick()`]: process.md#processnexttickcallback-args
@@ -139,6 +139,9 @@ Requires Node.js to be built with
.It Fl -enable-source-maps
Enable Source Map V3 support for stack traces.
.
.It Fl -experimental-fetch
Enable experimental support for the Fetch API.
.
.It Fl -experimental-import-meta-resolve
Enable experimental ES modules support for import.meta.resolve().
.
@@ -14,6 +14,11 @@ const {
getEmbedderOptions,
} = require('internal/options');
const { reconnectZeroFillToggle } = require('internal/buffer');
const {
defineOperation,
emitExperimentalWarning,
exposeInterface,
} = require('internal/util');
const { Buffer } = require('buffer');
const { ERR_MANIFEST_ASSERT_INTEGRITY } = require('internal/errors').codes;
@@ -30,6 +35,7 @@ function prepareMainThreadExecution(expandArgv1 = false) {
setupPerfHooks();
setupInspectorHooks();
setupWarningHandler();
setupFetch();
// Resolve the coverage directory to an absolute path, and
// overwrite process.env so that the original path gets passed
@@ -139,6 +145,21 @@ function setupWarningHandler() {
}
}
// https://fetch.spec.whatwg.org/
function setupFetch() {
if (!getOptionValue('--experimental-fetch')) {
return;
}
emitExperimentalWarning('Fetch');
const undici = require('internal/deps/undici/undici');
defineOperation(globalThis, 'fetch', undici.fetch);
exposeInterface(globalThis, 'Headers', undici.Headers);
exposeInterface(globalThis, 'Request', undici.Request);
exposeInterface(globalThis, 'Response', undici.Response);
}
// Setup User-facing NODE_V8_COVERAGE environment variable that writes
// ScriptCoverage to a specified file.
function setupCoverageHooks(dir) {
@@ -479,6 +500,7 @@ module.exports = {
patchProcessObject,
setupCoverageHooks,
setupWarningHandler,
setupFetch,
setupDebugEnv,
setupPerfHooks,
prepareMainThreadExecution,
@@ -17,6 +17,7 @@ const {
setupCoverageHooks,
setupInspectorHooks,
setupWarningHandler,
setupFetch,
setupDebugEnv,
setupPerfHooks,
initializeDeprecations,
@@ -67,6 +68,7 @@ setupInspectorHooks();
setupDebugEnv();
setupWarningHandler();
setupFetch();
initializeSourceMapsHandlers();
// Since worker threads cannot switch cwd, we do not need to
@@ -51,6 +51,7 @@
'deps/acorn/acorn-walk/dist/walk.js',
'deps/cjs-module-lexer/lexer.js',
'deps/cjs-module-lexer/dist/lexer.js',
'deps/undici/undici.js',
],
'node_mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)node_mksnapshot<(EXECUTABLE_SUFFIX)',
'mkcodecache_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mkcodecache<(EXECUTABLE_SUFFIX)',
@@ -315,6 +315,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
kAllowedInEnvironment);
AddOption("--experimental-abortcontroller", "",
NoOp{}, kAllowedInEnvironment);
AddOption("--experimental-fetch",
"experimental Fetch API",
&EnvironmentOptions::experimental_fetch,
kAllowedInEnvironment);
AddOption("--experimental-json-modules", "", NoOp{}, kAllowedInEnvironment);
AddOption("--experimental-loader",
"use the specified module as a custom loader",
@@ -107,6 +107,7 @@ class EnvironmentOptions : public Options {
std::vector<std::string> conditions;
std::string dns_result_order;
bool enable_source_maps = false;
bool experimental_fetch = false;
std::string experimental_specifier_resolution;
bool experimental_wasm_modules = false;
bool experimental_import_meta_resolve = false;
@@ -68,12 +68,12 @@ if (process.argv.length === 2 &&
!process.env.NODE_SKIP_FLAG_CHECK &&
isMainThread &&
hasCrypto &&
require.main &&
require('cluster').isPrimary) {
require('cluster').isPrimary &&
fs.existsSync(process.argv[1])) {
// The copyright notice is relatively big and the flags could come afterwards.
const bytesToRead = 1500;
const buffer = Buffer.allocUnsafe(bytesToRead);
const fd = fs.openSync(require.main.filename, 'r');
const fd = fs.openSync(process.argv[1], 'r');
const bytesRead = fs.readSync(fd, buffer, 0, bytesToRead);
fs.closeSync(fd);
const source = buffer.toString('utf8', 0, bytesRead);
@@ -300,6 +300,15 @@ if (global.structuredClone) {
knownGlobals.push(global.structuredClone);
}
if (global.fetch) {
knownGlobals.push(
global.fetch,
global.Request,
global.Response,
global.Headers,
);
}
function allowGlobals(...allowlist) {
knownGlobals = knownGlobals.concat(allowlist);
}
@@ -0,0 +1,32 @@
// Flags: --experimental-fetch --no-warnings
import '../common/index.mjs';
import assert from 'assert';
import events from 'events';
import http from 'http';
assert.strictEqual(typeof globalThis.fetch, 'function');
assert.strictEqual(typeof globalThis.Headers, 'function');
assert.strictEqual(typeof globalThis.Request, 'function');
assert.strictEqual(typeof globalThis.Response, 'function');
const server = http.createServer((req, res) => {
// TODO: Remove this once keep-alive behavior can be disabled from the client
// side.
res.setHeader('Keep-Alive', 'timeout=0, max=0');
res.end('Hello world');
});
server.listen(0);
await events.once(server, 'listening');
const port = server.address().port;
const response = await fetch(`http://localhost:${port}`);
assert(response instanceof Response);
assert.strictEqual(response.status, 200);
assert.strictEqual(response.statusText, 'OK');
const body = await response.text();
assert.strictEqual(body, 'Hello world');
server.close();
@@ -270,6 +270,10 @@ const customTypesMap = {
'webstreams.md#class-textencoderstream',
'TextDecoderStream':
'webstreams.md#class-textdecoderstream',
'Headers': 'https://developer.mozilla.org/en-US/docs/Web/API/Headers',
'Response': 'https://developer.mozilla.org/en-US/docs/Web/API/Response',
'Request': 'https://developer.mozilla.org/en-US/docs/Web/API/Request',
};
const arrayPart = /(?:\[])+$/;
@@ -63,6 +63,8 @@ licenseText="$(cat deps/llhttp/LICENSE-MIT)"
addlicense "llhttp" "deps/llhttp" "$licenseText"
licenseText="$(cat "${rootdir}"/deps/corepack/LICENSE.md)"
addlicense "corepack" "deps/corepack" "$licenseText"
licenseText="$(cat "${rootdir}"/deps/undici/LICENSE)"
addlicense "undici" "deps/undici" "$licenseText"
licenseText="$(cat "${rootdir}"/deps/openssl/openssl/LICENSE.txt)"
addlicense "OpenSSL" "deps/openssl" "$licenseText"
licenseText="$(curl -sL https://raw.githubusercontent.com/bestiejs/punycode.js/HEAD/LICENSE-MIT.txt)"
0 comments
on commit 6ec2253
Please sign in to comment.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK