Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b73943e

Browse filesBrowse files
aduh95BethGriggs
authored andcommitted
workers: add support for data: URLs
PR-URL: #34584 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Jan Krems <jan.krems@gmail.com>
1 parent 90abdd3 commit b73943e
Copy full SHA for b73943e

File tree

Expand file treeCollapse file tree

7 files changed

+60
-7
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

7 files changed

+60
-7
lines changed
Open diff view settings
Collapse file

‎doc/api/worker_threads.md‎

Copy file name to clipboardExpand all lines: doc/api/worker_threads.md
+12-1Lines changed: 12 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,13 @@ if (isMainThread) {
621621
<!-- YAML
622622
added: v10.5.0
623623
changes:
624+
- version: REPLACEME
625+
pr-url: https://github.com/nodejs/node/pull/34584
626+
description: The `filename` parameter can be a WHATWG `URL` object using
627+
`data:` protocol.
628+
- version: REPLACEME
629+
pr-url: https://github.com/nodejs/node/pull/34394
630+
description: The `trackUnmanagedFds` option was set to `true` by default.
624631
- version:
625632
- v14.6.0
626633
pr-url: https://github.com/nodejs/node/pull/34303
@@ -647,7 +654,9 @@ changes:
647654
* `filename` {string|URL} The path to the Worker’s main script or module. Must
648655
be either an absolute path or a relative path (i.e. relative to the
649656
current working directory) starting with `./` or `../`, or a WHATWG `URL`
650-
object using `file:` protocol.
657+
object using `file:` or `data:` protocol.
658+
When using a [`data:` URL][], the data is interpreted based on MIME type using
659+
the [ECMAScript module loader][].
651660
If `options.eval` is `true`, this is a string containing JavaScript code
652661
rather than a path.
653662
* `options` {Object}
@@ -893,6 +902,7 @@ active handle in the event system. If the worker is already `unref()`ed calling
893902
[`AsyncResource`]: async_hooks.html#async_hooks_class_asyncresource
894903
[`Buffer`]: buffer.html
895904
[`Buffer.allocUnsafe()`]: buffer.html#buffer_static_method_buffer_allocunsafe_size
905+
[ECMAScript module loader]: esm.html#esm_data_imports
896906
[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: errors.html#errors_err_missing_message_port_in_transfer_list
897907
[`ERR_WORKER_NOT_RUNNING`]: errors.html#ERR_WORKER_NOT_RUNNING
898908
[`EventEmitter`]: events.html
@@ -944,3 +954,4 @@ active handle in the event system. If the worker is already `unref()`ed calling
944954
[child processes]: child_process.html
945955
[contextified]: vm.html#vm_what_does_it_mean_to_contextify_an_object
946956
[v8.serdes]: v8.html#v8_serialization_api
957+
[`data:` URL]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
Collapse file

‎lib/internal/errors.js‎

Copy file name to clipboardExpand all lines: lib/internal/errors.js
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,9 @@ E('ERR_WORKER_PATH', (filename) =>
14511451
(filename.startsWith('file://') ?
14521452
' Wrap file:// URLs with `new URL`.' : ''
14531453
) +
1454+
(filename.startsWith('data:text/javascript') ?
1455+
' Wrap data: URLs with `new URL`.' : ''
1456+
) +
14541457
` Received "${filename}"`,
14551458
TypeError);
14561459
E('ERR_WORKER_UNSERIALIZABLE_ERROR',
Collapse file

‎lib/internal/main/worker_thread.js‎

Copy file name to clipboardExpand all lines: lib/internal/main/worker_thread.js
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ port.on('message', (message) => {
149149
debug(`[${threadId}] starts worker script ${filename} ` +
150150
`(eval = ${eval}) at cwd = ${process.cwd()}`);
151151
port.postMessage({ type: UP_AND_RUNNING });
152-
if (doEval) {
152+
if (doEval === 'classic') {
153153
const { evalScript } = require('internal/process/execution');
154154
const name = '[worker eval]';
155155
// This is necessary for CJS module compilation.
@@ -161,6 +161,11 @@ port.on('message', (message) => {
161161
});
162162
process.argv.splice(1, 0, name);
163163
evalScript(name, filename);
164+
} else if (doEval === 'module') {
165+
const { evalModule } = require('internal/process/execution');
166+
evalModule(filename).catch((e) => {
167+
workerOnGlobalUncaughtException(e, true);
168+
});
164169
} else {
165170
// script filename
166171
// runMain here might be monkey-patched by users in --require.
Collapse file

‎lib/internal/process/execution.js‎

Copy file name to clipboardExpand all lines: lib/internal/process/execution.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ function evalModule(source, print) {
4545
const { log } = require('internal/console/global');
4646
const { loadESM } = require('internal/process/esm_loader');
4747
const { handleMainPromise } = require('internal/modules/run_main');
48-
handleMainPromise(loadESM(async (loader) => {
48+
return handleMainPromise(loadESM(async (loader) => {
4949
const { result } = await loader.eval(source);
5050
if (print) {
5151
log(result);
Collapse file

‎lib/internal/worker.js‎

Copy file name to clipboardExpand all lines: lib/internal/worker.js
+9-2Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
const {
66
ArrayIsArray,
7+
JSONStringify,
78
MathMax,
89
ObjectCreate,
910
ObjectEntries,
@@ -100,7 +101,7 @@ class Worker extends EventEmitter {
100101
argv = options.argv.map(String);
101102
}
102103

103-
let url;
104+
let url, doEval;
104105
if (options.eval) {
105106
if (typeof filename !== 'string') {
106107
throw new ERR_INVALID_ARG_VALUE(
@@ -110,7 +111,13 @@ class Worker extends EventEmitter {
110111
);
111112
}
112113
url = null;
114+
doEval = 'classic';
115+
} else if (isURLInstance(filename) && filename.protocol === 'data:') {
116+
url = null;
117+
doEval = 'module';
118+
filename = `import ${JSONStringify(`${filename}`)}`;
113119
} else {
120+
doEval = false;
114121
if (isURLInstance(filename)) {
115122
url = filename;
116123
filename = fileURLToPath(filename);
@@ -201,7 +208,7 @@ class Worker extends EventEmitter {
201208
argv,
202209
type: messageTypes.LOAD_SCRIPT,
203210
filename,
204-
doEval: !!options.eval,
211+
doEval,
205212
cwdCounter: cwdCounter || workerIo.sharedCwdCounter,
206213
workerData: options.workerData,
207214
publicPort: port2,
Collapse file
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const { Worker } = require('worker_threads');
5+
const assert = require('assert');
6+
7+
new Worker(new URL('data:text/javascript,'))
8+
.on('error', common.mustNotCall(() => {}));
9+
new Worker(new URL('data:text/javascript,export{}'))
10+
.on('error', common.mustNotCall(() => {}));
11+
12+
new Worker(new URL('data:text/plain,'))
13+
.on('error', common.mustCall(() => {}));
14+
new Worker(new URL('data:text/javascript,module.exports={}'))
15+
.on('error', common.mustCall(() => {}));
16+
17+
new Worker(new URL('data:text/javascript,await Promise.resolve()'))
18+
.on('error', common.mustNotCall(() => {}));
19+
new Worker(new URL('data:text/javascript,await Promise.reject()'))
20+
.on('error', common.mustCall(() => {}));
21+
new Worker(new URL('data:text/javascript,await new Promise(()=>{})'))
22+
.on(
23+
'exit',
24+
common.mustCall((exitCode) => { assert.strictEqual(exitCode, 13); })
25+
);
Collapse file

‎test/parallel/test-worker-unsupported-path.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-worker-unsupported-path.js
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ const { Worker } = require('worker_threads');
3333
() => { new Worker('file:///file_url'); },
3434
/Wrap file:\/\/ URLs with `new URL`/
3535
);
36+
assert.throws(
37+
() => { new Worker('data:text/javascript,'); },
38+
/Wrap data: URLs with `new URL`/
39+
);
3640
assert.throws(
3741
() => { new Worker('relative_no_dot'); },
3842
// eslint-disable-next-line node-core/no-unescaped-regexp-dot
@@ -47,6 +51,4 @@ const { Worker } = require('worker_threads');
4751
};
4852
assert.throws(() => { new Worker(new URL('https://www.url.com')); },
4953
expectedErr);
50-
assert.throws(() => { new Worker(new URL('data:application/javascript,')); },
51-
expectedErr);
5254
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.