visaljs 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -4
- package/THIRD_PARTY_LICENSES +1216 -0
- package/cli.js +4461 -321
- package/node/include/js_node.h +57 -1
- package/node/include/js_uv.h +8 -1
- package/node/prelude/_http_agent.js +5 -0
- package/node/prelude/_http_server.js +7 -0
- package/node/prelude/_stream_duplex.js +4 -0
- package/node/prelude/_stream_passthrough.js +4 -0
- package/node/prelude/_stream_readable.js +4 -0
- package/node/prelude/_stream_transform.js +4 -0
- package/node/prelude/_stream_writable.js +4 -0
- package/node/prelude/assert.js +1334 -0
- package/node/prelude/assert_strict.js +12 -0
- package/node/prelude/async_hooks.js +1 -1
- package/node/prelude/buffer.js +43 -3
- package/node/prelude/child_process.js +1098 -0
- package/node/prelude/cluster.js +52 -0
- package/node/prelude/console.js +328 -0
- package/node/prelude/constants.js +10 -0
- package/node/prelude/crypto.js +1 -1
- package/node/prelude/diagnostics_channel.js +1 -1
- package/node/prelude/dns.js +8 -2
- package/node/prelude/domain.js +115 -0
- package/node/prelude/events.js +148 -16
- package/node/prelude/fs.js +1138 -151
- package/node/prelude/fs_promises.js +117 -11
- package/node/prelude/http.js +784 -301
- package/node/prelude/http2.js +1 -1
- package/node/prelude/https.js +159 -0
- package/node/prelude/inspector.js +27 -0
- package/node/prelude/inspector_promises.js +4 -0
- package/node/prelude/internal/async_context.js +1 -1
- package/node/prelude/internal/buffer_transcode.js +44 -0
- package/node/prelude/internal/comparisons.js +916 -0
- package/node/prelude/internal/compression_streams.js +153 -0
- package/node/prelude/internal/crypto/asym.js +27 -14
- package/node/prelude/internal/crypto/cipher.js +16 -5
- package/node/prelude/internal/crypto/diffiehellman.js +3 -2
- package/node/prelude/internal/crypto/hash.js +2 -1
- package/node/prelude/internal/crypto/kdf.js +14 -9
- package/node/prelude/internal/crypto/keys.js +63 -50
- package/node/prelude/internal/crypto/random.js +2 -1
- package/node/prelude/internal/crypto/util.js +4 -4
- package/node/prelude/internal/dotenv.js +98 -0
- package/node/prelude/internal/errors.js +21 -5
- package/node/prelude/internal/events_extras.js +113 -0
- package/node/prelude/internal/events_on.js +100 -0
- package/node/prelude/internal/features.js +72 -0
- package/node/prelude/internal/fetch.js +364 -0
- package/node/prelude/internal/form_data.js +376 -0
- package/node/prelude/internal/fs_bigint_stats.js +41 -0
- package/node/prelude/internal/fs_blob.js +19 -0
- package/node/prelude/internal/fs_cp.js +709 -0
- package/node/prelude/internal/fs_dir.js +166 -0
- package/node/prelude/internal/fs_filehandle.js +287 -0
- package/node/prelude/internal/fs_glob.js +296 -0
- package/node/prelude/internal/fs_statfs.js +42 -0
- package/node/prelude/internal/fs_stats.js +89 -0
- package/node/prelude/internal/fs_streams.js +541 -0
- package/node/prelude/internal/fs_utils.js +286 -0
- package/node/prelude/internal/fs_watch.js +580 -0
- package/node/prelude/internal/http_agent.js +114 -2
- package/node/prelude/internal/http_symbols.js +3 -0
- package/node/prelude/internal/mime.js +249 -0
- package/node/prelude/internal/net.js +1 -0
- package/node/prelude/internal/net_bound.js +123 -0
- package/node/prelude/internal/net_onread.js +73 -0
- package/node/prelude/internal/net_tos.js +54 -0
- package/node/prelude/internal/parse_args.js +288 -0
- package/node/prelude/internal/perf_histogram.js +435 -0
- package/node/prelude/internal/perf_observe.js +125 -0
- package/node/prelude/internal/performance_global.js +19 -0
- package/node/prelude/internal/process_events.js +49 -1
- package/node/prelude/internal/process_memory.js +14 -0
- package/node/prelude/internal/process_more.js +414 -0
- package/node/prelude/internal/process_signals.js +2 -1
- package/node/prelude/internal/process_stdin.js +52 -0
- package/node/prelude/internal/process_stdio.js +36 -0
- package/node/prelude/internal/querystring.js +0 -0
- package/node/prelude/internal/readline.js +338 -0
- package/node/prelude/internal/socketaddress.js +8 -4
- package/node/prelude/internal/source_map.js +122 -0
- package/node/prelude/internal/stream_compose.js +74 -0
- package/node/prelude/internal/stream_from.js +6 -0
- package/node/prelude/internal/stream_operators.js +23 -0
- package/node/prelude/internal/stream_pipeline.js +7 -0
- package/node/prelude/internal/stream_transform.js +10 -0
- package/node/prelude/internal/stream_web_adapters.js +143 -0
- package/node/prelude/internal/streams/add_abort_signal.js +58 -0
- package/node/prelude/internal/streams/compose.js +244 -0
- package/node/prelude/internal/streams/destroy.js +358 -0
- package/node/prelude/internal/streams/duplex.js +199 -0
- package/node/prelude/internal/streams/duplexify.js +378 -0
- package/node/prelude/internal/streams/end_of_stream.js +387 -0
- package/node/prelude/internal/streams/errors.js +216 -0
- package/node/prelude/internal/streams/from.js +211 -0
- package/node/prelude/internal/streams/legacy.js +120 -0
- package/node/prelude/internal/streams/operators.js +375 -0
- package/node/prelude/internal/streams/passthrough.js +45 -0
- package/node/prelude/internal/streams/pipeline.js +468 -0
- package/node/prelude/internal/streams/readable.js +1835 -0
- package/node/prelude/internal/streams/state.js +48 -0
- package/node/prelude/internal/streams/transform.js +203 -0
- package/node/prelude/internal/streams/utils.js +355 -0
- package/node/prelude/internal/streams/validators.js +108 -0
- package/node/prelude/internal/streams/writable.js +1160 -0
- package/node/prelude/internal/structured_clone.js +238 -0
- package/node/prelude/internal/system_errors.js +37 -0
- package/node/prelude/internal/test_runner/mock.js +431 -0
- package/node/prelude/internal/test_runner/reporters.js +404 -0
- package/node/prelude/internal/test_runner/test.js +1571 -0
- package/node/prelude/internal/timers.js +38 -7
- package/node/prelude/internal/timers_global.js +1 -1
- package/node/prelude/internal/tls/common.js +8 -2
- package/node/prelude/internal/tls/wrap.js +5 -16
- package/node/prelude/internal/tls/x509.js +1 -1
- package/node/prelude/internal/tty_read_stream.js +39 -0
- package/node/prelude/internal/tty_streams.js +3 -0
- package/node/prelude/internal/util_debuglog.js +68 -0
- package/node/prelude/internal/util_diff.js +63 -0
- package/node/prelude/internal/util_more.js +111 -0
- package/node/prelude/internal/util_styles.js +76 -0
- package/node/prelude/internal/zlib_engines.js +1 -1
- package/node/prelude/module.js +219 -8
- package/node/prelude/net.js +197 -49
- package/node/prelude/os.js +88 -11
- package/node/prelude/path.js +11 -7
- package/node/prelude/path_posix.js +1 -1
- package/node/prelude/path_win32.js +1 -1
- package/node/prelude/perf_hooks.js +151 -0
- package/node/prelude/process.js +36 -1
- package/node/prelude/punycode.js +188 -0
- package/node/prelude/querystring.js +1 -1
- package/node/prelude/readline.js +8 -0
- package/node/prelude/readline_promises.js +88 -0
- package/node/prelude/repl.js +38 -0
- package/node/prelude/sea.js +23 -0
- package/node/prelude/stream.js +70 -1332
- package/node/prelude/stream_consumers.js +34 -0
- package/node/prelude/stream_promises.js +1 -1
- package/node/prelude/stream_web.js +15 -2
- package/node/prelude/string_decoder.js +1 -1
- package/node/prelude/sys.js +7 -0
- package/node/prelude/test.js +56 -0
- package/node/prelude/test_reporters.js +269 -0
- package/node/prelude/timers.js +7 -84
- package/node/prelude/timers_promises.js +1 -1
- package/node/prelude/tls.js +2 -1
- package/node/prelude/trace_events.js +52 -0
- package/node/prelude/tty.js +10 -4
- package/node/prelude/url.js +88 -27
- package/node/prelude/util.js +121 -5
- package/node/prelude/util_types.js +4 -3
- package/node/prelude/v8.js +814 -0
- package/node/prelude/vm.js +86 -0
- package/node/prelude/wasi.js +10 -0
- package/node/prelude/worker_threads.js +56 -0
- package/node/prelude/zlib.js +58 -25
- package/node/src/host_brotli.c +59 -11
- package/node/src/host_fs.c +342 -11
- package/node/src/host_fswatch.c +170 -0
- package/node/src/host_http.c +292 -39
- package/node/src/host_loop.c +25 -2
- package/node/src/host_net.c +130 -16
- package/node/src/host_os.c +55 -1
- package/node/src/host_proc.c +291 -0
- package/node/src/host_process.c +488 -0
- package/node/src/host_sys.c +64 -2
- package/node/src/host_zlib.c +27 -7
- package/node/src/host_zstd.c +41 -6
- package/node/third_party/hdrhistogram/LICENSE +42 -0
- package/node/third_party/hdrhistogram/README.md +5 -0
- package/node/third_party/libuv/LICENSE +0 -0
- package/node/third_party/libuv/LICENSE-extra +36 -0
- package/node/third_party/libuv/include/uv/aix.h +0 -0
- package/node/third_party/libuv/include/uv/bsd.h +0 -0
- package/node/third_party/libuv/include/uv/darwin.h +0 -0
- package/node/third_party/libuv/include/uv/errno.h +0 -0
- package/node/third_party/libuv/include/uv/linux.h +0 -0
- package/node/third_party/libuv/include/uv/os390.h +0 -0
- package/node/third_party/libuv/include/uv/posix.h +0 -0
- package/node/third_party/libuv/include/uv/sunos.h +0 -0
- package/node/third_party/libuv/include/uv/threadpool.h +0 -0
- package/node/third_party/libuv/include/uv/tree.h +0 -0
- package/node/third_party/libuv/include/uv/unix.h +0 -0
- package/node/third_party/libuv/include/uv/version.h +0 -0
- package/node/third_party/libuv/include/uv/win.h +0 -0
- package/node/third_party/libuv/include/uv.h +0 -0
- package/node/third_party/libuv/src/fs-poll.c +0 -0
- package/node/third_party/libuv/src/heap-inl.h +0 -0
- package/node/third_party/libuv/src/idna.c +0 -0
- package/node/third_party/libuv/src/idna.h +0 -0
- package/node/third_party/libuv/src/inet.c +0 -0
- package/node/third_party/libuv/src/queue.h +0 -0
- package/node/third_party/libuv/src/random.c +0 -0
- package/node/third_party/libuv/src/strscpy.c +0 -0
- package/node/third_party/libuv/src/strscpy.h +0 -0
- package/node/third_party/libuv/src/strtok.c +0 -0
- package/node/third_party/libuv/src/strtok.h +0 -0
- package/node/third_party/libuv/src/thread-common.c +0 -0
- package/node/third_party/libuv/src/threadpool.c +0 -0
- package/node/third_party/libuv/src/timer.c +0 -0
- package/node/third_party/libuv/src/unix/async.c +0 -0
- package/node/third_party/libuv/src/unix/bsd-ifaddrs.c +0 -0
- package/node/third_party/libuv/src/unix/core.c +0 -0
- package/node/third_party/libuv/src/unix/darwin-proctitle.c +0 -0
- package/node/third_party/libuv/src/unix/darwin-stub.h +0 -0
- package/node/third_party/libuv/src/unix/darwin-syscalls.h +0 -0
- package/node/third_party/libuv/src/unix/darwin.c +0 -0
- package/node/third_party/libuv/src/unix/dl.c +0 -0
- package/node/third_party/libuv/src/unix/fs.c +0 -0
- package/node/third_party/libuv/src/unix/fsevents.c +0 -0
- package/node/third_party/libuv/src/unix/getaddrinfo.c +0 -0
- package/node/third_party/libuv/src/unix/getnameinfo.c +0 -0
- package/node/third_party/libuv/src/unix/internal.h +0 -0
- package/node/third_party/libuv/src/unix/kqueue.c +0 -0
- package/node/third_party/libuv/src/unix/linux.c +0 -0
- package/node/third_party/libuv/src/unix/loop-watcher.c +0 -0
- package/node/third_party/libuv/src/unix/loop.c +0 -0
- package/node/third_party/libuv/src/unix/pipe.c +0 -0
- package/node/third_party/libuv/src/unix/poll.c +0 -0
- package/node/third_party/libuv/src/unix/process.c +0 -0
- package/node/third_party/libuv/src/unix/procfs-exepath.c +0 -0
- package/node/third_party/libuv/src/unix/proctitle.c +0 -0
- package/node/third_party/libuv/src/unix/random-devurandom.c +0 -0
- package/node/third_party/libuv/src/unix/random-getentropy.c +0 -0
- package/node/third_party/libuv/src/unix/random-getrandom.c +0 -0
- package/node/third_party/libuv/src/unix/random-sysctl-linux.c +0 -0
- package/node/third_party/libuv/src/unix/signal.c +0 -0
- package/node/third_party/libuv/src/unix/stream.c +0 -0
- package/node/third_party/libuv/src/unix/tcp.c +0 -0
- package/node/third_party/libuv/src/unix/thread.c +0 -0
- package/node/third_party/libuv/src/unix/tty.c +0 -0
- package/node/third_party/libuv/src/unix/udp.c +0 -0
- package/node/third_party/libuv/src/uv-common.c +0 -0
- package/node/third_party/libuv/src/uv-common.h +0 -0
- package/node/third_party/libuv/src/uv-data-getter-setters.c +0 -0
- package/node/third_party/libuv/src/version.c +0 -0
- package/node/third_party/llhttp/LICENSE +0 -0
- package/node/third_party/llhttp/api.c +0 -0
- package/node/third_party/llhttp/http.c +0 -0
- package/node/third_party/llhttp/llhttp.c +0 -0
- package/node/third_party/llhttp/llhttp.h +0 -0
- package/node/third_party/nodejs/LICENSE +47 -0
- package/node/third_party/nodejs/README.md +5 -0
- package/node/third_party/parseargs/LICENSE +21 -0
- package/node/third_party/parseargs/README.md +5 -0
- package/node/third_party/punycode/LICENSE +20 -0
- package/node/third_party/punycode/README.md +5 -0
- package/node/third_party/zlib/LICENSE.chromium +27 -0
- package/package.json +1 -1
- package/prebuilt/darwin-arm64/boringssl-4a47438eaf7e73ba.a +0 -0
- package/prebuilt/darwin-arm64/brotli-7995bbdacc52e51c.a +0 -0
- package/prebuilt/darwin-arm64/uv-72ab666eae197cd8.a +0 -0
- package/prebuilt/darwin-arm64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/darwin-arm64/zstd-015315ac7c784c73.a +0 -0
- package/prebuilt/darwin-x64/boringssl-4a47438eaf7e73ba.a +0 -0
- package/prebuilt/darwin-x64/brotli-7995bbdacc52e51c.a +0 -0
- package/prebuilt/darwin-x64/uv-72ab666eae197cd8.a +0 -0
- package/prebuilt/darwin-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/darwin-x64/zstd-015315ac7c784c73.a +0 -0
- package/prebuilt/linux-arm64/boringssl-4a47438eaf7e73ba.a +0 -0
- package/prebuilt/linux-arm64/brotli-65481ff838ce9def.a +0 -0
- package/prebuilt/linux-arm64/uv-f1353f50ff983f3c.a +0 -0
- package/prebuilt/linux-arm64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/linux-arm64/zstd-015315ac7c784c73.a +0 -0
- package/prebuilt/linux-arm64-musl/boringssl-4a47438eaf7e73ba.a +0 -0
- package/prebuilt/linux-arm64-musl/brotli-65481ff838ce9def.a +0 -0
- package/prebuilt/linux-arm64-musl/uv-f1353f50ff983f3c.a +0 -0
- package/prebuilt/linux-arm64-musl/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/linux-arm64-musl/zstd-015315ac7c784c73.a +0 -0
- package/prebuilt/linux-x64/boringssl-4a47438eaf7e73ba.a +0 -0
- package/prebuilt/linux-x64/brotli-65481ff838ce9def.a +0 -0
- package/prebuilt/linux-x64/uv-f1353f50ff983f3c.a +0 -0
- package/prebuilt/linux-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/linux-x64/zstd-015315ac7c784c73.a +0 -0
- package/prebuilt/linux-x64-musl/boringssl-4a47438eaf7e73ba.a +0 -0
- package/prebuilt/linux-x64-musl/brotli-65481ff838ce9def.a +0 -0
- package/prebuilt/linux-x64-musl/uv-f1353f50ff983f3c.a +0 -0
- package/prebuilt/linux-x64-musl/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/linux-x64-musl/zstd-015315ac7c784c73.a +0 -0
- package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
- package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
- package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
- package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
- package/runtime/include/js_atoms.gen.h +0 -0
- package/runtime/include/js_atoms.h +5 -1
- package/runtime/include/js_bigint.h +1 -1
- package/runtime/include/js_buffer.h +4 -4
- package/runtime/include/js_builtins.h +41 -3
- package/runtime/include/js_console.h +9 -4
- package/runtime/include/js_convert.h +1 -1
- package/runtime/include/js_core.def +5 -4
- package/runtime/include/js_crypto.h +1 -1
- package/runtime/include/js_error.h +1 -1
- package/runtime/include/js_exception.h +21 -1
- package/runtime/include/js_function.h +33 -9
- package/runtime/include/js_gc.h +172 -30
- package/runtime/include/js_generator.h +2 -2
- package/runtime/include/js_host.h +19 -1
- package/runtime/include/js_jobs.h +5 -5
- package/runtime/include/js_module.h +1 -1
- package/runtime/include/js_object.h +142 -15
- package/runtime/include/js_ops.h +107 -5
- package/runtime/include/js_promise.h +3 -3
- package/runtime/include/js_regexp.h +1 -1
- package/runtime/include/js_runtime.h +0 -0
- package/runtime/include/js_symbol.h +1 -1
- package/runtime/include/js_web.h +5 -1
- package/runtime/include/jscell.h +22 -15
- package/runtime/include/jscontext.h +82 -39
- package/runtime/include/jsnum.h +1 -1
- package/runtime/include/jsstring.h +19 -6
- package/runtime/include/jsvalue.h +7 -3
- package/runtime/src/arguments.c +2 -2
- package/runtime/src/array.c +4 -1
- package/runtime/src/arraybuffer.c +19 -7
- package/runtime/src/async_iter.c +4 -3
- package/runtime/src/atoms.c +38 -4
- package/runtime/src/base64.c +2 -2
- package/runtime/src/bigint.c +1 -1
- package/runtime/src/blob.c +22 -9
- package/runtime/src/boringssl_support.cc +1 -1
- package/runtime/src/buffer.c +299 -91
- package/runtime/src/builtin_table.c +1 -1
- package/runtime/src/builtins.c +30 -4
- package/runtime/src/builtins_util.h +0 -0
- package/runtime/src/collections.c +18 -3
- package/runtime/src/components.c +1 -1
- package/runtime/src/console.c +14 -7
- package/runtime/src/convert.c +0 -0
- package/runtime/src/core_all.c +1 -1
- package/runtime/src/crypto.c +1 -1
- package/runtime/src/crypto_asym.c +1 -1
- package/runtime/src/crypto_bn.c +1 -1
- package/runtime/src/crypto_cipher.c +10 -3
- package/runtime/src/crypto_hash.c +1 -1
- package/runtime/src/crypto_host.c +1 -1
- package/runtime/src/crypto_internal.h +1 -1
- package/runtime/src/crypto_kdf.c +1 -1
- package/runtime/src/crypto_key.c +14 -1
- package/runtime/src/crypto_pkey.c +1 -1
- package/runtime/src/crypto_subtle.c +142 -58
- package/runtime/src/crypto_tls.c +1 -1
- package/runtime/src/date.c +5 -2
- package/runtime/src/domexception.c +2 -2
- package/runtime/src/elements.c +56 -17
- package/runtime/src/elements.h +7 -2
- package/runtime/src/encoding.c +1 -1
- package/runtime/src/error.c +4 -4
- package/runtime/src/events.c +42 -14
- package/runtime/src/exception.c +1 -1
- package/runtime/src/fetch.c +241 -17
- package/runtime/src/function.c +31 -19
- package/runtime/src/gc.c +1720 -211
- package/runtime/src/gc_visit.h +87 -0
- package/runtime/src/generator.c +5 -3
- package/runtime/src/global.c +14 -6
- package/runtime/src/headers.c +10 -10
- package/runtime/src/inspect.c +76 -17
- package/runtime/src/internal.h +9 -6
- package/runtime/src/iterate.c +94 -2
- package/runtime/src/iterator.c +1 -1
- package/runtime/src/jobs.c +11 -5
- package/runtime/src/jsnum.c +2 -2
- package/runtime/src/json.c +1 -1
- package/runtime/src/math.c +9 -1
- package/runtime/src/module.c +3 -3
- package/runtime/src/number.c +0 -0
- package/runtime/src/object.c +107 -74
- package/runtime/src/ops.c +21 -3
- package/runtime/src/os.c +192 -1
- package/runtime/src/os.h +33 -2
- package/runtime/src/process.c +73 -8
- package/runtime/src/promise.c +4 -4
- package/runtime/src/proxy.c +1 -1
- package/runtime/src/reflect.c +1 -1
- package/runtime/src/regexp.c +700 -11
- package/runtime/src/regexp_anchor.h +1 -1
- package/runtime/src/regexp_message.h +1 -1
- package/runtime/src/shape.c +78 -20
- package/runtime/src/shape.h +0 -0
- package/runtime/src/streams.c +22 -8
- package/runtime/src/streams.h +0 -0
- package/runtime/src/string.c +64 -25
- package/runtime/src/string_builtins.c +7 -7
- package/runtime/src/symbol.c +2 -7
- package/runtime/src/test_host.c +3 -3
- package/runtime/src/tls_roots.gen.h +102 -620
- package/runtime/src/typedarray.c +8 -3
- package/runtime/src/tznames.gen.h +2 -1
- package/runtime/src/uri.c +1 -1
- package/runtime/src/url.c +42 -39
- package/runtime/src/weak.c +110 -36
- package/runtime/src/web.c +21 -3
- package/runtime/src/wrapper.c +0 -0
- package/runtime/src/writable.c +7 -6
- package/runtime/third_party/ada-idna/LICENSE-MIT +0 -0
- package/runtime/third_party/ada-idna/README.md +7 -7
- package/runtime/third_party/ada-idna/convert.mjs +89 -27
- package/runtime/third_party/ada-idna/idna.c +30 -31
- package/runtime/third_party/ada-idna/idna.h +0 -0
- package/runtime/third_party/ada-idna/idna_tables.h +2272 -1952
- package/runtime/third_party/boringssl/third_party/fiat/LICENSE +15 -0
- package/runtime/third_party/mozilla-ca/LICENSE +373 -0
- package/runtime/third_party/mozilla-ca/README.md +9 -0
- package/runtime/third_party/nodejs/LICENSE +47 -0
- package/runtime/third_party/nodejs/README.md +7 -0
- package/runtime/third_party/quickjs-dtoa/LICENSE +0 -0
- package/runtime/third_party/quickjs-dtoa/README.md +1 -1
- package/runtime/third_party/quickjs-dtoa/dtoa.c +0 -0
- package/runtime/third_party/quickjs-dtoa/dtoa.h +0 -0
- package/runtime/third_party/quickjs-dtoa/dtoa_compat.h +0 -0
- package/runtime/third_party/quickjs-regexp/LICENSE +0 -0
- package/runtime/third_party/quickjs-regexp/README.md +2 -2
- package/runtime/third_party/quickjs-regexp/cutils.c +0 -0
- package/runtime/third_party/quickjs-regexp/cutils.h +0 -0
- package/runtime/third_party/quickjs-regexp/libregexp-opcode.h +0 -0
- package/runtime/third_party/quickjs-regexp/libregexp.c +0 -0
- package/runtime/third_party/quickjs-regexp/libregexp.h +0 -0
- package/runtime/third_party/quickjs-regexp/libunicode-table.h +0 -0
- package/runtime/third_party/quickjs-regexp/libunicode.c +0 -0
- package/runtime/third_party/quickjs-regexp/libunicode.h +0 -0
- package/runtime/third_party/unicode/LICENSE +39 -0
- package/runtime/third_party/unicode/README.md +9 -0
- package/runtime/third_party/v8-ieee754/LICENSE +0 -0
- package/runtime/third_party/v8-ieee754/LICENSE.fdlibm +10 -0
- package/runtime/third_party/v8-ieee754/README.md +3 -2
- package/runtime/third_party/v8-ieee754/convert.py +0 -0
- package/runtime/third_party/v8-ieee754/ieee754.c +0 -0
- package/runtime/third_party/v8-ieee754/ieee754.h +0 -0
- package/runtime/tools/regexp_compile.c +2 -2
package/node/src/host_http.c
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Host primitives for node:http
|
|
1
|
+
/* Host primitives for node:http: llhttp (Node's parser) on node:net's
|
|
2
2
|
* sockets, for a server's requests and a client's responses. As in Node, a connection is a
|
|
3
3
|
* net.Socket, but its bytes go to the parser in C, not through JS: host_net.c's hook hands them
|
|
4
4
|
* over. The prelude's http.js builds Node's objects from what the parser finds; C does the
|
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
* writes goes out in one write when it (and its microtasks) returns
|
|
23
23
|
* httpFlush(conn) sends the corked output now (before the socket is ended)
|
|
24
24
|
* httpDate() → the Date header's value
|
|
25
|
+
* A socket whose bytes aren't its handle's (a TLS socket's are decrypted in JS, a Duplex has no
|
|
26
|
+
* handle) is a fed connection, with a negative id: JS gives its parser the bytes, and its output
|
|
27
|
+
* goes to a JS writer (which the TLS socket encrypts).
|
|
28
|
+
* httpFedOpen(writer) → conn writer(bytes) gets what the connection's output flushes
|
|
29
|
+
* httpFeed(conn, bytes | null) → whether the parser took them (null: the end of the input)
|
|
30
|
+
* httpFedClose(conn) the connection is done with (its socket closed)
|
|
25
31
|
* The loop is host_loop.c's; the sockets are host_net.c's. */
|
|
26
32
|
#define _POSIX_C_SOURCE 200809L /* libuv's headers: pthread_rwlock_t, struct addrinfo */
|
|
27
33
|
#include <stdio.h>
|
|
@@ -44,11 +50,12 @@
|
|
|
44
50
|
static void flush_pending(void);
|
|
45
51
|
typedef struct Conn Conn;
|
|
46
52
|
static void flush_conn(Conn *c);
|
|
53
|
+
static size_t pending_bytes(Conn *c);
|
|
47
54
|
|
|
48
55
|
/* ---- Parsers and connections ------------------------------------------------------------- */
|
|
49
56
|
|
|
50
57
|
typedef struct Parsers {
|
|
51
|
-
JSValue on_request, on_body, on_complete, on_upgrade, on_error; /* roots */
|
|
58
|
+
JSValue on_request, on_body, on_complete, on_upgrade, on_error, on_drain; /* roots */
|
|
52
59
|
} Parsers;
|
|
53
60
|
|
|
54
61
|
typedef struct Buf {
|
|
@@ -64,9 +71,13 @@ struct Conn {
|
|
|
64
71
|
bool detached; /* upgraded, or a parse error: the parser doesn't read any more */
|
|
65
72
|
bool executing; /* llhttp is running on it: it can't be freed yet */
|
|
66
73
|
bool released; /* let go of while executing: freed when llhttp returns */
|
|
74
|
+
bool detach_after; /* detached when llhttp is done with the read (httpDetach's afterRead) */
|
|
67
75
|
bool upgrading; /* JS took the upgrade the head asked for */
|
|
68
76
|
bool active; /* a message is under way (or the connection is new): timeouts count */
|
|
69
77
|
bool head_done; /* its head is complete: what follows are its body and trailers */
|
|
78
|
+
bool in_message; /* a message has begun and isn't complete: the connection isn't idle */
|
|
79
|
+
llhttp_errno_t failed; /* the parse error it stopped at: more bytes report it again, as Node's */
|
|
80
|
+
bool need_drain; /* JS waits for its output to drain (a write over the high-water mark) */
|
|
70
81
|
bool overflow; /* its head is over max_header bytes */
|
|
71
82
|
uint64_t begin_ms; /* when the message began (the loop's time) */
|
|
72
83
|
size_t header_bytes, max_header;
|
|
@@ -77,10 +88,18 @@ struct Conn {
|
|
|
77
88
|
Buf out; /* written but not sent: corked, as Node corks a response */
|
|
78
89
|
};
|
|
79
90
|
|
|
91
|
+
/* A fed connection: its writer, and the parser it has now (a new one per kept-alive request). */
|
|
92
|
+
typedef struct Fed {
|
|
93
|
+
JSValue writer; /* a root */
|
|
94
|
+
Conn *conn;
|
|
95
|
+
} Fed;
|
|
96
|
+
|
|
80
97
|
static Parsers **parsers;
|
|
81
98
|
static size_t nparsers;
|
|
82
99
|
static Conn **conns; /* by net handle id */
|
|
83
100
|
static size_t nconns;
|
|
101
|
+
static Fed **feds; /* fed connections: id -(k + 1) is feds[k] */
|
|
102
|
+
static size_t nfeds;
|
|
84
103
|
static int *pending; /* ids of connections with corked output */
|
|
85
104
|
static size_t npending, pending_cap;
|
|
86
105
|
static llhttp_settings_t settings;
|
|
@@ -136,6 +155,7 @@ static int on_message_begin(llhttp_t *p) {
|
|
|
136
155
|
c->headers = js_new_array(ctx_(), 0);
|
|
137
156
|
c->active = true;
|
|
138
157
|
c->head_done = false;
|
|
158
|
+
c->in_message = true;
|
|
139
159
|
c->header_bytes = 0;
|
|
140
160
|
c->begin_ms = uv_now(js_uv_loop(ctx_()));
|
|
141
161
|
return 0;
|
|
@@ -206,21 +226,40 @@ static int on_message_complete(llhttp_t *p) {
|
|
|
206
226
|
if (c->detached) return -1; /* let go of by an earlier callback */
|
|
207
227
|
if (c->in_value || c->field.n) push_header(c); /* the last trailer */
|
|
208
228
|
c->active = false;
|
|
229
|
+
c->in_message = false;
|
|
209
230
|
JSValue args[2] = { js_int32(c->id), c->headers };
|
|
210
231
|
c->headers = JS_UNDEFINED;
|
|
211
232
|
return js_uv_call(c->parsers->on_complete, 2, args, NULL) ? 0 : -1;
|
|
212
233
|
}
|
|
213
234
|
|
|
214
|
-
static
|
|
235
|
+
static Fed *fed_of(int id) {
|
|
236
|
+
if (id >= 0) return NULL;
|
|
237
|
+
size_t k = (size_t)(-(id + 1));
|
|
238
|
+
return k < nfeds ? feds[k] : NULL;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
static Conn *conn_of(int id) {
|
|
242
|
+
if (id < 0) {
|
|
243
|
+
Fed *f = fed_of(id);
|
|
244
|
+
return f ? f->conn : NULL;
|
|
245
|
+
}
|
|
246
|
+
return (size_t)id < nconns ? conns[id] : NULL;
|
|
247
|
+
}
|
|
215
248
|
|
|
216
|
-
|
|
249
|
+
/* the parse error, with Node's bytesParsed and rawPacket: how far into the read llhttp got, and
|
|
250
|
+
* the read (none for a message cut short at the end of the stream) */
|
|
251
|
+
static void parse_error(Conn *c, llhttp_errno_t e, const char *bytes, size_t n) {
|
|
217
252
|
c->detached = true;
|
|
253
|
+
c->failed = e;
|
|
218
254
|
c->active = false;
|
|
219
255
|
JSContext *ctx = ctx_();
|
|
220
256
|
const char *code = c->overflow ? "HPE_HEADER_OVERFLOW" : llhttp_errno_name(e);
|
|
221
257
|
const char *reason = c->overflow ? "Header overflow" : llhttp_get_error_reason(&c->parser);
|
|
222
|
-
|
|
223
|
-
(
|
|
258
|
+
const char *pos = bytes ? llhttp_get_error_pos(&c->parser) : NULL;
|
|
259
|
+
int32_t parsed = pos && pos >= bytes && pos <= bytes + n ? (int32_t)(pos - bytes) : 0;
|
|
260
|
+
JSValue args[5] = { js_int32(c->id), js_new_string_cstr(ctx, code), js_new_string_cstr(ctx, reason ? reason : ""), js_int32(parsed),
|
|
261
|
+
bytes ? bytes_value(ctx, bytes, n) : JS_UNDEFINED };
|
|
262
|
+
(void)js_uv_call(c->parsers->on_error, 5, args, NULL);
|
|
224
263
|
}
|
|
225
264
|
|
|
226
265
|
static void free_conn(Conn *c) {
|
|
@@ -233,16 +272,45 @@ static void free_conn(Conn *c) {
|
|
|
233
272
|
* when llhttp returns if a callback let go of it (a client frees its parser in the response's
|
|
234
273
|
* last callback, and starts the next request in a microtask). */
|
|
235
274
|
static void release_conn(Conn *c) {
|
|
236
|
-
|
|
275
|
+
Fed *f = fed_of(c->id);
|
|
276
|
+
if (f) {
|
|
277
|
+
if (f->conn == c) f->conn = NULL;
|
|
278
|
+
} else if (conns[c->id] == c) {
|
|
279
|
+
conns[c->id] = NULL;
|
|
280
|
+
}
|
|
237
281
|
c->detached = true;
|
|
238
282
|
if (c->executing) c->released = true;
|
|
239
283
|
else free_conn(c);
|
|
240
284
|
}
|
|
241
285
|
|
|
242
|
-
/* The socket's bytes
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
286
|
+
/* The socket's bytes go to JS again: the corked output first, then the parser let go of. */
|
|
287
|
+
static void detach_conn(Conn *c) {
|
|
288
|
+
if (c->queued) flush_conn(c);
|
|
289
|
+
if (c->id >= 0) js_net_hook(c->id, NULL, NULL);
|
|
290
|
+
release_conn(c);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/* llhttp is done with a read: a parser let go of meanwhile is freed, or detached if asked to be. */
|
|
294
|
+
static void read_done(Conn *c) {
|
|
295
|
+
c->executing = false;
|
|
296
|
+
if (c->released) {
|
|
297
|
+
free_conn(c);
|
|
298
|
+
} else if (c->detach_after) {
|
|
299
|
+
c->detach_after = false;
|
|
300
|
+
detach_conn(c);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/* A connection's bytes: parsed while attached; EOF and errors go on to JS (the socket's 'end'
|
|
305
|
+
* and 'error'). False when the parser doesn't take them. */
|
|
306
|
+
static bool parse_input(Conn *c, ssize_t n, const char *bytes) {
|
|
307
|
+
if (c->detached && c->failed != HPE_OK && n > 0 && !c->executing) {
|
|
308
|
+
/* a parser that failed fails again on what follows, with those bytes (Node's execute) */
|
|
309
|
+
c->executing = true;
|
|
310
|
+
parse_error(c, c->failed, bytes, (size_t)n);
|
|
311
|
+
read_done(c);
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
246
314
|
if (c->detached) return false;
|
|
247
315
|
c->executing = true;
|
|
248
316
|
if (n < 0) {
|
|
@@ -250,10 +318,9 @@ static bool hook_read(void *data, ssize_t n, const char *bytes) {
|
|
|
250
318
|
/* a request cut short is the server's parse error; a client's response cut short shows
|
|
251
319
|
* as its 'aborted', when the socket closes (as Node's socketOnEnd ignores finish()) */
|
|
252
320
|
llhttp_errno_t e = llhttp_finish(&c->parser);
|
|
253
|
-
if (e != HPE_OK && !c->detached && !c->response) parse_error(c, e);
|
|
321
|
+
if (e != HPE_OK && !c->detached && !c->response) parse_error(c, e, NULL, 0);
|
|
254
322
|
}
|
|
255
|
-
c
|
|
256
|
-
if (c->released) free_conn(c);
|
|
323
|
+
read_done(c);
|
|
257
324
|
return false;
|
|
258
325
|
}
|
|
259
326
|
const char *at = bytes, *end = bytes + n;
|
|
@@ -261,7 +328,7 @@ static bool hook_read(void *data, ssize_t n, const char *bytes) {
|
|
|
261
328
|
llhttp_errno_t e = llhttp_execute(&c->parser, at, (size_t)(end - at));
|
|
262
329
|
if (e == HPE_OK || c->detached) break; /* released or upgraded by a callback: stop here */
|
|
263
330
|
if (e != HPE_PAUSED_UPGRADE) {
|
|
264
|
-
parse_error(c, e); /* nothing runs once a callback failed in JS: the loop is ending */
|
|
331
|
+
parse_error(c, e, bytes, (size_t)n); /* nothing runs once a callback failed in JS: the loop is ending */
|
|
265
332
|
break;
|
|
266
333
|
}
|
|
267
334
|
const char *pos = llhttp_get_error_pos(&c->parser);
|
|
@@ -276,16 +343,66 @@ static bool hook_read(void *data, ssize_t n, const char *bytes) {
|
|
|
276
343
|
(void)js_uv_call(c->parsers->on_upgrade, 2, args, NULL);
|
|
277
344
|
break;
|
|
278
345
|
}
|
|
279
|
-
c
|
|
280
|
-
if (c->released) free_conn(c);
|
|
346
|
+
read_done(c);
|
|
281
347
|
return true;
|
|
282
348
|
}
|
|
283
349
|
|
|
350
|
+
/* A socket's bytes, before JS sees them. */
|
|
351
|
+
/* a socket's read, parsed in C: its callbacks (a body and its end) run before the microtasks and
|
|
352
|
+
* nextTicks do, as in Node, where one read is one callback scope */
|
|
353
|
+
static bool hook_read(void *data, ssize_t n, const char *bytes) {
|
|
354
|
+
js_uv_nest(1);
|
|
355
|
+
bool ok = parse_input(data, n, bytes);
|
|
356
|
+
js_uv_nest(-1);
|
|
357
|
+
return js_uv_drain() && ok;
|
|
358
|
+
}
|
|
359
|
+
|
|
284
360
|
static void hook_close(void *data) { release_conn(data); }
|
|
285
361
|
|
|
286
362
|
static const JSNetHook http_hook = { hook_read, hook_close };
|
|
287
363
|
|
|
288
|
-
/*
|
|
364
|
+
/* ---- An idle client socket's guard --------------------------------------------------------- */
|
|
365
|
+
|
|
366
|
+
/* Bytes a socket reads while it waits in an agent's pool (no request on it): a server sending what
|
|
367
|
+
* nobody asked for, which the next request would take for its response. Node's free socket data
|
|
368
|
+
* guard: the bytes are dropped and JS destroys the socket. Its end and errors go on to JS. */
|
|
369
|
+
static JSValue guard_callback = JS_UNDEFINED;
|
|
370
|
+
static bool guard_rooted;
|
|
371
|
+
|
|
372
|
+
static bool guard_read(void *data, ssize_t n, const char *bytes) {
|
|
373
|
+
(void)bytes;
|
|
374
|
+
if (n <= 0) return false;
|
|
375
|
+
int id = (int)(intptr_t)data;
|
|
376
|
+
js_net_hook(id, NULL, NULL);
|
|
377
|
+
if (js_is_callable(guard_callback)) {
|
|
378
|
+
JSValue arg = js_int32(id);
|
|
379
|
+
js_uv_nest(1);
|
|
380
|
+
(void)js_uv_call(guard_callback, 1, &arg, NULL);
|
|
381
|
+
js_uv_nest(-1);
|
|
382
|
+
(void)js_uv_drain();
|
|
383
|
+
}
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
static void guard_close(void *data) { (void)data; }
|
|
388
|
+
|
|
389
|
+
static const JSNetHook guard_hook = { guard_read, guard_close };
|
|
390
|
+
|
|
391
|
+
/* httpGuard(conn, onData) → whether it's guarded: onData(conn) when the socket reads while idle */
|
|
392
|
+
JSValue js_host_http_guard(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
393
|
+
(void)callee, (void)this_val, (void)new_target;
|
|
394
|
+
if (argc < 2 || !js_is_int32(argv[0])) return JS_FALSE;
|
|
395
|
+
int id = js_as_int32(argv[0]);
|
|
396
|
+
if (id < 0 || ((size_t)id < nconns && conns[id])) return JS_FALSE; /* a parser has it */
|
|
397
|
+
if (!guard_rooted) {
|
|
398
|
+
js_add_root(ctx->rt, &guard_callback);
|
|
399
|
+
guard_rooted = true;
|
|
400
|
+
}
|
|
401
|
+
guard_callback = argv[1];
|
|
402
|
+
return js_bool(js_net_hook(id, &guard_hook, (void *)(intptr_t)id));
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/* httpParsers(onHead, onBody, onComplete, onUpgrade, onError, onDrain) → id */
|
|
289
406
|
JSValue js_host_http_parsers(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
290
407
|
(void)callee, (void)this_val, (void)new_target;
|
|
291
408
|
if (argc < 5) return js_throw_type_error(ctx, "httpParsers: 5 arguments expected");
|
|
@@ -305,8 +422,9 @@ JSValue js_host_http_parsers(JSContext *ctx, JSValue callee, JSValue this_val, u
|
|
|
305
422
|
Parsers *p = malloc(sizeof *p);
|
|
306
423
|
if (!p) js_fatal("out of memory in http");
|
|
307
424
|
p->on_request = argv[0], p->on_body = argv[1], p->on_complete = argv[2], p->on_upgrade = argv[3], p->on_error = argv[4];
|
|
425
|
+
p->on_drain = argc > 5 ? argv[5] : JS_UNDEFINED;
|
|
308
426
|
js_add_root(ctx->rt, &p->on_request), js_add_root(ctx->rt, &p->on_body), js_add_root(ctx->rt, &p->on_complete);
|
|
309
|
-
js_add_root(ctx->rt, &p->on_upgrade), js_add_root(ctx->rt, &p->on_error);
|
|
427
|
+
js_add_root(ctx->rt, &p->on_upgrade), js_add_root(ctx->rt, &p->on_error), js_add_root(ctx->rt, &p->on_drain);
|
|
310
428
|
Parsers **v = realloc(parsers, (nparsers + 1) * sizeof *v);
|
|
311
429
|
if (!v) js_fatal("out of memory in http");
|
|
312
430
|
parsers = v;
|
|
@@ -320,8 +438,11 @@ JSValue js_host_http_attach(JSContext *ctx, JSValue callee, JSValue this_val, ui
|
|
|
320
438
|
if (argc < 2 || !js_is_int32(argv[0]) || !js_is_int32(argv[1])) return js_throw_type_error(ctx, "httpAttach: (conn, parsers) expected");
|
|
321
439
|
int id = js_as_int32(argv[0]);
|
|
322
440
|
int32_t pi = js_as_int32(argv[1]);
|
|
323
|
-
|
|
324
|
-
if ((size_t)
|
|
441
|
+
Fed *f = fed_of(id);
|
|
442
|
+
if (pi < 0 || (size_t)pi >= nparsers || (id < 0 ? !f : !js_net_stream(id))) return js_int32(UV_EBADF);
|
|
443
|
+
if (f) {
|
|
444
|
+
if (f->conn) release_conn(f->conn);
|
|
445
|
+
} else if ((size_t)id >= nconns) {
|
|
325
446
|
size_t n = nconns ? nconns : 64;
|
|
326
447
|
while (n <= (size_t)id) n *= 2;
|
|
327
448
|
Conn **v = realloc(conns, n * sizeof *v);
|
|
@@ -330,7 +451,7 @@ JSValue js_host_http_attach(JSContext *ctx, JSValue callee, JSValue this_val, ui
|
|
|
330
451
|
conns = v;
|
|
331
452
|
nconns = n;
|
|
332
453
|
}
|
|
333
|
-
if (conns[id]) release_conn(conns[id]); /* a kept-alive socket's next request: a fresh parser */
|
|
454
|
+
if (!f && conns[id]) release_conn(conns[id]); /* a kept-alive socket's next request: a fresh parser */
|
|
334
455
|
Conn *c = calloc(1, sizeof *c);
|
|
335
456
|
if (!c) js_fatal("out of memory in http");
|
|
336
457
|
c->id = id;
|
|
@@ -343,23 +464,52 @@ JSValue js_host_http_attach(JSContext *ctx, JSValue callee, JSValue this_val, ui
|
|
|
343
464
|
js_add_root(ctx->rt, &c->headers);
|
|
344
465
|
llhttp_init(&c->parser, c->response ? HTTP_RESPONSE : HTTP_REQUEST, &settings);
|
|
345
466
|
c->parser.data = c;
|
|
346
|
-
|
|
347
|
-
|
|
467
|
+
if (f) {
|
|
468
|
+
f->conn = c; /* its bytes come from httpFeed */
|
|
469
|
+
} else {
|
|
470
|
+
conns[id] = c;
|
|
471
|
+
js_net_hook(id, &http_hook, c);
|
|
472
|
+
}
|
|
348
473
|
return js_int32(0);
|
|
349
474
|
}
|
|
350
475
|
|
|
351
|
-
/* httpDetach(conn): the socket's bytes go to JS again (its corked output goes first)
|
|
476
|
+
/* httpDetach(conn, afterRead): the socket's bytes go to JS again (its corked output goes first);
|
|
477
|
+
* with afterRead, from a parser callback, once llhttp is done with the read, as Node's client frees
|
|
478
|
+
* its parser after the read (what follows a response in it is still parsed) */
|
|
352
479
|
JSValue js_host_http_detach(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
353
480
|
(void)ctx, (void)callee, (void)this_val, (void)new_target;
|
|
354
481
|
Conn *c = argc > 0 && js_is_int32(argv[0]) ? conn_of(js_as_int32(argv[0])) : NULL;
|
|
355
|
-
if (c)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
release_conn(c);
|
|
359
|
-
}
|
|
482
|
+
if (!c) return JS_UNDEFINED;
|
|
483
|
+
if (argc > 1 && js_truthy(argv[1]) && c->executing) c->detach_after = true;
|
|
484
|
+
else detach_conn(c);
|
|
360
485
|
return JS_UNDEFINED;
|
|
361
486
|
}
|
|
362
487
|
|
|
488
|
+
/* httpBusy(conn): whether a message is under way on the connection (begun, not complete), as Node's
|
|
489
|
+
* ConnectionsList tells an idle connection from an active one */
|
|
490
|
+
JSValue js_host_http_busy(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
491
|
+
(void)ctx, (void)callee, (void)this_val, (void)new_target;
|
|
492
|
+
Conn *c = argc > 0 && js_is_int32(argv[0]) ? conn_of(js_as_int32(argv[0])) : NULL;
|
|
493
|
+
return js_bool(c && c->in_message && !c->detached);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/* httpPending(conn) → the bytes written to it that haven't gone out yet (a response's backpressure) */
|
|
497
|
+
JSValue js_host_http_pending(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
498
|
+
(void)ctx, (void)callee, (void)this_val, (void)new_target;
|
|
499
|
+
Conn *c = argc > 0 && js_is_int32(argv[0]) ? conn_of(js_as_int32(argv[0])) : NULL;
|
|
500
|
+
return js_number(c ? (double)pending_bytes(c) : 0);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/* httpWatchDrain(conn) → true when nothing is pending (drained already), else the parsers' onDrain
|
|
504
|
+
* is called once it all has gone out */
|
|
505
|
+
JSValue js_host_http_watch_drain(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
506
|
+
(void)ctx, (void)callee, (void)this_val, (void)new_target;
|
|
507
|
+
Conn *c = argc > 0 && js_is_int32(argv[0]) ? conn_of(js_as_int32(argv[0])) : NULL;
|
|
508
|
+
if (!c || pending_bytes(c) == 0) return JS_TRUE;
|
|
509
|
+
c->need_drain = true;
|
|
510
|
+
return JS_FALSE;
|
|
511
|
+
}
|
|
512
|
+
|
|
363
513
|
/* httpExpired(parsers, headersTimeout, requestTimeout) → the connections over time, as Node's
|
|
364
514
|
* ConnectionsList::Expired: a head not complete within headersTimeout, or a request not
|
|
365
515
|
* complete within requestTimeout, from its start (or the connection's); 0 turns one off */
|
|
@@ -372,8 +522,8 @@ JSValue js_host_http_expired(JSContext *ctx, JSValue callee, JSValue this_val, u
|
|
|
372
522
|
JSValue list = js_new_array(ctx, 0);
|
|
373
523
|
if (pi < 0 || (size_t)pi >= nparsers) return list;
|
|
374
524
|
uint64_t now = uv_now(js_uv_loop(ctx));
|
|
375
|
-
for (size_t i = 0; i < nconns; i++) {
|
|
376
|
-
Conn *c = conns[i];
|
|
525
|
+
for (size_t i = 0; i < nconns + nfeds; i++) {
|
|
526
|
+
Conn *c = i < nconns ? conns[i] : feds[i - nconns] ? feds[i - nconns]->conn : NULL;
|
|
377
527
|
if (!c || c->parsers != parsers[pi] || !c->active || c->detached) continue;
|
|
378
528
|
uint64_t age = now - c->begin_ms;
|
|
379
529
|
if ((!c->head_done && headers_timeout > 0 && (double)age > headers_timeout) || (request_timeout > 0 && (double)age > request_timeout)) {
|
|
@@ -389,18 +539,44 @@ JSValue js_host_http_expired(JSContext *ctx, JSValue callee, JSValue this_val, u
|
|
|
389
539
|
typedef struct WriteReq {
|
|
390
540
|
uv_write_t req;
|
|
391
541
|
char *data;
|
|
542
|
+
int id; /* the connection's: whether its output has drained, once written */
|
|
392
543
|
} WriteReq;
|
|
393
544
|
|
|
545
|
+
/* bytes written to the connection but not yet sent: corked, or in libuv's write queue */
|
|
546
|
+
static size_t pending_bytes(Conn *c) {
|
|
547
|
+
uv_stream_t *s = c->id >= 0 ? js_net_stream(c->id) : NULL;
|
|
548
|
+
return c->out.n + (s ? uv_stream_get_write_queue_size(s) : 0);
|
|
549
|
+
}
|
|
550
|
+
|
|
394
551
|
static void on_written(uv_write_t *req, int status) {
|
|
395
552
|
(void)status; /* a failed write shows as the socket's read error, or its close */
|
|
396
553
|
WriteReq *w = (WriteReq *)req;
|
|
554
|
+
int id = w->id;
|
|
397
555
|
free(w->data);
|
|
398
556
|
free(w);
|
|
557
|
+
/* JS waited for the output to drain (Node's 'drain' on the response) */
|
|
558
|
+
Conn *c = conn_of(id);
|
|
559
|
+
if (c && c->need_drain && pending_bytes(c) == 0) {
|
|
560
|
+
c->need_drain = false;
|
|
561
|
+
if (js_is_callable(c->parsers->on_drain)) {
|
|
562
|
+
JSValue arg = js_int32(id);
|
|
563
|
+
(void)js_uv_call(c->parsers->on_drain, 1, &arg, NULL);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
399
566
|
}
|
|
400
567
|
|
|
401
568
|
/* Sends a connection's corked output as one write. */
|
|
402
569
|
static void flush_conn(Conn *c) {
|
|
403
570
|
c->queued = false;
|
|
571
|
+
Fed *f = fed_of(c->id);
|
|
572
|
+
if (f) { /* to its writer: the connection may be gone when it returns */
|
|
573
|
+
if (c->out.n == 0) return;
|
|
574
|
+
JSValue bytes = bytes_value(ctx_(), c->out.v, c->out.n);
|
|
575
|
+
c->out.n = 0;
|
|
576
|
+
JSValue writer = f->writer;
|
|
577
|
+
(void)js_uv_call(writer, 1, &bytes, NULL);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
404
580
|
uv_stream_t *s = js_net_stream(c->id);
|
|
405
581
|
if (!s || c->out.n == 0) {
|
|
406
582
|
c->out.n = 0;
|
|
@@ -409,6 +585,7 @@ static void flush_conn(Conn *c) {
|
|
|
409
585
|
WriteReq *w = malloc(sizeof *w);
|
|
410
586
|
if (!w) js_fatal("out of memory in http");
|
|
411
587
|
w->data = c->out.v; /* the buffer goes with the write; the connection starts a new one */
|
|
588
|
+
w->id = c->id;
|
|
412
589
|
uv_buf_t b = uv_buf_init(c->out.v, (unsigned)c->out.n);
|
|
413
590
|
c->out = (Buf){ 0 };
|
|
414
591
|
if (uv_write(&w->req, s, &b, 1, on_written) < 0) {
|
|
@@ -417,20 +594,35 @@ static void flush_conn(Conn *c) {
|
|
|
417
594
|
}
|
|
418
595
|
}
|
|
419
596
|
|
|
597
|
+
/* Taken over before it runs: a fed connection's writer runs JS, which may write (and flush) more. */
|
|
420
598
|
static void flush_pending(void) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
599
|
+
while (npending > 0) {
|
|
600
|
+
int *ids = pending;
|
|
601
|
+
size_t n = npending;
|
|
602
|
+
pending = NULL;
|
|
603
|
+
npending = pending_cap = 0;
|
|
604
|
+
for (size_t i = 0; i < n; i++) {
|
|
605
|
+
Conn *c = conn_of(ids[i]);
|
|
606
|
+
if (c && c->queued) flush_conn(c);
|
|
607
|
+
}
|
|
608
|
+
free(ids);
|
|
424
609
|
}
|
|
425
|
-
npending = 0;
|
|
426
610
|
}
|
|
427
611
|
|
|
428
|
-
/* httpWrite(conn, data): corked until the current callback (and its microtasks) returns
|
|
612
|
+
/* httpWrite(conn, data, latin1): corked until the current callback (and its microtasks) returns; a
|
|
613
|
+
* string as UTF-8, or with latin1 a byte a character (its low byte), as Node writes a head */
|
|
429
614
|
JSValue js_host_http_write(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
430
615
|
(void)callee, (void)this_val, (void)new_target;
|
|
431
616
|
Conn *c = argc > 0 && js_is_int32(argv[0]) ? conn_of(js_as_int32(argv[0])) : NULL;
|
|
432
|
-
if (!c || argc < 2 || !js_net_stream(c->id)) return JS_FALSE;
|
|
433
|
-
if (js_is_string(argv[1])) {
|
|
617
|
+
if (!c || argc < 2 || (c->id >= 0 && !js_net_stream(c->id))) return JS_FALSE;
|
|
618
|
+
if (js_is_string(argv[1]) && argc > 2 && js_truthy(argv[2])) {
|
|
619
|
+
JSStrView v = js_string_view(ctx, argv[1]);
|
|
620
|
+
if (v.length == 0) return JS_TRUE;
|
|
621
|
+
buf_reserve(&c->out, v.length);
|
|
622
|
+
if (v.latin1) memcpy(c->out.v + c->out.n, v.chars, v.length);
|
|
623
|
+
else for (uint32_t i = 0; i < v.length; i++) c->out.v[c->out.n + i] = (char)(js_view_at(v, i) & 0xff);
|
|
624
|
+
c->out.n += v.length;
|
|
625
|
+
} else if (js_is_string(argv[1])) {
|
|
434
626
|
JSStrView v = js_string_view(ctx, argv[1]);
|
|
435
627
|
size_t n = js_view_to_utf8(v, NULL, 0);
|
|
436
628
|
if (n == 0) return JS_TRUE;
|
|
@@ -465,6 +657,67 @@ JSValue js_host_http_flush(JSContext *ctx, JSValue callee, JSValue this_val, uin
|
|
|
465
657
|
return JS_UNDEFINED;
|
|
466
658
|
}
|
|
467
659
|
|
|
660
|
+
/* ---- Fed connections --------------------------------------------------------------------- */
|
|
661
|
+
|
|
662
|
+
/* httpFedOpen(writer) → conn: a connection whose bytes JS feeds */
|
|
663
|
+
JSValue js_host_http_fed_open(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
664
|
+
(void)callee, (void)this_val, (void)new_target;
|
|
665
|
+
if (argc < 1 || !js_is_callable(argv[0])) return js_throw_type_error(ctx, "httpFedOpen: a writer expected");
|
|
666
|
+
size_t k = 0;
|
|
667
|
+
while (k < nfeds && feds[k]) k++;
|
|
668
|
+
if (k == nfeds) {
|
|
669
|
+
size_t n = nfeds ? nfeds * 2 : 16;
|
|
670
|
+
Fed **v = realloc(feds, n * sizeof *v);
|
|
671
|
+
if (!v) js_fatal("out of memory in http");
|
|
672
|
+
memset(v + nfeds, 0, (n - nfeds) * sizeof *v);
|
|
673
|
+
feds = v;
|
|
674
|
+
nfeds = n;
|
|
675
|
+
}
|
|
676
|
+
Fed *f = calloc(1, sizeof *f); /* by itself: its writer is a root at a fixed address */
|
|
677
|
+
if (!f) js_fatal("out of memory in http");
|
|
678
|
+
f->writer = argv[0];
|
|
679
|
+
js_add_root(ctx->rt, &f->writer);
|
|
680
|
+
feds[k] = f;
|
|
681
|
+
return js_int32(-(int32_t)k - 1);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/* httpFeed(conn, bytes | null) → whether the parser took them; null: the input ended */
|
|
685
|
+
JSValue js_host_http_feed(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
686
|
+
(void)callee, (void)this_val, (void)new_target;
|
|
687
|
+
/* a fed connection's bytes; or a socket's that JS read before the parser took the socket */
|
|
688
|
+
Conn *c = argc > 0 && js_is_int32(argv[0]) ? conn_of(js_as_int32(argv[0])) : NULL;
|
|
689
|
+
if (!c) return JS_FALSE;
|
|
690
|
+
/* called from JS: the parser's callbacks run in it, so no microtask or nextTick runs between
|
|
691
|
+
* two of them (a body and its end come in the same turn, as in Node) */
|
|
692
|
+
if (argc < 2 || js_is_null(argv[1]) || js_is_undefined(argv[1])) {
|
|
693
|
+
js_uv_nest(1);
|
|
694
|
+
bool ok = parse_input(c, UV_EOF, NULL);
|
|
695
|
+
js_uv_nest(-1);
|
|
696
|
+
return js_bool(ok);
|
|
697
|
+
}
|
|
698
|
+
uint8_t *bytes;
|
|
699
|
+
size_t n;
|
|
700
|
+
if (!js_buffer_source_bytes(argv[1], &bytes, &n)) return js_throw_type_error(ctx, "httpFeed: bytes expected");
|
|
701
|
+
if (n == 0) return JS_TRUE;
|
|
702
|
+
js_uv_nest(1);
|
|
703
|
+
bool ok = parse_input(c, (ssize_t)n, (const char *)bytes);
|
|
704
|
+
js_uv_nest(-1);
|
|
705
|
+
return js_bool(ok);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/* httpFedClose(conn): its parser and writer go */
|
|
709
|
+
JSValue js_host_http_fed_close(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
710
|
+
(void)callee, (void)this_val, (void)new_target;
|
|
711
|
+
int id = argc > 0 && js_is_int32(argv[0]) ? js_as_int32(argv[0]) : 0;
|
|
712
|
+
Fed *f = fed_of(id);
|
|
713
|
+
if (!f) return JS_UNDEFINED;
|
|
714
|
+
if (f->conn) release_conn(f->conn);
|
|
715
|
+
feds[-(id + 1)] = NULL;
|
|
716
|
+
js_remove_root(ctx->rt, &f->writer);
|
|
717
|
+
free(f);
|
|
718
|
+
return JS_UNDEFINED;
|
|
719
|
+
}
|
|
720
|
+
|
|
468
721
|
/* httpDate(): the Date header's value, IMF-fixdate, formatted once per second (as Node caches it) */
|
|
469
722
|
JSValue js_host_http_date(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
470
723
|
(void)callee, (void)this_val, (void)argc, (void)argv, (void)new_target;
|
package/node/src/host_loop.c
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* The libuv loop the host modules share
|
|
1
|
+
/* The libuv loop the host modules share: node:http and node:net
|
|
2
2
|
* install it on first use, so programs without I/O don't link libuv. */
|
|
3
3
|
#define _POSIX_C_SOURCE 200809L /* libuv's headers: pthread_rwlock_t, struct addrinfo */
|
|
4
4
|
#ifndef _WIN32
|
|
@@ -16,6 +16,7 @@ static uv_timer_t wake; /* ends uv_run at the next timer's deadline; unref'
|
|
|
16
16
|
static JSContext *loop_ctx; /* the realm callbacks run in */
|
|
17
17
|
static int failed; /* exit status after an uncaught error in a callback */
|
|
18
18
|
static void (*flush_hook)(void);
|
|
19
|
+
static int call_depth; /* js_uv_calls under way: one made from JS (a fed http parser's) nests */
|
|
19
20
|
|
|
20
21
|
static void on_wake(uv_timer_t *t) { (void)t; }
|
|
21
22
|
|
|
@@ -63,13 +64,29 @@ JSContext *js_uv_context(void) { return loop_ctx; }
|
|
|
63
64
|
|
|
64
65
|
void js_uv_set_flush(void (*fn)(void)) { flush_hook = fn; }
|
|
65
66
|
|
|
67
|
+
void js_uv_nest(int delta) { call_depth += delta; }
|
|
68
|
+
|
|
69
|
+
bool js_uv_drain(void) {
|
|
70
|
+
if (failed) return false;
|
|
71
|
+
if (call_depth > 0) return true;
|
|
72
|
+
if (js_run_microtasks(loop_ctx) < 0) {
|
|
73
|
+
failed = loop_ctx->rt->failure;
|
|
74
|
+
uv_stop(loop);
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
flush();
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
66
81
|
bool js_uv_call(JSValue fn, uint32_t argc, JSValue *argv, JSValue *result) {
|
|
67
82
|
if (failed) return false;
|
|
68
83
|
JSContext *ctx = loop_ctx;
|
|
69
|
-
/* under no async context
|
|
84
|
+
/* under no async context: the prelude binds a callback to the one it was given in */
|
|
70
85
|
JSValue saved = js_async_context(ctx);
|
|
71
86
|
js_set_async_context(ctx, JS_UNDEFINED);
|
|
87
|
+
call_depth++;
|
|
72
88
|
JSValue r = js_call(ctx, fn, JS_UNDEFINED, argc, argv);
|
|
89
|
+
call_depth--;
|
|
73
90
|
js_set_async_context(ctx, saved);
|
|
74
91
|
if (js_is_exception(r)) {
|
|
75
92
|
failed = js_report_uncaught(ctx);
|
|
@@ -79,6 +96,12 @@ bool js_uv_call(JSValue fn, uint32_t argc, JSValue *argv, JSValue *result) {
|
|
|
79
96
|
}
|
|
80
97
|
r = JS_UNDEFINED; /* handled ('uncaughtException'): the program goes on */
|
|
81
98
|
}
|
|
99
|
+
/* microtasks run, and output goes out, when the outermost callback returns, as in Node: a call
|
|
100
|
+
* made while JS is running (a parser fed from a 'data' listener) leaves them to it */
|
|
101
|
+
if (call_depth > 0) {
|
|
102
|
+
if (result) *result = r;
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
82
105
|
if (js_run_microtasks(ctx) < 0) {
|
|
83
106
|
failed = ctx->rt->failure;
|
|
84
107
|
uv_stop(loop);
|