Showing preview only (6,185K chars total). Download the full file or copy to clipboard to get everything.
Repository: nodejs/undici
Branch: main
Commit: 4c3a2be56abc
Files: 733
Total size: 5.8 MB
Directory structure:
gitextract_26dbkv5y/
├── .c8rc.json
├── .dockerignore
├── .editorconfig
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.md
│ │ └── feature-request.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── autobahn.yml
│ ├── backport.yml
│ ├── bench.yml
│ ├── ci.yml
│ ├── codeql.yml
│ ├── nodejs-nightly.yml
│ ├── nodejs-shared.yml
│ ├── nodejs.yml
│ ├── release-create-pr.yml
│ ├── release.yml
│ ├── scorecard.yml
│ ├── triggered-autobahn.yml
│ └── update-submodules.yml
├── .gitignore
├── .gitmodules
├── .husky/
│ └── pre-commit
├── .npmignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── SECURITY.md
├── benchmarks/
│ ├── _util/
│ │ ├── index.js
│ │ └── runner.js
│ ├── benchmark-http2.js
│ ├── benchmark-https.js
│ ├── benchmark.js
│ ├── cache/
│ │ ├── date.mjs
│ │ └── get-field-values.mjs
│ ├── cookies/
│ │ ├── is-ctl-excluding-htab.mjs
│ │ ├── to-imf-date.mjs
│ │ ├── validate-cookie-name.mjs
│ │ └── validate-cookie-value.mjs
│ ├── core/
│ │ ├── is-blob-like.mjs
│ │ ├── is-valid-header-char.mjs
│ │ ├── is-valid-port.mjs
│ │ ├── parse-headers.mjs
│ │ ├── parse-raw-headers.mjs
│ │ ├── request-instantiation.mjs
│ │ └── tree.mjs
│ ├── fetch/
│ │ ├── body-arraybuffer.mjs
│ │ ├── bytes-match.mjs
│ │ ├── headers-length32.mjs
│ │ ├── headers.mjs
│ │ ├── is-valid-encoded-url.mjs
│ │ ├── is-valid-header-value.mjs
│ │ ├── isomorphic-encode.mjs
│ │ ├── request-creation.mjs
│ │ └── url-has-https-scheme.mjs
│ ├── package.json
│ ├── post-benchmark.js
│ ├── server-http2.js
│ ├── server-https.js
│ ├── server.js
│ ├── timers/
│ │ └── compare-timer-getters.mjs
│ ├── utils/
│ │ └── date.mjs
│ ├── wait.js
│ ├── webidl/
│ │ └── webidl-is.mjs
│ ├── websocket/
│ │ ├── generate-mask.mjs
│ │ ├── is-valid-subprotocol.mjs
│ │ └── messageevent.mjs
│ ├── websocket-benchmark.mjs
│ └── websocket-echo-server.mjs
├── build/
│ └── wasm.js
├── deps/
│ └── llhttp/
│ ├── include/
│ │ └── llhttp.h
│ └── src/
│ ├── api.c
│ ├── http.c
│ └── llhttp.c
├── docs/
│ ├── .nojekyll
│ ├── CNAME
│ ├── docs/
│ │ ├── api/
│ │ │ ├── Agent.md
│ │ │ ├── BalancedPool.md
│ │ │ ├── CacheStorage.md
│ │ │ ├── CacheStore.md
│ │ │ ├── Client.md
│ │ │ ├── ClientStats.md
│ │ │ ├── Connector.md
│ │ │ ├── ContentType.md
│ │ │ ├── Cookies.md
│ │ │ ├── Debug.md
│ │ │ ├── DiagnosticsChannel.md
│ │ │ ├── Dispatcher.md
│ │ │ ├── EnvHttpProxyAgent.md
│ │ │ ├── Errors.md
│ │ │ ├── EventSource.md
│ │ │ ├── Fetch.md
│ │ │ ├── GlobalInstallation.md
│ │ │ ├── H2CClient.md
│ │ │ ├── MockAgent.md
│ │ │ ├── MockCallHistory.md
│ │ │ ├── MockCallHistoryLog.md
│ │ │ ├── MockClient.md
│ │ │ ├── MockErrors.md
│ │ │ ├── MockPool.md
│ │ │ ├── Pool.md
│ │ │ ├── PoolStats.md
│ │ │ ├── ProxyAgent.md
│ │ │ ├── RedirectHandler.md
│ │ │ ├── RetryAgent.md
│ │ │ ├── RetryHandler.md
│ │ │ ├── RoundRobinPool.md
│ │ │ ├── SnapshotAgent.md
│ │ │ ├── Socks5ProxyAgent.md
│ │ │ ├── Util.md
│ │ │ ├── WebSocket.md
│ │ │ └── api-lifecycle.md
│ │ └── best-practices/
│ │ ├── client-certificate.md
│ │ ├── crawling.md
│ │ ├── mocking-request.md
│ │ ├── proxy.md
│ │ ├── undici-vs-builtin-fetch.md
│ │ └── writing-tests.md
│ ├── docsify/
│ │ └── sidebar.md
│ ├── examples/
│ │ ├── README.md
│ │ ├── ca-fingerprint/
│ │ │ └── index.js
│ │ ├── eventsource.js
│ │ ├── fetch.js
│ │ ├── proxy/
│ │ │ ├── fetch.mjs
│ │ │ ├── index.js
│ │ │ ├── proxy.js
│ │ │ └── websocket.js
│ │ ├── proxy-agent.js
│ │ ├── request.js
│ │ ├── snapshot-testing.js
│ │ └── socks5-proxy.js
│ ├── index.html
│ └── package.json
├── eslint.config.js
├── index-fetch.js
├── index.d.ts
├── index.js
├── lib/
│ ├── api/
│ │ ├── abort-signal.js
│ │ ├── api-connect.js
│ │ ├── api-pipeline.js
│ │ ├── api-request.js
│ │ ├── api-stream.js
│ │ ├── api-upgrade.js
│ │ ├── index.js
│ │ └── readable.js
│ ├── cache/
│ │ ├── memory-cache-store.js
│ │ └── sqlite-cache-store.js
│ ├── core/
│ │ ├── connect.js
│ │ ├── constants.js
│ │ ├── diagnostics.js
│ │ ├── errors.js
│ │ ├── request.js
│ │ ├── socks5-client.js
│ │ ├── socks5-utils.js
│ │ ├── symbols.js
│ │ ├── tree.js
│ │ └── util.js
│ ├── dispatcher/
│ │ ├── agent.js
│ │ ├── balanced-pool.js
│ │ ├── client-h1.js
│ │ ├── client-h2.js
│ │ ├── client.js
│ │ ├── dispatcher-base.js
│ │ ├── dispatcher.js
│ │ ├── env-http-proxy-agent.js
│ │ ├── fixed-queue.js
│ │ ├── h2c-client.js
│ │ ├── pool-base.js
│ │ ├── pool.js
│ │ ├── proxy-agent.js
│ │ ├── retry-agent.js
│ │ ├── round-robin-pool.js
│ │ └── socks5-proxy-agent.js
│ ├── encoding/
│ │ └── index.js
│ ├── global.js
│ ├── handler/
│ │ ├── cache-handler.js
│ │ ├── cache-revalidation-handler.js
│ │ ├── decorator-handler.js
│ │ ├── deduplication-handler.js
│ │ ├── redirect-handler.js
│ │ ├── retry-handler.js
│ │ ├── unwrap-handler.js
│ │ └── wrap-handler.js
│ ├── interceptor/
│ │ ├── cache.js
│ │ ├── decompress.js
│ │ ├── deduplicate.js
│ │ ├── dns.js
│ │ ├── dump.js
│ │ ├── redirect.js
│ │ ├── response-error.js
│ │ └── retry.js
│ ├── llhttp/
│ │ ├── .gitkeep
│ │ ├── constants.d.ts
│ │ ├── constants.js
│ │ ├── llhttp-wasm.js
│ │ ├── llhttp.wasm
│ │ ├── llhttp_simd-wasm.js
│ │ ├── llhttp_simd.wasm
│ │ ├── utils.d.ts
│ │ └── utils.js
│ ├── mock/
│ │ ├── mock-agent.js
│ │ ├── mock-call-history.js
│ │ ├── mock-client.js
│ │ ├── mock-errors.js
│ │ ├── mock-interceptor.js
│ │ ├── mock-pool.js
│ │ ├── mock-symbols.js
│ │ ├── mock-utils.js
│ │ ├── pending-interceptors-formatter.js
│ │ ├── snapshot-agent.js
│ │ ├── snapshot-recorder.js
│ │ └── snapshot-utils.js
│ ├── util/
│ │ ├── cache.js
│ │ ├── date.js
│ │ ├── promise.js
│ │ ├── runtime-features.js
│ │ ├── stats.js
│ │ └── timers.js
│ └── web/
│ ├── cache/
│ │ ├── cache.js
│ │ ├── cachestorage.js
│ │ └── util.js
│ ├── cookies/
│ │ ├── constants.js
│ │ ├── index.js
│ │ ├── parse.js
│ │ └── util.js
│ ├── eventsource/
│ │ ├── eventsource-stream.js
│ │ ├── eventsource.js
│ │ └── util.js
│ ├── fetch/
│ │ ├── LICENSE
│ │ ├── body.js
│ │ ├── constants.js
│ │ ├── data-url.js
│ │ ├── formdata-parser.js
│ │ ├── formdata.js
│ │ ├── global.js
│ │ ├── headers.js
│ │ ├── index.js
│ │ ├── request.js
│ │ ├── response.js
│ │ └── util.js
│ ├── infra/
│ │ └── index.js
│ ├── subresource-integrity/
│ │ ├── Readme.md
│ │ └── subresource-integrity.js
│ ├── webidl/
│ │ └── index.js
│ └── websocket/
│ ├── connection.js
│ ├── constants.js
│ ├── events.js
│ ├── frame.js
│ ├── permessage-deflate.js
│ ├── receiver.js
│ ├── sender.js
│ ├── stream/
│ │ ├── websocketerror.js
│ │ └── websocketstream.js
│ ├── util.js
│ └── websocket.js
├── package.json
├── scripts/
│ ├── clean-coverage.js
│ ├── generate-pem.js
│ ├── generate-undici-types-package-json.js
│ ├── platform-shell.js
│ ├── release.js
│ └── strip-comments.js
├── test/
│ ├── autobahn/
│ │ ├── .gitignore
│ │ ├── client.js
│ │ ├── config/
│ │ │ └── fuzzingserver.json
│ │ ├── report.js
│ │ └── run.sh
│ ├── busboy/
│ │ ├── LICENSE
│ │ ├── formdata-test.js
│ │ ├── issue-3676.js
│ │ ├── issue-3760.js
│ │ ├── issue-4660.js
│ │ ├── issue-4671.js
│ │ ├── test-parser.js
│ │ ├── test-types-multipart-charsets.js
│ │ └── test-types-multipart.js
│ ├── cache/
│ │ ├── cache.js
│ │ ├── cachestorage.js
│ │ └── get-field-values.js
│ ├── cache-interceptor/
│ │ ├── cache-store-test-utils.js
│ │ ├── cache-tests-worker.mjs
│ │ ├── cache-tests.mjs
│ │ ├── cache-utils.js
│ │ ├── memory-cache-store-tests.js
│ │ ├── sqlite-cache-store-tests.js
│ │ └── utils.js
│ ├── client-connect.js
│ ├── client-head-reset-override.js
│ ├── client-idempotent-body.js
│ ├── client-keep-alive.js
│ ├── client-node-max-header-size.js
│ ├── client-pipeline.js
│ ├── client-pipelining.js
│ ├── client-post.js
│ ├── client-reconnect.js
│ ├── client-request.js
│ ├── client-stream.js
│ ├── client-timeout.js
│ ├── client-unref.js
│ ├── client-upgrade.js
│ ├── client-wasm.js
│ ├── client-write-max-listeners.js
│ ├── client.js
│ ├── close-and-destroy.js
│ ├── connect-abort.js
│ ├── connect-errconnect.js
│ ├── connect-pre-shared-session.js
│ ├── connect-timeout.js
│ ├── content-length.js
│ ├── cookie/
│ │ ├── cookies.js
│ │ ├── global-headers.js
│ │ ├── is-ctl-excluding-htab.js
│ │ ├── npm-cookie.js
│ │ ├── to-imf-date.js
│ │ ├── validate-cookie-name.js
│ │ ├── validate-cookie-path.js
│ │ └── validate-cookie-value.js
│ ├── decorator-handler.js
│ ├── dispatcher.js
│ ├── env-http-proxy-agent-nodejs-bundle.js
│ ├── env-http-proxy-agent.js
│ ├── errors.js
│ ├── esm-wrapper.js
│ ├── eventsource/
│ │ ├── eventsource-attributes.js
│ │ ├── eventsource-close.js
│ │ ├── eventsource-connect.js
│ │ ├── eventsource-constructor-stringify.js
│ │ ├── eventsource-constructor.js
│ │ ├── eventsource-custom-dispatcher.js
│ │ ├── eventsource-message.js
│ │ ├── eventsource-properties.js
│ │ ├── eventsource-reconnect.js
│ │ ├── eventsource-redirecting.js
│ │ ├── eventsource-request-status-error.js
│ │ ├── eventsource-stream-bom.js
│ │ ├── eventsource-stream-parse-line.js
│ │ ├── eventsource-stream-process-event.js
│ │ ├── eventsource-stream.js
│ │ ├── eventsource.js
│ │ └── util.js
│ ├── examples.js
│ ├── fetch/
│ │ ├── 401-statuscode-no-infinite-loop.js
│ │ ├── 407-statuscode-window-null.js
│ │ ├── abort.js
│ │ ├── abort2.js
│ │ ├── about-uri.js
│ │ ├── blob-uri.js
│ │ ├── bundle.js
│ │ ├── client-error-stack-trace.js
│ │ ├── client-fetch.js
│ │ ├── client-node-max-header-size.js
│ │ ├── content-length.js
│ │ ├── cookies.js
│ │ ├── data-uri.js
│ │ ├── encoding.js
│ │ ├── exiting.js
│ │ ├── export-env-proxy-agent.js
│ │ ├── fetch-leak.js
│ │ ├── fetch-timeouts.js
│ │ ├── fetch-url-after-redirect.js
│ │ ├── fire-and-forget.js
│ │ ├── formdata-inspect-custom.js
│ │ ├── formdata.js
│ │ ├── general.js
│ │ ├── headers-case.js
│ │ ├── headers-inspect-custom.js
│ │ ├── headers.js
│ │ ├── headerslist-sortedarray.js
│ │ ├── http2.js
│ │ ├── includes-credentials.js
│ │ ├── integrity.js
│ │ ├── issue-1447.js
│ │ ├── issue-1711.js
│ │ ├── issue-2009.js
│ │ ├── issue-2021.js
│ │ ├── issue-2171.js
│ │ ├── issue-2242.js
│ │ ├── issue-2294-patch-method.js
│ │ ├── issue-2318.js
│ │ ├── issue-2828.js
│ │ ├── issue-2898-comment.js
│ │ ├── issue-2898.js
│ │ ├── issue-3267.js
│ │ ├── issue-3334.js
│ │ ├── issue-3616.js
│ │ ├── issue-3624.js
│ │ ├── issue-3630.js
│ │ ├── issue-3767.js
│ │ ├── issue-4105.js
│ │ ├── issue-4627.js
│ │ ├── issue-4647.js
│ │ ├── issue-4789.js
│ │ ├── issue-4799.js
│ │ ├── issue-4836.js
│ │ ├── issue-4897.js
│ │ ├── issue-node-46525.js
│ │ ├── issue-rsshub-15532.js
│ │ ├── iterators.js
│ │ ├── long-lived-abort-controller.js
│ │ ├── max-listeners.js
│ │ ├── pull-dont-push.js
│ │ ├── readable-stream-from.js
│ │ ├── redirect-cross-origin-header.js
│ │ ├── redirect.js
│ │ ├── referrrer-policy.js
│ │ ├── relative-url.js
│ │ ├── request-inspect-custom.js
│ │ ├── request.js
│ │ ├── resource-timing.js
│ │ ├── response-inspect-custom.js
│ │ ├── response-json.js
│ │ ├── response.js
│ │ ├── spread.js
│ │ ├── user-agent.js
│ │ └── util.js
│ ├── fixed-queue.js
│ ├── fixtures/
│ │ ├── ca.pem
│ │ ├── cert.pem
│ │ ├── docker/
│ │ │ ├── dante/
│ │ │ │ ├── Dockerfile
│ │ │ │ └── danted.conf
│ │ │ └── docker-compose.yml
│ │ ├── duplicate-debug.js
│ │ ├── fetch.js
│ │ ├── interceptors/
│ │ │ └── retry-event-loop.js
│ │ ├── key.pem
│ │ ├── socks5-test-server.js
│ │ ├── undici.js
│ │ └── websocket.js
│ ├── fuzzing/
│ │ ├── client/
│ │ │ ├── client-fuzz-body.js
│ │ │ ├── client-fuzz-headers.js
│ │ │ ├── client-fuzz-options.js
│ │ │ └── index.js
│ │ ├── fuzzing.test.js
│ │ └── server/
│ │ ├── index.js
│ │ ├── server-fuzz-append-data.js
│ │ └── server-fuzz-split-data.js
│ ├── gc.js
│ ├── get-head-body.js
│ ├── h2c-client.js
│ ├── headers-as-array.js
│ ├── headers-crlf.js
│ ├── http-100.js
│ ├── http-req-destroy.js
│ ├── http2-abort.js
│ ├── http2-agent.js
│ ├── http2-alpn.js
│ ├── http2-body.js
│ ├── http2-connection.js
│ ├── http2-continue.js
│ ├── http2-dispatcher.js
│ ├── http2-goaway.js
│ ├── http2-instantiation.js
│ ├── http2-late-data.js
│ ├── http2-pseudo-headers.js
│ ├── http2-resume-null-request.js
│ ├── http2-stream.js
│ ├── http2-timeout.js
│ ├── http2-trailers.js
│ ├── http2-window-size.js
│ ├── https.js
│ ├── imports/
│ │ └── undici-import.ts
│ ├── inflight-and-close.js
│ ├── infra/
│ │ └── collect-a-sequence-of-code-points.js
│ ├── install.js
│ ├── interceptors/
│ │ ├── cache-async-store.js
│ │ ├── cache-query-params.js
│ │ ├── cache-revalidate-stale.js
│ │ ├── cache.js
│ │ ├── decompress.js
│ │ ├── deduplicate.js
│ │ ├── dns.js
│ │ ├── dump-interceptor.js
│ │ ├── redirect-cross-origin-fix.js
│ │ ├── redirect-issue-3803.js
│ │ ├── redirect.js
│ │ ├── response-error.js
│ │ └── retry.js
│ ├── invalid-headers.js
│ ├── ip-prioritization.js
│ ├── issue-1757.js
│ ├── issue-2065.js
│ ├── issue-2078.js
│ ├── issue-2283.js
│ ├── issue-2349.js
│ ├── issue-2590.js
│ ├── issue-3356.js
│ ├── issue-3410.js
│ ├── issue-3904.js
│ ├── issue-3934.js
│ ├── issue-3959.js
│ ├── issue-4244.js
│ ├── issue-4691.js
│ ├── issue-4806.js
│ ├── issue-4880.js
│ ├── issue-803.js
│ ├── issue-810.js
│ ├── jest/
│ │ ├── instanceof-error.test.js
│ │ ├── issue-1757.test.js
│ │ ├── mock-agent.test.js
│ │ ├── mock-scope.test.js
│ │ ├── parser-timeout.test.js
│ │ ├── test.js
│ │ └── util-timers.test.js
│ ├── max-headers.js
│ ├── max-response-size.js
│ ├── mock-agent.js
│ ├── mock-call-history-log.js
│ ├── mock-call-history.js
│ ├── mock-client.js
│ ├── mock-delayed-abort.js
│ ├── mock-errors.js
│ ├── mock-interceptor-unused-assertions.js
│ ├── mock-interceptor.js
│ ├── mock-pool.js
│ ├── mock-scope.js
│ ├── mock-utils.js
│ ├── no-strict-content-length.js
│ ├── node-fetch/
│ │ ├── LICENSE
│ │ ├── headers.js
│ │ ├── main.js
│ │ ├── mock.js
│ │ ├── request.js
│ │ ├── response.js
│ │ └── utils/
│ │ ├── dummy.txt
│ │ ├── read-stream.js
│ │ └── server.js
│ ├── node-platform-objects.js
│ ├── node-test/
│ │ ├── abort-controller.js
│ │ ├── abort-event-emitter.js
│ │ ├── agent.js
│ │ ├── async_hooks.js
│ │ ├── autoselectfamily.js
│ │ ├── balanced-pool.js
│ │ ├── ca-fingerprint.js
│ │ ├── client-abort.js
│ │ ├── client-connect.js
│ │ ├── client-dispatch.js
│ │ ├── client-errors.js
│ │ ├── debug.js
│ │ ├── diagnostics-channel/
│ │ │ ├── connect-error.js
│ │ │ ├── error.js
│ │ │ ├── get-h2.js
│ │ │ ├── get.js
│ │ │ ├── post-stream.js
│ │ │ └── post.js
│ │ ├── large-body.js
│ │ ├── tree.js
│ │ ├── unix.js
│ │ ├── util.js
│ │ └── validations.js
│ ├── parser-issues.js
│ ├── pipeline-pipelining.js
│ ├── pool-connection-error-memory-leak.js
│ ├── pool.js
│ ├── promises.js
│ ├── proxy-agent.js
│ ├── proxy.js
│ ├── readable.js
│ ├── redirect-pipeline.js
│ ├── redirect-request.js
│ ├── redirect-stream.js
│ ├── request-crlf.js
│ ├── request-signal.js
│ ├── request-timeout.js
│ ├── request-timeout2.js
│ ├── request.js
│ ├── retry-agent.js
│ ├── retry-handler.js
│ ├── retry-handler2.js
│ ├── round-robin-pool.js
│ ├── snapshot-recorder.js
│ ├── snapshot-redirect-interceptor.js
│ ├── snapshot-testing.js
│ ├── socket-back-pressure.js
│ ├── socket-timeout.js
│ ├── socks5-client.js
│ ├── socks5-proxy-agent.js
│ ├── socks5-utils.js
│ ├── stream-compat.js
│ ├── subresource-integrity/
│ │ ├── apply-algorithm-to-bytes.js
│ │ ├── bytes-match.js
│ │ ├── case-sensitive-match.js
│ │ ├── get-strongest-metadata.js
│ │ ├── is-valid-sri-hash-algorithm.js
│ │ └── parse-metadata.js
│ ├── sync-error-in-callback.js
│ ├── timers.js
│ ├── tls-cert-leak.js
│ ├── tls-session-reuse.js
│ ├── tls.js
│ ├── trailers.js
│ ├── types/
│ │ ├── agent.test-d.ts
│ │ ├── api.test-d.ts
│ │ ├── balanced-pool.test-d.ts
│ │ ├── cache-interceptor.test-d.ts
│ │ ├── cache-storage.test-d.ts
│ │ ├── client.test-d.ts
│ │ ├── connector.test-d.ts
│ │ ├── diagnostics-channel.test-d.ts
│ │ ├── dispatcher.events.test-d.ts
│ │ ├── dispatcher.test-d.ts
│ │ ├── dns-interceptor.test-d.ts
│ │ ├── env-http-proxy-agent.test-d.ts
│ │ ├── errors.test-d.ts
│ │ ├── event-source-d.ts
│ │ ├── fetch.test-d.ts
│ │ ├── formdata.test-d.ts
│ │ ├── global-dispatcher.test-d.ts
│ │ ├── header.test-d.ts
│ │ ├── index.test-d.ts
│ │ ├── mock-agent.test-d.ts
│ │ ├── mock-call-history.test-d.ts
│ │ ├── mock-client.test-d.ts
│ │ ├── mock-errors.test-d.ts
│ │ ├── mock-interceptor.test-d.ts
│ │ ├── mock-pool.test-d.ts
│ │ ├── pool.test-d.ts
│ │ ├── proxy-agent.test-d.ts
│ │ ├── readable.test-d.ts
│ │ ├── retry-agent.test-d.ts
│ │ ├── retry-handler.test-d.ts
│ │ ├── snapshot-agent.test-d.ts
│ │ ├── util.test-d.ts
│ │ └── websocket.test-d.ts
│ ├── upgrade-crlf.js
│ ├── util.js
│ ├── utils/
│ │ ├── async-iterators.js
│ │ ├── date.js
│ │ ├── esm-wrapper.mjs
│ │ ├── event-loop-blocker.js
│ │ ├── formdata.js
│ │ ├── hello-world-server.js
│ │ ├── node-http.js
│ │ ├── redirecting-servers.js
│ │ └── stream.js
│ ├── web-platform-tests/
│ │ ├── expectation.json
│ │ ├── runner/
│ │ │ ├── certs/
│ │ │ │ ├── cacert.key
│ │ │ │ ├── cacert.pem
│ │ │ │ ├── web-platform.test.key
│ │ │ │ └── web-platform.test.pem
│ │ │ ├── config.json
│ │ │ ├── test-runner.mjs
│ │ │ └── utils.mjs
│ │ └── wpt-runner.mjs
│ ├── webidl/
│ │ ├── converters.js
│ │ ├── errors.js
│ │ ├── helpers.js
│ │ └── util.js
│ └── websocket/
│ ├── client-received-masked-frame.js
│ ├── close-invalid-status-code.js
│ ├── close-invalid-utf-8.js
│ ├── close.js
│ ├── constructor.js
│ ├── continuation-frames.js
│ ├── custom-headers.js
│ ├── diagnostics-channel-handshake-response.js
│ ├── diagnostics-channel-open-close.js
│ ├── diagnostics-channel-ping-pong.js
│ ├── events.js
│ ├── fragments.js
│ ├── frame.js
│ ├── issue-2679.js
│ ├── issue-2844.js
│ ├── issue-2859.js
│ ├── issue-3202.js
│ ├── issue-3506.js
│ ├── issue-3546.js
│ ├── issue-3697-2399493917.js
│ ├── issue-4273.js
│ ├── issue-4487.js
│ ├── issue-4628.js
│ ├── issue-4889.js
│ ├── messageevent.js
│ ├── opening-handshake.js
│ ├── permessage-deflate-limit.js
│ ├── permessage-deflate-windowbits.js
│ ├── ping-pong.js
│ ├── ping-util.js
│ ├── receive.js
│ ├── receiver-unit.js
│ ├── send-mutable.js
│ ├── send.js
│ ├── stream/
│ │ └── readable-closed-after-close.js
│ ├── util.js
│ └── websocketinit.js
└── types/
├── README.md
├── agent.d.ts
├── api.d.ts
├── balanced-pool.d.ts
├── cache-interceptor.d.ts
├── cache.d.ts
├── client-stats.d.ts
├── client.d.ts
├── connector.d.ts
├── content-type.d.ts
├── cookies.d.ts
├── diagnostics-channel.d.ts
├── dispatcher.d.ts
├── env-http-proxy-agent.d.ts
├── errors.d.ts
├── eventsource.d.ts
├── fetch.d.ts
├── formdata.d.ts
├── global-dispatcher.d.ts
├── global-origin.d.ts
├── h2c-client.d.ts
├── handlers.d.ts
├── header.d.ts
├── index.d.ts
├── interceptors.d.ts
├── mock-agent.d.ts
├── mock-call-history.d.ts
├── mock-client.d.ts
├── mock-errors.d.ts
├── mock-interceptor.d.ts
├── mock-pool.d.ts
├── patch.d.ts
├── pool-stats.d.ts
├── pool.d.ts
├── proxy-agent.d.ts
├── readable.d.ts
├── retry-agent.d.ts
├── retry-handler.d.ts
├── round-robin-pool.d.ts
├── snapshot-agent.d.ts
├── socks5-proxy-agent.d.ts
├── util.d.ts
├── utility.d.ts
├── webidl.d.ts
└── websocket.d.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .c8rc.json
================================================
{
"all": true,
"reporter": [
"lcov",
"text",
"html",
"text-summary"
],
"include": [
"lib/**/*.js",
"index.js"
]
}
================================================
FILE: .dockerignore
================================================
# Ignore everything but the stuff following the `*` with the `!`
# See https://docs.docker.com/engine/reference/builder/#dockerignore-file
*
!package.json
!lib
!deps
!build
================================================
FILE: .editorconfig
================================================
# https://editorconfig.org/
root = true
[*]
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.md
================================================
---
name: Bug Report
about: Report an issue
title: ''
labels: bug
assignees: ''
---
## Bug Description
<!-- A clear and concise description of what the bug is. -->
## Reproducible By
<!-- A step by step list on how the bug can be reproduced for examination. -->
## Expected Behavior
<!-- A clear and concise description of what you expected to happen. -->
## Logs & Screenshots
<!-- If applicable, add screenshots to help explain your problem, or
alternatively add your console logs here. -->
## Environment
<!-- This is just your OS and environment information [e.g. Ubuntu 18.04 LTS,
Node v14.14.0] -->
### Additional context
<!-- Add any other context about the problem here. -->
================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.md
================================================
---
name: Feature Request
about: Make a suggestion on a feature or improvement for the project
title: ''
labels: enhancement
assignees: ''
---
## This would solve...
<!-- A clear and concise description of the problem this feature request relates
to, if applicable. -->
## The implementation should look like...
<!-- A clear and concise description of how you expect this to be resolved or
implemented. -->
## I have also considered...
<!-- A clear and concise description of any alternative solutions or features
you have considered. -->
## Additional context
<!-- Add any other context, screenshots or ideas about the feature request
here. -->
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--
Before submitting a Pull Request, please read our contribution guidelines, which
can be found at CONTRIBUTING.md in the repository root.
For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that tests and linting pass.
You will also need to ensure that your contribution complies with the
Developer's Certificate of Origin, outlined in CONTRIBUTING.md
-->
## This relates to...
<!-- List the issues this resolves or relates to here (if applicable) -->
## Rationale
<!-- Briefly explain the purpose of this pull request, if not already
justifiable with the above section. If it is, you may omit this section. -->
## Changes
<!-- Write a summary or list of changes here -->
### Features
<!-- List the new features here (if applicable), or write N/A if not -->
### Bug Fixes
<!-- List the fixed bugs here (if applicable), or write N/A if not -->
### Breaking Changes and Deprecations
<!-- List the breaking changes (changes that modify the existing API) and
deprecations (removed features) here -->
## Status
<!-- KEY: S = Skipped, x = complete -->
- [ ] I have read and agreed to the [Developer's Certificate of Origin][cert]
- [ ] Tested
- [ ] Benchmarked (**optional**)
- [ ] Documented
- [ ] Review ready
- [ ] In review
- [ ] Merge ready
[cert]: https://github.com/nodejs/undici/blob/main/CONTRIBUTING.md#developers-certificate-of-origin
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 10
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "npm"
directory: /docs
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "npm"
directory: /benchmarks
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: docker
directory: /build
schedule:
interval: daily
================================================
FILE: .github/workflows/autobahn.yml
================================================
name: Autobahn
on:
workflow_dispatch:
workflow_call:
inputs:
node-version:
default: '24'
type: string
pull_request:
paths:
- '.github/workflows/autobahn.yml'
- 'lib/web/websocket/**'
- 'test/autobahn/**'
permissions:
contents: read
jobs:
autobahn:
name: Autobahn Test Suite
runs-on: ubuntu-latest
container: node:24
services:
fuzzingserver:
image: crossbario/autobahn-testsuite:latest
ports:
- '9001:9001'
options: --name fuzzingserver
volumes:
- ${{ github.workspace }}/test/autobahn/config:/config
- ${{ github.workspace }}/test/autobahn/reports:/reports
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
clean: false
- name: Restart Autobahn Server
# Restart service after volumes have been checked out
uses: docker://docker
with:
args: docker restart --time 0 --signal=SIGKILL fuzzingserver
- name: Setup Node.js@${{ inputs.node-version }}
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ inputs.node-version }}
- name: Run Autobahn Test Suite
run: npm run test:websocket:autobahn
env:
FUZZING_SERVER_URL: ws://fuzzingserver:9001
LOG_ON_ERROR: false
- name: Report CI
id: report-ci
run: npm run test:websocket:autobahn:report
env:
FAIL_ON_ERROR: true
================================================
FILE: .github/workflows/backport.yml
================================================
name: Backport
on:
pull_request_target:
types:
- closed
- labeled
jobs:
backport:
name: Backport
runs-on: ubuntu-latest
if: >
github.event.pull_request.merged
&& (
github.event.action == 'closed'
|| (
github.event.action == 'labeled'
&& contains(github.event.label.name, 'backport')
)
)
permissions:
pull-requests: write
contents: write
steps:
- name: Backport
uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e # v2.0.4
id: backport
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/bench.yml
================================================
name: Benchmarks
on:
push:
branches:
- main
- current
- next
- 'v*'
pull_request:
permissions:
contents: read
jobs:
benchmark_current:
name: benchmark current
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ github.base_ref }}
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
- name: Install Modules for undici
run: npm i --ignore-scripts --omit=dev
- name: Install Modules for Benchmarks
run: npm i
working-directory: ./benchmarks
- name: Run Benchmark
run: npm run bench
working-directory: ./benchmarks
benchmark_branch:
name: benchmark branch
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
- name: Install Modules for undici
run: npm i --ignore-scripts --omit=dev
- name: Install Modules for Benchmarks
run: npm i
working-directory: ./benchmarks
- name: Run Benchmark
run: npm run bench
working-directory: ./benchmarks
benchmark_post_current:
name: benchmark (sending data) current
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ github.base_ref }}
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
- name: Install Modules for undici
run: npm i --ignore-scripts --omit=dev
- name: Install Modules for Benchmarks
run: npm i
working-directory: ./benchmarks
- name: Run Benchmark
run: npm run bench-post
working-directory: ./benchmarks
benchmark_post_branch:
name: benchmark (sending data) branch
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
- name: Install Modules for undici
run: npm i --ignore-scripts --omit=dev
- name: Install Modules for Benchmarks
run: npm i
working-directory: ./benchmarks
- name: Run Benchmark
run: npm run bench-post
working-directory: ./benchmarks
benchmark_current_h2:
name: benchmark current h2
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: ${{ github.base_ref }}
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
- name: Install Modules for undici
run: npm i --ignore-scripts --omit=dev
- name: Install Modules for Benchmarks
run: npm i
working-directory: ./benchmarks
- name: Run Benchmark
run: npm run bench:h2
working-directory: ./benchmarks
benchmark_branch_h2:
name: benchmark branch h2
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
- name: Install Modules for undici
run: npm i --ignore-scripts --omit=dev
- name: Install Modules for Benchmarks
run: npm i
working-directory: ./benchmarks
- name: Run Benchmark
run: npm run bench:h2
working-directory: ./benchmarks
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches:
- main
- current
- next
- 'v*'
pull_request:
permissions:
contents: read
jobs:
dependency-review:
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1
with:
egress-policy: audit
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Dependency Review
uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # v4.8.1
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
# Using `latest` as `lts` could point to previous major version.
# Different versions of Node.js can cause different linting results
# (e.g. dependening on process.getBuiltinModule())
node-version: 'latest'
- name: Install dependencies
run: npm install
- name: Lint
run: npm run lint
test:
name: Test ${{ matrix.node-version == '24' && matrix.runs-on == 'ubuntu-latest' && 'and Coverage ' || ''}}with Node.js ${{ matrix.node-version }} on ${{ matrix.runs-on }}
strategy:
fail-fast: false
max-parallel: 0
matrix:
node-version: ['20', '22', '24', '25']
runs-on: ['ubuntu-latest', 'windows-latest', 'macos-latest']
exclude:
- node-version: '20'
runs-on: windows-latest
uses: ./.github/workflows/nodejs.yml
with:
# Disable coverage on Node.js 25 until https://github.com/nodejs/node/issues/61971 is resolved.
codecov: ${{ matrix.node-version == '24' && matrix.runs-on == 'ubuntu-latest' }}
node-version: ${{ matrix.node-version }}
runs-on: ${{ matrix.runs-on }}
secrets: inherit
test-with-no-wasm-simd:
name: Test with Node.js ${{ matrix.node-version }} on ${{ matrix.runs-on }} with WASM SIMD disabled
strategy:
fail-fast: false
max-parallel: 0
matrix:
node-version: ['24', '25']
runs-on: ['ubuntu-latest']
uses: ./.github/workflows/nodejs.yml
with:
node-version: ${{ matrix.node-version }}
runs-on: ${{ matrix.runs-on }}
no-wasm-simd: '1'
secrets: inherit
test-without-intl:
name: Test with Node.js ${{ matrix.node-version }} compiled --without-intl
strategy:
fail-fast: false
max-parallel: 0
matrix:
node-version: ['20', '22', '24', '25']
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
submodules: recursive
# Setup node, install deps, and build undici prior to building icu-less node and testing
- name: Setup Node.js@${{ matrix.node-version }}
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Build undici
run: npm run build:node
- name: Determine latest release
id: release
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
result-encoding: string
script: |
const req = await fetch('https://nodejs.org/download/release/index.json')
const releases = await req.json()
const latest = releases.find((r) => r.version.startsWith('v${{ matrix.node-version }}'))
return latest.version
- name: Download and extract source
run: curl https://nodejs.org/download/release/${{ steps.release.outputs.result }}/node-${{ steps.release.outputs.result }}.tar.xz | tar xfJ -
- name: Install ninja
run: sudo apt-get install ninja-build
- name: ccache
uses: hendrikmuhs/ccache-action@bfa03e1de4d7f7c3e80ad9109feedd05c4f5a716 #v1.2.19
with:
key: node${{ matrix.node-version }}
- name: Build node
working-directory: ./node-${{ steps.release.outputs.result }}
run: |
export CC="ccache gcc"
export CXX="ccache g++"
./configure --without-intl --ninja --prefix=./final
make
make install
echo "$(pwd)/final/bin" >> $GITHUB_PATH
- name: Print version information
run: |
echo OS: $(node -p "os.version()")
echo Node.js: $(node --version)
echo "Node.js built-in dependencies: $(node -p "'\r\n' + (Object.entries(process.versions).map(([k, v], i, arr) => (i !== arr.length - 1 ? '├──' : '└──') + k + '@' + v)).join('\r\n')")"
echo npm: $(npm --version)
echo git: $(git --version)
echo icu config: $(node -e "console.log(process.config)" | grep icu)
- name: Configure hosts file for WPT (Windows)
if: runner.os == 'Windows'
run: |
cd ${{ github.workspace }}\test\web-platform-tests\wpt
python wpt make-hosts-file | Out-File $env:SystemRoot\System32\drivers\etc\hosts -Encoding ascii -Append
shell: powershell
- name: Configure hosts file for WPT (Unix)
if: runner.os != 'Windows'
run: |
cd ${{ github.workspace }}/test/web-platform-tests/wpt
python3 wpt make-hosts-file | sudo tee -a /etc/hosts
- name: Run tests
run: npm run test:javascript:without-intl
test-without-ssl:
name: Test with Node.js ${{ matrix.node-version }} compiled --without-ssl
strategy:
fail-fast: false
max-parallel: 0
matrix:
node-version: ['20', '22', '24', '25']
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
submodules: recursive
# Setup node, install deps, and build undici prior to building icu-less node and testing
- name: Setup Node.js@${{ matrix.node-version }}
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install
- name: Build undici
run: npm run build:node
- name: Determine latest release
id: release
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
result-encoding: string
script: |
const req = await fetch('https://nodejs.org/download/release/index.json')
const releases = await req.json()
const latest = releases.find((r) => r.version.startsWith('v${{ matrix.node-version }}'))
return latest.version
- name: Download and extract source
run: curl https://nodejs.org/download/release/${{ steps.release.outputs.result }}/node-${{ steps.release.outputs.result }}.tar.xz | tar xfJ -
- name: Install ninja
run: sudo apt-get install ninja-build
- name: ccache
uses: hendrikmuhs/ccache-action@bfa03e1de4d7f7c3e80ad9109feedd05c4f5a716 #v1.2.19
with:
key: node${{ matrix.node-version }}
- name: Build node
working-directory: ./node-${{ steps.release.outputs.result }}
run: |
export CC="ccache gcc"
export CXX="ccache g++"
./configure --without-ssl --ninja --prefix=./final
make
make install
echo "$(pwd)/final/bin" >> $GITHUB_PATH
- name: Print version information
run: |
echo OS: $(node -p "os.version()")
echo Node.js: $(node --version)
echo "Node.js built-in dependencies: $(node -p "'\r\n' + (Object.entries(process.versions).map(([k, v], i, arr) => (i !== arr.length - 1 ? '├──' : '└──') + k + '@' + v)).join('\r\n')")"
echo npm: $(npm --version)
echo git: $(git --version)
echo icu config: $(node -e "console.log(process.config)" | grep icu)
- name: Try loading Node.js without Crypto
run: node index.js
test-fuzzing:
name: Fuzzing
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: lts/*
- name: Install dependencies
run: npm install
- name: Run fuzzing tests
run: npm run test:fuzzing
test-shared-builtin:
name: Test with Node.js ${{ matrix.node-version }} compiled --shared-builtin-undici/undici-path
uses: ./.github/workflows/nodejs-shared.yml
strategy:
fail-fast: false
max-parallel: 0
matrix:
node-version: ['24', '25']
runs-on: ['ubuntu-latest']
with:
node-version: ${{ matrix.node-version }}
test-types:
name: Test TypeScript types
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: lts/*
- name: Install dependencies
run: npm install
- name: Run typings tests
run: npm run test:typescript
automerge:
if: >
github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]'
needs:
- dependency-review
- test
- test-types
- test-with-no-wasm-simd
- test-without-intl
- test-fuzzing
- lint
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Merge Dependabot PR
uses: fastify/github-action-merge-dependabot@1b2ed42db8f9d81a46bac83adedfc03eb5149dff # v3.11.2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: ["main"]
pull_request:
# The branches below must be a subset of the branches above
branches: ["main"]
schedule:
- cron: "0 0 * * 1"
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["javascript", "typescript"]
# CodeQL supports [ $supported-codeql-languages ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Harden Runner
uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # v2.3.3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@9e907b5e64f6b83e7804b09294d44122997950d6 # v2.3.3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # v2.3.3
with:
category: "/language:${{matrix.language}}"
================================================
FILE: .github/workflows/nodejs-nightly.yml
================================================
name: Node.js Nightly
on:
workflow_dispatch:
schedule:
- cron: "0 10 * * *"
permissions:
contents: read
jobs:
test:
name: Test with Node.js ${{ matrix.node-version }} on ${{ matrix.runs-on }}
if: github.repository == 'nodejs/undici'
strategy:
fail-fast: false
max-parallel: 0
matrix:
node-version: ['25-nightly']
runs-on: [ubuntu-latest, windows-latest, macos-latest]
uses: ./.github/workflows/nodejs.yml
with:
node-version: ${{ matrix.node-version }}
runs-on: ${{ matrix.runs-on }}
secrets: inherit
autobahn:
if: github.repository == 'nodejs/undici'
uses: ./.github/workflows/autobahn.yml
with:
node-version: '25-nightly'
secrets: inherit
test-shared-builtin:
if: github.repository == 'nodejs/undici'
uses: ./.github/workflows/nodejs-shared.yml
with:
node-version: '25'
node-download-server-path: '/nightly'
report-failure:
if: ${{ always() && (needs.test.result == 'failure' || needs.test-shared-builtin.result == 'failure' || needs.autobahn.result == 'failure') }}
needs:
- test
- test-shared-builtin
- autobahn
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Create or update issue
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const ISSUE_TITLE = "Nightly tests are failing"
const actionRunUrl = "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
const issueContext = {
owner: context.repo.owner,
repo: context.repo.repo
}
let issue = (await github.rest.issues.listForRepo({
state: "open",
creator: "github-actions[bot]",
...issueContext
})).data.find((issue) => issue.title === ISSUE_TITLE)
if(!issue) {
issue = (await github.rest.issues.create({
title: ISSUE_TITLE,
body: `Tests against nightly failed, see: ${actionRunUrl}`,
...issueContext
})).data
}
================================================
FILE: .github/workflows/nodejs-shared.yml
================================================
name: Node.js compiled --shared-builtin-undici/undici-path CI
on:
workflow_call:
inputs:
node-version:
required: true
type: string
node-download-server-path:
required: false
type: string
default: '/release'
permissions:
contents: read
jobs:
test-shared-builtin:
name: Test with Node.js ${{ inputs.node-version }} compiled --shared-builtin-undici/undici-path
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
# Checkout into a subdirectory otherwise Node.js tests will break due to finding Undici's package.json in a parent directory.
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: ./undici
persist-credentials: false
# Setup node, install deps, and build undici prior to building node with `--shared-builtin-undici/undici-path` and testing
- name: Setup Node.js lts/*
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
- name: Install dependencies
working-directory: ./undici
run: npm install
- name: Install wasi-libc
run: sudo apt-get install -y wasi-libc binaryen
- name: Build WASM
working-directory: ./undici
run: |
export EXTERNAL_PATH=${{ github.workspace }}/undici
export WASM_CC=clang
export WASM_CFLAGS='--target=wasm32-wasi --sysroot=/usr'
export WASM_LDFLAGS='-nodefaultlibs'
export WASM_LDLIBS='-lc'
node build/wasm.js
- name: Determine latest release for Node.js ${{ inputs.node-version }}
id: release
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
result-encoding: string
script: |
const req = await fetch('https://nodejs.org/download${{ inputs.node-download-server-path }}/index.json')
const releases = await req.json()
const latest = releases.find((r) => r.version.startsWith('v${{ inputs.node-version }}'))
return latest.version
- name: Download and extract source for Node.js ${{ steps.release.outputs.result }}
run: curl https://nodejs.org/download${{ inputs.node-download-server-path }}/${{ steps.release.outputs.result }}/node-${{ steps.release.outputs.result }}.tar.xz | tar xfJ -
- name: Install ninja
run: sudo apt-get install ninja-build
- name: ccache
uses: hendrikmuhs/ccache-action@bfa03e1de4d7f7c3e80ad9109feedd05c4f5a716 #v1.2.19
with:
key: node(external_undici)${{ inputs.node-version }}
- name: Build node ${{ steps.release.outputs.result }} with --shared-builtin-undici/undici-path
working-directory: ./node-${{ steps.release.outputs.result }}
run: |
export CC="ccache gcc"
export CXX="ccache g++"
rm -rf deps/undici
./configure --shared-builtin-undici/undici-path ${{ github.workspace }}/undici/loader.js --ninja --prefix=./final
make
make install
echo "$(pwd)/final/bin" >> $GITHUB_PATH
- name: Print version information
run: |
echo OS: $(node -p "os.version()")
echo Node.js: $(node --version)
echo "Node.js built-in dependencies: $(node -p "'\r\n' + (Object.entries(process.versions).map(([k, v], i, arr) => (i !== arr.length - 1 ? '├──' : '└──') + k + '@' + v)).join('\r\n')")"
echo npm: $(npm --version)
echo git: $(git --version)
echo external config: $(node -e "console.log(process.config)" | grep NODE_SHARED_BUILTIN_UNDICI_UNDICI_PATH)
echo Node.js built-in undici version: $(node -p "process.versions.undici") # undefined for external Undici
- name: Run tests
working-directory: ./node-${{ steps.release.outputs.result }}
run: tools/test.py -p dots --flaky-tests=dontcare
================================================
FILE: .github/workflows/nodejs.yml
================================================
name: Node.js
on:
workflow_call:
inputs:
node-version:
required: true
type: string
runs-on:
required: true
type: string
codecov:
required: false
type: boolean
default: false
no-wasm-simd:
type: string
required: false
default: ''
permissions:
contents: read
jobs:
test:
name: Test ${{ inputs.codecov == true && 'and Coverage ' || '' }}with Node.js ${{ inputs.node-version }} on ${{ inputs.runs-on }}
timeout-minutes: 20
runs-on: ${{ inputs.runs-on }}
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
submodules: recursive
- name: Setup Node.js@${{ inputs.node-version }}
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: ${{ inputs.node-version }}
- name: Print version information
run: |
echo OS: $(node -p "os.version()")
echo Node.js: $(node --version)
echo "Node.js built-in dependencies: $(node -p "'\r\n' + (Object.entries(process.versions).map(([k, v], i, arr) => (i !== arr.length - 1 ? '├──' : '└──') + k + '@' + v)).join('\r\n')")"
echo npm: $(npm --version)
echo git: $(git --version)
- name: Install dependencies
run: npm install
- name: Print installed dependencies
run: npm ls --all
continue-on-error: true
- name: Configure hosts file for WPT (Windows)
if: runner.os == 'Windows'
run: |
cd ${{ github.workspace }}\test\web-platform-tests\wpt
python wpt make-hosts-file | Out-File $env:SystemRoot\System32\drivers\etc\hosts -Encoding ascii -Append
shell: powershell
- name: Configure hosts file for WPT (Unix)
if: runner.os != 'Windows'
run: |
cd ${{ github.workspace }}/test/web-platform-tests/wpt
python3 wpt make-hosts-file | sudo tee -a /etc/hosts
- name: Generate PEM files
run: npm run generate-pem
id: generate-pem
- name: Test unit
run: npm run test:unit
id: test-unit
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test node-test
run: npm run test:node-test
id: test-node-test
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test fetch
run: npm run test:fetch
id: test-fetch
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test node-fetch
run: npm run test:node-fetch
id: test-node-fetch
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test cache
run: npm run test:cache
id: test-cache
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test cache-interceptor ${{ inputs.node-version != '20' && 'with' || 'without' }} sqlite
run: npm run test:cache-interceptor
id: test-cache-interceptor
env:
CI: true
NODE_OPTIONS: ${{ inputs.node-version != '20' && '--experimental-sqlite' || '' }}
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test cache-tests
run: npm run test:cache-tests
id: test-cache-tests
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test cookies
run: npm run test:cookies
id: test-cookies
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test interceptors
run: npm run test:interceptors
id: test-interceptors
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test eventsource
run: npm run test:eventsource
id: test-eventsource
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test infra
run: npm run test:infra
id: test-infra
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test subresource-integrity
run: npm run test:subresource-integrity
id: test-subresource-integrity
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test websocket
run: npm run test:websocket
id: test-websocket
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test jest
run: npm run test:jest
id: test-jest
env:
CI: true
NODE_V8_COVERAGE: ''
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Test wpt
run: npm run test:wpt
id: test-wpt
env:
CI: true
NODE_V8_COVERAGE: ${{ inputs.codecov == true && './coverage/tmp' || '' }}
UNDICI_NO_WASM_SIMD: ${{ inputs['no-wasm-simd'] }}
- name: Coverage summary
if: inputs.codecov == true
run: npm run coverage:report:ci
id: prepare-coverage-report
- name: Upload coverage report to Codecov
if: inputs.codecov == true
uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
================================================
FILE: .github/workflows/release-create-pr.yml
================================================
name: Create release PR
permissions:
contents: read
on:
workflow_dispatch:
inputs:
version:
description: 'The version number to release (has priority over release_type)'
type: string
release_type:
description: Type of release
type: choice
default: patch
options:
- patch
- minor
- major
jobs:
create-pr:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
outputs:
version: ${{ steps.bump.outputs.version }}
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
id: checkout
with:
persist-credentials: true
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
id: setup-node
with:
node-version: 'lts/*'
- name: Git Config
id: git-config
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Change version number and push
id: bump
run: |
npm version ${{ inputs.version || inputs.release_type }} --git-tag-version=false
VERSION=`jq -r ".version" package.json`
RELEASE_BRANCH="release/v$VERSION"
git add -u
git commit -m "Bumped v$VERSION"
git push origin "HEAD:$RELEASE_BRANCH"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Create PR
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
id: create-pr
with:
script: |
const defaultBranch = "${{ github.event.repository.default_branch }}"
const versionTag = "v${{ steps.bump.outputs.version }}"
const commitHash = "${{ github.sha }}"
await require('./scripts/release').generatePr({ github, context, defaultBranch, versionTag, commitHash })
================================================
FILE: .github/workflows/release.yml
================================================
name: Release undici and undici-types on NPM and create GitHub Release
on:
push:
branches:
- main
paths:
- package.json
permissions:
contents: read
jobs:
determine-release-version:
runs-on: ubuntu-latest
outputs:
release-version: ${{ steps.determine-release-version.outputs.result }}
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
id: checkout
with:
persist-credentials: false
- name: Determine release version
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
id: determine-release-version
with:
result-encoding: string
script: |
const { owner, repo } = context.repo
const version = require("./package.json").version
const versionTag = `v${version}`
const { data: releases } = await github.rest.repos.listReleases({
owner,
repo
})
const previousRelease = releases.find((r) => r.tag_name.startsWith('v7'))
if (versionTag !== previousRelease?.tag_name) {
return versionTag
}
release:
runs-on: ubuntu-latest
needs: determine-release-version
if: ${{ startsWith(needs.determine-release-version.outputs.release-version, 'v') }}
permissions:
contents: write
id-token: write
environment: release
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
id: checkout
with:
persist-credentials: true
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: 'lts/*'
registry-url: 'https://registry.npmjs.org'
- name: Install globally latest npm
run: npm install -g npm@latest
id: install-globally-latest-npm
- name: Install dependencies
run: npm install
id: install-dependencies
- name: Publish undici on NPM
run: npm publish --access public
id: npm-publish-undici
- name: Generate Types Package
run: node scripts/generate-undici-types-package-json.js
id: generate-types-package
- name: Publish undici-types on NPM
run: npm publish
id: npm-publish-undici-types
working-directory: './types'
- name: Create GitHub release
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
id: create-gh-release
with:
script: |
const defaultBranch = "${{ github.event.repository.default_branch }}"
const versionTag = "${{ needs.determine-release-version.outputs.release-version }}"
const commitHash = "${{ github.sha }}"
await require('./scripts/release').release({ github, context, defaultBranch, versionTag, commitHash })
================================================
FILE: .github/workflows/scorecard.yml
================================================
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '16 10 * * 2'
push:
branches: [ "main" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
steps:
- name: "Checkout code"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
results_file: results.sarif
results_format: sarif
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@9e907b5e64f6b83e7804b09294d44122997950d6 # v3.29.5
with:
sarif_file: results.sarif
================================================
FILE: .github/workflows/triggered-autobahn.yml
================================================
name: Autobahn
on:
pull_request:
types:
- labeled
jobs:
autobahn:
if: ${{ github.event.label.name == 'autobahn' }}
name: Autobahn Test Suite
uses: ./.github/workflows/autobahn.yml
================================================
FILE: .github/workflows/update-submodules.yml
================================================
name: Update Submodules
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
jobs:
update-wpt:
name: Update Submodules
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout Repository
id: checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: true
- name: Git Config
id: git-config
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Update Submodules
id: update-submodules
run: |
git submodule update --init --recursive --remote --merge
- name: Check for Changes
id: check-for-changes
run: |
if git diff --quiet; then
echo "no changes detected"
echo "change=false" >> "$GITHUB_OUTPUT"
else
echo "changes detected"
echo "change=true" >> "$GITHUB_OUTPUT"
fi
- name: Create Branch
id: create-branch
if: ${{ steps.check-for-changes.outputs.change == 'true'}}
run: |
git checkout -b submodules-update
git add .
git commit -m "chore: update Submodules"
git push --force --set-upstream origin submodules-update
- name: Create Pull Request
id: create-pr
if: ${{ steps.check-for-changes.outputs.change == 'true'}}
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
base: main
branch: submodules-update
title: Update Submodules
body: Automated update of the Submodules
commit-message: "chore: update Submodules"
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next
# lock files
package-lock.json
yarn.lock
pnpm-lock.yaml
# IDE files
.idea
.vscode
*0x
*clinic*
# Fuzzing
corpus/
crash-*
fuzz-results-*.json
# Bundle output
undici-fetch.js
/test/imports/undici-import.js
# .npmrc has platform specific value for windows
.npmrc
.tap
# File generated by /test/request-timeout.js
test/request-timeout.10mb.bin
# Claude files
CLAUDE.md
.claude
# Ignore .pi
.pi
# Ignore .githuman
.githuman
================================================
FILE: .gitmodules
================================================
[submodule "test/web-platform-tests/wpt"]
path = test/web-platform-tests/wpt
url = https://github.com/web-platform-tests/wpt.git
[submodule "test/fixtures/cache-tests"]
path = test/fixtures/cache-tests
url = https://github.com/http-tests/cache-tests
================================================
FILE: .husky/pre-commit
================================================
npm run lint
================================================
FILE: .npmignore
================================================
*
!lib/**/*
!index.js
!index-fetch.js
# The wasm files are stored as base64 strings in the corresponding .js files
lib/llhttp/llhttp_simd.wasm
lib/llhttp/llhttp.wasm
!types/**/*
!index.d.ts
!docs/docs/**/*
!scripts/strip-comments.js
# File generated by /test/request-timeout.js
test/request-timeout.10mb.bin
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct
Undici is committed to upholding the Node.js Code of Conduct.
The Node.js Code of Conduct document can be found at
https://github.com/nodejs/admin/blob/main/CODE_OF_CONDUCT.md
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Undici
* [Guides](#guides)
* [Update `llhttp`](#update-llhttp)
* [Lint](#lint)
* [Test](#test)
* [Coverage](#coverage)
* [Releases](#releases)
* [Update `WPTs`](#update-wpts)
* [Building for externally shared node builtins](#external-builds)
* [Benchmarks](#benchmarks)
* [Documentation](#documentation)
* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin)
* [Moderation Policy](#moderation-policy)
<a id="guides"></a>
## Guides
This is a collection of guides on how to run and update `undici`, and how to run different parts of the project.
<a id="update-llhttp"></a>
### Update `llhttp`
The HTTP parser used by `undici` is a WebAssembly build of [`llhttp`](https://github.com/nodejs/llhttp).
While the project itself provides a way to compile targeting WebAssembly, at the moment we embed the sources
directly and compile the module in `undici`.
The `deps/llhttp/include` folder contains the C header files, while the `deps/llhttp/src` folder contains
the C source files needed to compile the module.
The `lib/llhttp` folder contains the `.js` transpiled assets required to implement a parser.
The following are the steps required to perform an update.
#### Clone the [llhttp](https://github.com/nodejs/llhttp) project
```bash
git clone git@github.com:nodejs/llhttp.git
cd llhttp
```
#### Checkout a `llhttp` release
```bash
git checkout <tag>
```
#### Install the `llhttp` dependencies
```bash
npm i
```
#### Run the wasm build script
> This requires [docker](https://www.docker.com/) installed on your machine.
```bash
npm run build-wasm
```
#### Copy the sources to `undici`
```bash
cp build/wasm/*.js <your-path-to-undici>/lib/llhttp/
cp build/wasm/*.js.map <your-path-to-undici>/lib/llhttp/
cp build/wasm/*.d.ts <your-path-to-undici>/lib/llhttp/
cp src/native/api.c src/native/http.c build/c/llhttp.c <your-path-to-undici>/deps/llhttp/src/
cp src/native/api.h build/llhttp.h <your-path-to-undici>/deps/llhttp/include/
```
#### Build the WebAssembly module in `undici`
> This requires [docker](https://www.docker.com/) installed on your machine.
```bash
cd <your-path-to-undici>
npm run build:wasm
```
#### Commit the contents of lib/llhttp
Create a commit which includes all of the updated files in lib/llhttp.
<a id="update-wpts"></a>
### Update `WPTs`
`undici` runs a subset of the [`web-platform-tests`](https://github.com/web-platform-tests/wpt).
### Steps:
```bash
git submodule update --init --recursive
```
### Run the tests
Run the tests to ensure that any new failures are marked as such.
Before running the tests for the first time, you must setup the testing environment.
```bash
cd test/web-platform-tests
node wpt-runner.mjs setup
```
To run all tests:
```bash
npm run test:wpt
```
To run a subset of tests:
```bash
cd test/web-platform-tests
node wpt-runner.mjs run [filter] [filterb]
```
To run a single file:
```bash
cd test/web-platform-tests
node wpt-runner.mjs run /path/to/test
```
### Debugging
Verbose logging can be enabled by setting the [`NODE_DEBUG`](https://nodejs.org/api/cli.html#node_debugmodule) flag:
```bash
npx cross-env NODE_DEBUG=UNDICI_WPT node --run test:wpt
```
(`npx cross-env` can be omitted on Linux and Mac)
<a id="lint"></a>
### Lint
```bash
npm run lint
```
<a id="test"></a>
### Test
```bash
npm run test
```
<a id="coverage"></a>
### Coverage
```bash
npm run coverage
```
<a id="releases"></a>
### Issuing Releases
Release is automatic on commit to main which bumps the package.json version field.
Use the "Create release PR" github action to generate a release PR.
<a id="external-builds"></a>
### Building for externally shared node builtins
If you are packaging `undici` for a distro, this might help if you would like to use
an unbundled version instead of bundling one in `libnode.so`.
To enable this, pass `EXTERNAL_PATH=/path/to/global/node_modules/undici` to `build/wasm.js`.
Pass this path with `loader.js` appended to `--shared-builtin-undici/undici-path` in Node.js's `configure.py`.
If building on a non-Alpine Linux distribution, you may need to also set the `WASM_CC`, `WASM_CFLAGS`, `WASM_LDFLAGS` and `WASM_LDLIBS` environment variables before running `build/wasm.js`.
Similarly, you can set the `WASM_OPT` environment variable to utilize your own `wasm-opt` optimizer.
<a id="benchmarks"></a>
### Benchmarks
```bash
cd benchmarks && npm i && npm run bench
```
The benchmarks will be available at `http://localhost:3042`.
<a id="documentation"></a>
### Documentation
```bash
cd docs && npm i && npm run serve
```
The documentation will be available at `http://localhost:3000`.
<a id="developers-certificate-of-origin"></a>
## Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
* (a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
* (b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
* (c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
* (d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
<a id="moderation-policy"></a>
### Moderation Policy
The [Node.js Moderation Policy] applies to this project.
[Node.js Moderation Policy]: https://github.com/nodejs/admin/blob/main/Moderation-Policy.md
================================================
FILE: GOVERNANCE.md
================================================
### Undici Working Group
The Node.js Undici project is governed by a Working Group (WG)
that is responsible for high-level guidance of the project.
The WG has final authority over this project including:
* Technical direction
* Project governance and process (including this policy)
* Contribution policy
* GitHub repository hosting
* Conduct guidelines
* Maintaining the list of additional Collaborators
For the current list of WG members, see the project
[README.md](./README.md#collaborators).
### Collaborators
The undici GitHub repository is
maintained by the WG and additional Collaborators who are added by the
WG on an ongoing basis.
Individuals making significant and valuable contributions are made
Collaborators and given commit-access to the project. These
individuals are identified by the WG and their addition as
Collaborators is discussed during the WG meeting.
_Note:_ If you make a significant contribution and are not considered
for commit-access log an issue or contact a WG member directly and it
will be brought up in the next WG meeting.
Modifications of the contents of the undici repository are
made on
a collaborative basis. Anybody with a GitHub account may propose a
modification via pull request and it will be considered by the project
Collaborators. All pull requests must be reviewed and accepted by a
Collaborator with sufficient expertise who is able to take full
responsibility for the change. In the case of pull requests proposed
by an existing Collaborator, an additional Collaborator is required
for sign-off. Consensus should be sought if additional Collaborators
participate and there is disagreement around a particular
modification. See _Consensus Seeking Process_ below for further detail
on the consensus model used for governance.
Collaborators may opt to elevate significant or controversial
modifications, or modifications that have not found consensus to the
WG for discussion by assigning the ***WG-agenda*** tag to a pull
request or issue. The WG should serve as the final arbiter where
required.
For the current list of Collaborators, see the project
[README.md](./README.md#collaborators). The list should be in
alphabetical order.
### WG Membership
WG seats are not time-limited. There is no fixed size of the WG.
However, the expected target is between 6 and 12, to ensure adequate
coverage of important areas of expertise, balanced with the ability to
make decisions efficiently.
There is no specific set of requirements or qualifications for WG
membership beyond these rules.
The WG may add additional members to the WG by unanimous consensus.
A WG member may be removed from the WG by voluntary resignation, or by
unanimous consensus of all other WG members.
Changes to WG membership should be posted in the agenda, and may be
suggested as any other agenda item (see "WG Meetings" below).
If an addition or removal is proposed during a meeting, and the full
WG is not in attendance to participate, then the addition or removal
is added to the agenda for the subsequent meeting. This is to ensure
that all members are given the opportunity to participate in all
membership decisions. If a WG member is unable to attend a meeting
where a planned membership decision is being made, then their consent
is assumed.
No more than 1/3 of the WG members may be affiliated with the same
employer. If removal or resignation of a WG member, or a change of
employment by a WG member, creates a situation where more than 1/3 of
the WG membership shares an employer, then the situation must be
immediately remedied by the resignation or removal of one or more WG
members affiliated with the over-represented employer(s).
### WG Meetings
The WG meets occasionally on Zoom. A designated moderator
approved by the WG runs the meeting. Each meeting should be
published to YouTube.
Items are added to the WG agenda that are considered contentious or
are modifications of governance, contribution policy, WG membership,
or release process.
The intention of the agenda is not to approve or review all patches;
that should happen continuously on GitHub and be handled by the larger
group of Collaborators.
Any community member or contributor can ask that something be added to
the next meeting's agenda by logging a GitHub Issue. Any Collaborator,
WG member or the moderator can add the item to the agenda by adding
the ***WG-agenda*** tag to the issue.
Prior to each WG meeting the moderator will share the Agenda with
members of the WG. WG members can add any items they like to the
agenda at the beginning of each meeting. The moderator and the WG
cannot veto or remove items.
The WG may invite persons or representatives from certain projects to
participate in a non-voting capacity.
The moderator is responsible for summarizing the discussion of each
agenda item and sends it as a pull request after the meeting.
### Consensus Seeking Process
The WG follows a
[Consensus
Seeking](http://en.wikipedia.org/wiki/Consensus-seeking_decision-making)
decision-making model.
When an agenda item has appeared to reach a consensus the moderator
will ask "Does anyone object?" as a final call for dissent from the
consensus.
If an agenda item cannot reach a consensus a WG member can call for
either a closing vote or a vote to table the issue to the next
meeting. The call for a vote must be seconded by a majority of the WG
or else the discussion will continue. Simple majority wins.
Note that changes to WG membership require a majority consensus. See
"WG Membership" above.
================================================
FILE: LICENSE
================================================
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.
================================================
FILE: MAINTAINERS.md
================================================
# Maintainers
This document details any and all processes relevant to project maintainers. Maintainers should feel empowered to contribute back to this document with any process changes they feel improve the overall experience for themselves and other maintainers.
## Labels
Maintainers are encouraged to use the extensive and detailed list of labels for easier repo management.
* Generally, all issues should be labelled. The most general labels are `bug`, `enhancement`, and `Status: help-wanted`.
* Issues specific to a certain aspect of the project should be labeled using one of the specificity labels listed below. For example, a bug in the `Client` class should have the `Client` and `bug` label assigned.
* Specificity labels:
* `Agent`
* `Client`
* `Docs`
* `Performance`
* `Pool`
* `Tests`
* `Types`
* Any `question` or `usage help` issues should be converted into Q&A Discussions
* `Status:` labels should be added to all open issues indicating their relative development status.
* Status labels:
* `Status: blocked`
* `Status: help-wanted`
* `Status: in-progress`
* `Status: wontfix`
* Issues and/or pull requests with an agreed upon semver status can be assigned the appropriate `semver-` label.
* Semver labels:
* `semver-major`
* `semver-minor`
* `semver-patch`
* Issues with a low-barrier of entry should be assigned the `good first issue` label.
* Do not use the `invalid` label, instead use `bug` or `Status: wontfix`.
* Duplicate issues should initially be assigned the `duplicate` label.
## Making a Release
1. Go to github actions, then select ["Create Release PR"](https://github.com/nodejs/undici/actions/workflows/release-create-pr.yml).
2. Run the workflow, selecting `main` and indicating if you want a specific version number or a patch/minor/major release
3. Wait for the PR to be created. Approve the PR ([this](https://github.com/nodejs/undici/pull/4021) is a an example).
4. Land the PR, wait for the CI to pass.
5. Got to the ["Release"](https://github.com/nodejs/undici/actions/workflows/release.yml) workflow, you should see a job waiting.
6. If you are one of the [releases](https://github.com/nodejs/undici?tab=readme-ov-file#releasers), then click "review deployments", then select "release" and click "approve and deploy". If you are not a releaser, contact one.
================================================
FILE: README.md
================================================
# undici
[](https://github.com/nodejs/undici/actions/workflows/nodejs.yml) [](https://github.com/neostandard/neostandard) [](https://badge.fury.io/js/undici) [](https://codecov.io/gh/nodejs/undici)
An HTTP/1.1 client, written from scratch for Node.js.
> Undici means eleven in Italian. 1.1 -> 11 -> Eleven -> Undici.
It is also a Stranger Things reference.
## How to get involved
Have a question about using Undici? Open a [Q&A Discussion](https://github.com/nodejs/undici/discussions/new) or join our official OpenJS [Slack](https://openjs-foundation.slack.com/archives/C01QF9Q31QD) channel.
Looking to contribute? Start by reading the [contributing guide](./CONTRIBUTING.md)
## Install
```
npm i undici
```
## Benchmarks
The benchmark is a simple getting data [example](https://github.com/nodejs/undici/blob/main/benchmarks/benchmark.js) using a
50 TCP connections with a pipelining depth of 10 running on Node 22.11.0.
```
┌────────────────────────┬─────────┬────────────────────┬────────────┬─────────────────────────┐
│ Tests │ Samples │ Result │ Tolerance │ Difference with slowest │
├────────────────────────┼─────────┼────────────────────┼────────────┼─────────────────────────┤
│ 'axios' │ 15 │ '5708.26 req/sec' │ '± 2.91 %' │ '-' │
│ 'http - no keepalive' │ 10 │ '5809.80 req/sec' │ '± 2.30 %' │ '+ 1.78 %' │
│ 'request' │ 30 │ '5828.80 req/sec' │ '± 2.91 %' │ '+ 2.11 %' │
│ 'undici - fetch' │ 40 │ '5903.78 req/sec' │ '± 2.87 %' │ '+ 3.43 %' │
│ 'node-fetch' │ 10 │ '5945.40 req/sec' │ '± 2.13 %' │ '+ 4.15 %' │
│ 'got' │ 35 │ '6511.45 req/sec' │ '± 2.84 %' │ '+ 14.07 %' │
│ 'http - keepalive' │ 65 │ '9193.24 req/sec' │ '± 2.92 %' │ '+ 61.05 %' │
│ 'superagent' │ 35 │ '9339.43 req/sec' │ '± 2.95 %' │ '+ 63.61 %' │
│ 'undici - pipeline' │ 50 │ '13364.62 req/sec' │ '± 2.93 %' │ '+ 134.13 %' │
│ 'undici - stream' │ 95 │ '18245.36 req/sec' │ '± 2.99 %' │ '+ 219.63 %' │
│ 'undici - request' │ 50 │ '18340.17 req/sec' │ '± 2.84 %' │ '+ 221.29 %' │
│ 'undici - dispatch' │ 40 │ '22234.42 req/sec' │ '± 2.94 %' │ '+ 289.51 %' │
└────────────────────────┴─────────┴────────────────────┴────────────┴─────────────────────────┘
```
## Undici vs. Fetch
### Overview
Node.js includes a built-in `fetch()` implementation powered by undici starting from Node.js v18. However, there are important differences between using the built-in fetch and installing undici as a separate module.
### Built-in Fetch (Node.js v18+)
Node.js's built-in fetch is powered by a bundled version of undici:
```js
// Available globally in Node.js v18+
const response = await fetch('https://api.example.com/data');
const data = await response.json();
// Check the bundled undici version
console.log(process.versions.undici); // e.g., "5.28.4"
```
**Pros:**
- No additional dependencies required
- Works across different JavaScript runtimes
- Automatic compression handling (gzip, deflate, br)
- Built-in caching support (in development)
**Cons:**
- Limited to the undici version bundled with your Node.js version
- Less control over connection pooling and advanced features
- Error handling follows Web API standards (errors wrapped in `TypeError`)
- Performance overhead due to Web Streams implementation
### Undici Module
Installing undici as a separate module gives you access to the latest features and APIs:
```bash
npm install undici
```
```js
import { request, fetch, Agent, setGlobalDispatcher } from 'undici';
// Use undici.request for maximum performance
const { statusCode, headers, body } = await request('https://api.example.com/data');
const data = await body.json();
// Or use undici.fetch with custom configuration
const agent = new Agent({ keepAliveTimeout: 10000 });
setGlobalDispatcher(agent);
const response = await fetch('https://api.example.com/data');
```
**Pros:**
- Latest undici features and bug fixes
- Access to advanced APIs (`request`, `stream`, `pipeline`)
- Fine-grained control over connection pooling
- Better error handling with clearer error messages
- Superior performance, especially with `undici.request`
- HTTP/1.1 pipelining support
- Custom interceptors and middleware
- Advanced features like `ProxyAgent`, `Socks5Agent`, `MockAgent`
**Cons:**
- Additional dependency to manage
- Larger bundle size
### When to Use Each
#### Use Built-in Fetch When:
- You want zero dependencies
- Building isomorphic code that runs in browsers and Node.js
- Publishing to npm and want to maximize compatibility with JS runtimes
- Simple HTTP requests without advanced configuration
- You're publishing to npm and you want to maximize compatiblity
- You don't depend on features from a specific version of undici
#### Use Undici Module When:
- You need the latest undici features and performance improvements
- You require advanced connection pooling configuration
- You need APIs not available in the built-in fetch (`ProxyAgent`, `Socks5Agent`, `MockAgent`, etc.)
- Performance is critical (use `undici.request` for maximum speed)
- You want better error handling and debugging capabilities
- You need HTTP/1.1 pipelining or advanced interceptors
- You prefer decoupled protocol and API interfaces
### Performance Comparison
Based on benchmarks, here's the typical performance hierarchy:
1. **`undici.request()`** - Fastest, most efficient
2. **`undici.fetch()`** - Good performance, standard compliance
3. **Node.js `http`/`https`** - Baseline performance
### Migration Guide
If you're currently using built-in fetch and want to migrate to undici:
```js
// Before: Built-in fetch
const response = await fetch('https://api.example.com/data');
// After: Undici fetch (drop-in replacement)
import { fetch } from 'undici';
const response = await fetch('https://api.example.com/data');
// Or: Undici request (better performance)
import { request } from 'undici';
const { statusCode, body } = await request('https://api.example.com/data');
const data = await body.json();
```
### Version Compatibility
You can check which version of undici is bundled with your Node.js version:
```js
console.log(process.versions.undici);
```
Installing undici as a module allows you to use a newer version than what's bundled with Node.js, giving you access to the latest features and performance improvements.
## Quick Start
### Basic Request
```js
import { request } from 'undici'
const {
statusCode,
headers,
trailers,
body
} = await request('http://localhost:3000/foo')
console.log('response received', statusCode)
console.log('headers', headers)
for await (const data of body) { console.log('data', data) }
console.log('trailers', trailers)
```
### Using Cache Interceptor
Undici provides a powerful HTTP caching interceptor that follows HTTP caching best practices. Here's how to use it:
```js
import { fetch, Agent, interceptors, cacheStores } from 'undici';
// Create a client with cache interceptor
const client = new Agent().compose(interceptors.cache({
// Optional: Configure cache store (defaults to MemoryCacheStore)
store: new cacheStores.MemoryCacheStore({
maxSize: 100 * 1024 * 1024, // 100MB
maxCount: 1000,
maxEntrySize: 5 * 1024 * 1024 // 5MB
}),
// Optional: Specify which HTTP methods to cache (default: ['GET', 'HEAD'])
methods: ['GET', 'HEAD']
}));
// Set the global dispatcher to use our caching client
setGlobalDispatcher(client);
// Now all fetch requests will use the cache
async function getData() {
const response = await fetch('https://api.example.com/data');
// The server should set appropriate Cache-Control headers in the response
// which the cache will respect based on the cache policy
return response.json();
}
// First request - fetches from origin
const data1 = await getData();
// Second request - served from cache if within max-age
const data2 = await getData();
```
#### Key Features:
- **Automatic Caching**: Respects `Cache-Control` and `Expires` headers
- **Validation**: Supports `ETag` and `Last-Modified` validation
- **Storage Options**: In-memory or persistent SQLite storage
- **Flexible**: Configure cache size, TTL, and more
## Global Installation
Undici provides an `install()` function to add all WHATWG fetch classes to `globalThis`, making them available globally:
```js
import { install } from 'undici'
// Install all WHATWG fetch classes globally
install()
// Now you can use fetch classes globally without importing
const response = await fetch('https://api.example.com/data')
const data = await response.json()
// All classes are available globally:
const headers = new Headers([['content-type', 'application/json']])
const request = new Request('https://example.com')
const formData = new FormData()
const ws = new WebSocket('wss://example.com')
const eventSource = new EventSource('https://example.com/events')
```
The `install()` function adds the following classes to `globalThis`:
- `fetch` - The fetch function
- `Headers` - HTTP headers management
- `Response` - HTTP response representation
- `Request` - HTTP request representation
- `FormData` - Form data handling
- `WebSocket` - WebSocket client
- `CloseEvent`, `ErrorEvent`, `MessageEvent` - WebSocket events
- `EventSource` - Server-sent events client
This is useful for:
- Polyfilling environments that don't have fetch
- Ensuring consistent fetch behavior across different Node.js versions
- Making undici's implementations available globally for libraries that expect them
## Body Mixins
The `body` mixins are the most common way to format the request/response body. Mixins include:
- [`.arrayBuffer()`](https://fetch.spec.whatwg.org/#dom-body-arraybuffer)
- [`.blob()`](https://fetch.spec.whatwg.org/#dom-body-blob)
- [`.bytes()`](https://fetch.spec.whatwg.org/#dom-body-bytes)
- [`.json()`](https://fetch.spec.whatwg.org/#dom-body-json)
- [`.text()`](https://fetch.spec.whatwg.org/#dom-body-text)
> [!NOTE]
> The body returned from `undici.request` does not implement `.formData()`.
Example usage:
```js
import { request } from 'undici'
const {
statusCode,
headers,
trailers,
body
} = await request('http://localhost:3000/foo')
console.log('response received', statusCode)
console.log('headers', headers)
console.log('data', await body.json())
console.log('trailers', trailers)
```
_Note: Once a mixin has been called then the body cannot be reused, thus calling additional mixins on `.body`, e.g. `.body.json(); .body.text()` will result in an error `TypeError: unusable` being thrown and returned through the `Promise` rejection._
Should you need to access the `body` in plain-text after using a mixin, the best practice is to use the `.text()` mixin first and then manually parse the text to the desired format.
For more information about their behavior, please reference the body mixin from the [Fetch Standard](https://fetch.spec.whatwg.org/#body-mixin).
## Common API Methods
This section documents our most commonly used API methods. Additional APIs are documented in their own files within the [docs](./docs/) folder and are accessible via the navigation list on the left side of the docs site.
### `undici.request([url, options]): Promise`
Arguments:
* **url** `string | URL | UrlObject`
* **options** [`RequestOptions`](./docs/docs/api/Dispatcher.md#parameter-requestoptions)
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
Returns a promise with the result of the `Dispatcher.request` method.
Calls `options.dispatcher.request(options)`.
See [Dispatcher.request](./docs/docs/api/Dispatcher.md#dispatcherrequestoptions-callback) for more details, and [request examples](./docs/examples/README.md) for examples.
### `undici.stream([url, options, ]factory): Promise`
Arguments:
* **url** `string | URL | UrlObject`
* **options** [`StreamOptions`](./docs/docs/api/Dispatcher.md#parameter-streamoptions)
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
* **factory** `Dispatcher.stream.factory`
Returns a promise with the result of the `Dispatcher.stream` method.
Calls `options.dispatcher.stream(options, factory)`.
See [Dispatcher.stream](./docs/docs/api/Dispatcher.md#dispatcherstreamoptions-factory-callback) for more details.
### `undici.pipeline([url, options, ]handler): Duplex`
Arguments:
* **url** `string | URL | UrlObject`
* **options** [`PipelineOptions`](./docs/docs/api/Dispatcher.md#parameter-pipelineoptions)
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
* **handler** `Dispatcher.pipeline.handler`
Returns: `stream.Duplex`
Calls `options.dispatch.pipeline(options, handler)`.
See [Dispatcher.pipeline](./docs/docs/api/Dispatcher.md#dispatcherpipelineoptions-handler) for more details.
### `undici.connect([url, options]): Promise`
Starts two-way communications with the requested resource using [HTTP CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT).
Arguments:
* **url** `string | URL | UrlObject`
* **options** [`ConnectOptions`](./docs/docs/api/Dispatcher.md#parameter-connectoptions)
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
* **callback** `(err: Error | null, data: ConnectData | null) => void` (optional)
Returns a promise with the result of the `Dispatcher.connect` method.
Calls `options.dispatch.connect(options)`.
See [Dispatcher.connect](./docs/docs/api/Dispatcher.md#dispatcherconnectoptions-callback) for more details.
### `undici.fetch(input[, init]): Promise`
Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method).
* https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
* https://fetch.spec.whatwg.org/#fetch-method
Basic usage example:
```js
import { fetch } from 'undici'
const res = await fetch('https://example.com')
const json = await res.json()
console.log(json)
```
You can pass an optional dispatcher to `fetch` as:
```js
import { fetch, Agent } from 'undici'
const res = await fetch('https://example.com', {
// Mocks are also supported
dispatcher: new Agent({
keepAliveTimeout: 10,
keepAliveMaxTimeout: 10
})
})
const json = await res.json()
console.log(json)
```
#### `request.body`
A body can be of the following types:
- ArrayBuffer
- ArrayBufferView
- AsyncIterables
- Blob
- Iterables
- String
- URLSearchParams
- FormData
In this implementation of fetch, ```request.body``` now accepts ```Async Iterables```. It is not present in the [Fetch Standard](https://fetch.spec.whatwg.org).
```js
import { fetch } from 'undici'
const data = {
async *[Symbol.asyncIterator]() {
yield 'hello'
yield 'world'
},
}
await fetch('https://example.com', { body: data, method: 'POST', duplex: 'half' })
```
[FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) besides text data and buffers can also utilize streams via [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects:
```js
import { openAsBlob } from 'node:fs'
const file = await openAsBlob('./big.csv')
const body = new FormData()
body.set('file', file, 'big.csv')
await fetch('http://example.com', { method: 'POST', body })
```
#### `request.duplex`
- `'half'`
In this implementation of fetch, `request.duplex` must be set if `request.body` is `ReadableStream` or `Async Iterables`, however, even though the value must be set to `'half'`, it is actually a _full_ duplex. For more detail refer to the [Fetch Standard](https://fetch.spec.whatwg.org/#dom-requestinit-duplex).
#### `response.body`
Nodejs has two kinds of streams: [web streams](https://nodejs.org/api/webstreams.html), which follow the API of the WHATWG web standard found in browsers, and an older Node-specific [streams API](https://nodejs.org/api/stream.html). `response.body` returns a readable web stream. If you would prefer to work with a Node stream you can convert a web stream using `.fromWeb()`.
```js
import { fetch } from 'undici'
import { Readable } from 'node:stream'
const response = await fetch('https://example.com')
const readableWebStream = response.body
const readableNodeStream = Readable.fromWeb(readableWebStream)
```
## Specification Compliance
This section documents parts of the [HTTP/1.1](https://www.rfc-editor.org/rfc/rfc9110.html) and [Fetch Standard](https://fetch.spec.whatwg.org) that Undici does
not support or does not fully implement.
#### CORS
Unlike browsers, Undici does not implement CORS (Cross-Origin Resource Sharing) checks by default. This means:
- No preflight requests are automatically sent for cross-origin requests
- No validation of `Access-Control-Allow-Origin` headers is performed
- Requests to any origin are allowed regardless of the source
This behavior is intentional for server-side environments where CORS restrictions are typically unnecessary. If your application requires CORS-like protections, you will need to implement these checks manually.
#### Garbage Collection
* https://fetch.spec.whatwg.org/#garbage-collection
The [Fetch Standard](https://fetch.spec.whatwg.org) allows users to skip consuming the response body by relying on
[garbage collection](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection) to release connection resources.
Garbage collection in Node is less aggressive and deterministic
(due to the lack of clear idle periods that browsers have through the rendering refresh rate)
which means that leaving the release of connection resources to the garbage collector can lead
to excessive connection usage, reduced performance (due to less connection re-use), and even
stalls or deadlocks when running out of connections.
Therefore, __it is important to always either consume or cancel the response body anyway__.
```js
// Do
const { body, headers } = await fetch(url);
for await (const chunk of body) {
// force consumption of body
}
// Do not
const { headers } = await fetch(url);
```
However, if you want to get only headers, it might be better to use `HEAD` request method. Usage of this method will obviate the need for consumption or cancelling of the response body. See [MDN - HTTP - HTTP request methods - HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD) for more details.
```js
const headers = await fetch(url, { method: 'HEAD' })
.then(res => res.headers)
```
Note that consuming the response body is _mandatory_ for `request`:
```js
// Do
const { body, headers } = await request(url);
await body.dump(); // force consumption of body
// Do not
const { headers } = await request(url);
```
#### Forbidden and Safelisted Header Names
* https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name
* https://fetch.spec.whatwg.org/#forbidden-header-name
* https://fetch.spec.whatwg.org/#forbidden-response-header-name
* https://github.com/wintercg/fetch/issues/6
The [Fetch Standard](https://fetch.spec.whatwg.org) requires implementations to exclude certain headers from requests and responses. In browser environments, some headers are forbidden so the user agent remains in full control over them. In Undici, these constraints are removed to give more control to the user.
#### Content-Encoding
* https://www.rfc-editor.org/rfc/rfc9110#field.content-encoding
Undici limits the number of `Content-Encoding` layers in a response to **5** to prevent resource exhaustion attacks. If a server responds with more than 5 content-encodings (e.g., `Content-Encoding: gzip, gzip, gzip, gzip, gzip, gzip`), the fetch will be rejected with an error. This limit matches the approach taken by [curl](https://curl.se/docs/CVE-2022-32206.html) and [urllib3](https://github.com/advisories/GHSA-gm62-xv2j-4rw9).
#### `undici.upgrade([url, options]): Promise`
Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.
Arguments:
* **url** `string | URL | UrlObject`
* **options** [`UpgradeOptions`](./docs/docs/api/Dispatcher.md#parameter-upgradeoptions)
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcher)
* **callback** `(error: Error | null, data: UpgradeData) => void` (optional)
Returns a promise with the result of the `Dispatcher.upgrade` method.
Calls `options.dispatcher.upgrade(options)`.
See [Dispatcher.upgrade](./docs/docs/api/Dispatcher.md#dispatcherupgradeoptions-callback) for more details.
### `undici.setGlobalDispatcher(dispatcher)`
* dispatcher `Dispatcher`
Sets the global dispatcher used by Common API Methods. Global dispatcher is shared among compatible undici modules,
including undici that is bundled internally with node.js.
### `undici.getGlobalDispatcher()`
Gets the global dispatcher used by Common API Methods.
Returns: `Dispatcher`
### `undici.setGlobalOrigin(origin)`
* origin `string | URL | undefined`
Sets the global origin used in `fetch`.
If `undefined` is passed, the global origin will be reset. This will cause `Response.redirect`, `new Request()`, and `fetch` to throw an error when a relative path is passed.
```js
setGlobalOrigin('http://localhost:3000')
const response = await fetch('/api/ping')
console.log(response.url) // http://localhost:3000/api/ping
```
### `undici.getGlobalOrigin()`
Gets the global origin used in `fetch`.
Returns: `URL`
### `UrlObject`
* **port** `string | number` (optional)
* **path** `string` (optional)
* **pathname** `string` (optional)
* **hostname** `string` (optional)
* **origin** `string` (optional)
* **protocol** `string` (optional)
* **search** `string` (optional)
#### Expect
Undici does not support the `Expect` request header field. The request
body is always immediately sent and the `100 Continue` response will be
ignored.
Refs: https://tools.ietf.org/html/rfc7231#section-5.1.1
#### Pipelining
Undici will only use pipelining if configured with a `pipelining` factor
greater than `1`. Also it is important to pass `blocking: false` to the
request options to properly pipeline requests.
Undici always assumes that connections are persistent and will immediately
pipeline requests, without checking whether the connection is persistent.
Hence, automatic fallback to HTTP/1.0 or HTTP/1.1 without pipelining is
not supported.
Undici will immediately pipeline when retrying requests after a failed
connection. However, Undici will not retry the first remaining requests in
the prior pipeline and instead error the corresponding callback/promise/stream.
Undici will abort all running requests in the pipeline when any of them are
aborted.
* Refs: https://tools.ietf.org/html/rfc2616#section-8.1.2.2
* Refs: https://tools.ietf.org/html/rfc7230#section-6.3.2
#### Manual Redirect
Since it is not possible to manually follow an HTTP redirect on the server-side,
Undici returns the actual response instead of an `opaqueredirect` filtered one
when invoked with a `manual` redirect. This aligns `fetch()` with the other
implementations in Deno and Cloudflare Workers.
Refs: https://fetch.spec.whatwg.org/#atomic-http-redirect-handling
### Workarounds
#### Network address family autoselection.
If you experience problem when connecting to a remote server that is resolved by your DNS servers to a IPv6 (AAAA record)
first, there are chances that your local router or ISP might have problem connecting to IPv6 networks. In that case
undici will throw an error with code `UND_ERR_CONNECT_TIMEOUT`.
If the target server resolves to both a IPv6 and IPv4 (A records) address and you are using a compatible Node version
(18.3.0 and above), you can fix the problem by providing the `autoSelectFamily` option (support by both `undici.request`
and `undici.Agent`) which will enable the family autoselection algorithm when establishing the connection.
## Collaborators
* [__Daniele Belardi__](https://github.com/dnlup), <https://www.npmjs.com/~dnlup>
* [__Ethan Arrowood__](https://github.com/ethan-arrowood), <https://www.npmjs.com/~ethan_arrowood>
* [__Matteo Collina__](https://github.com/mcollina), <https://www.npmjs.com/~matteo.collina>
* [__Matthew Aitken__](https://github.com/KhafraDev), <https://www.npmjs.com/~khaf>
* [__Robert Nagy__](https://github.com/ronag), <https://www.npmjs.com/~ronag>
* [__Szymon Marczak__](https://github.com/szmarczak), <https://www.npmjs.com/~szmarczak>
## Past Collaborators
* [__Tomas Della Vedova__](https://github.com/delvedor), <https://www.npmjs.com/~delvedor>
### Releasers
* [__Ethan Arrowood__](https://github.com/ethan-arrowood), <https://www.npmjs.com/~ethan_arrowood>
* [__Matteo Collina__](https://github.com/mcollina), <https://www.npmjs.com/~matteo.collina>
* [__Robert Nagy__](https://github.com/ronag), <https://www.npmjs.com/~ronag>
* [__Matthew Aitken__](https://github.com/KhafraDev), <https://www.npmjs.com/~khaf>
## Long Term Support
Undici aligns with the Node.js LTS schedule. The following table shows the supported versions:
| Undici Version | Bundled in Node.js | Node.js Versions Supported | End of Life |
|----------------|-------------------|----------------------------|-------------|
| 5.x | 18.x | ≥14.0 (tested: 14, 16, 18) | 2024-04-30 |
| 6.x | 20.x, 22.x | ≥18.17 (tested: 18, 20, 21, 22) | 2026-04-30 |
| 7.x | 24.x | ≥20.18.1 (tested: 20, 22, 24) | 2027-04-30 |
## License
MIT
================================================
FILE: SECURITY.md
================================================
If you believe you have found a security issue in the software in this
repository, please consult https://github.com/nodejs/node/blob/HEAD/SECURITY.md.
================================================
FILE: benchmarks/_util/index.js
================================================
'use strict'
const parallelRequests = parseInt(process.env.PARALLEL, 10) || 100
function makeParallelRequests (cb) {
const promises = new Array(parallelRequests)
for (let i = 0; i < parallelRequests; ++i) {
promises[i] = new Promise(cb)
}
return Promise.all(promises)
}
function printResults (results) {
// Sort results by least performant first, then compare relative performances and also printing padding
let last
const rows = Object.entries(results)
// If any failed, put on the top of the list, otherwise order by mean, ascending
.sort((a, b) => (!a[1].success ? -1 : b[1].mean - a[1].mean))
.map(([name, result]) => {
if (!result.success) {
return {
Tests: name,
Samples: result.size,
Result: 'Errored',
Tolerance: 'N/A',
'Difference with Slowest': 'N/A'
}
}
// Calculate throughput and relative performance
const { size, mean, standardError } = result
const relative = last !== 0 ? (last / mean - 1) * 100 : 0
// Save the slowest for relative comparison
if (typeof last === 'undefined') {
last = mean
}
return {
Tests: name,
Samples: size,
Result: `${((parallelRequests * 1e9) / mean).toFixed(2)} req/sec`,
Tolerance: `± ${((standardError / mean) * 100).toFixed(2)} %`,
'Difference with slowest':
relative > 0 ? `+ ${relative.toFixed(2)} %` : '-'
}
})
return console.table(rows)
}
/**
* @param {number} num
* @returns {string}
*/
function formatBytes (num) {
if (!Number.isFinite(num)) {
throw new Error('invalid number')
}
const prefixes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']
const idx = Math.min(Math.floor(Math.log(num) / Math.log(1024)), prefixes.length - 1)
return `${(num / Math.pow(1024, idx)).toFixed(2)}${prefixes[idx]}`
}
module.exports = { makeParallelRequests, printResults, formatBytes }
================================================
FILE: benchmarks/_util/runner.js
================================================
// @ts-check
'use strict'
class Info {
/** @type {string} */
#name
/** @type {bigint} */
#current
/** @type {bigint} */
#finish
/** @type {(...args: any[]) => any} */
#callback
/** @type {boolean} */
#finalized = false
/**
* @param {string} name
* @param {(...args: any[]) => any} callback
*/
constructor (name, callback) {
this.#name = name
this.#callback = callback
}
get name () {
return this.#name
}
start () {
if (this.#finalized) {
throw new TypeError('called after finished.')
}
this.#current = process.hrtime.bigint()
}
end () {
if (this.#finalized) {
throw new TypeError('called after finished.')
}
this.#finish = process.hrtime.bigint()
this.#finalized = true
this.#callback()
}
diff () {
return Number(this.#finish - this.#current)
}
}
/**
* @typedef BenchMarkHandler
* @type {(ev: { name: string; start(): void; end(): void; }) => any}
*/
/**
* @param {Record<string, BenchMarkHandler>} experiments
* @param {{ minSamples?: number; maxSamples?: number }} [options]
* @returns {Promise<{ name: string; average: number; samples: number; fn: BenchMarkHandler; iterationPerSecond: number; min: number; max: number }[]>}
*/
async function bench (experiments, options = {}) {
const names = Object.keys(experiments)
/** @type {{ name: string; average: number; samples: number; fn: BenchMarkHandler; iterationPerSecond: number; min: number; max: number }[]} */
const results = []
async function waitMaybePromiseLike (p) {
if (
(typeof p === 'object' || typeof p === 'function') &&
p !== null &&
typeof p.then === 'function'
) {
await p
}
}
for (let i = 0; i < names.length; ++i) {
const name = names[i]
const fn = experiments[name]
const samples = []
for (let i = 0; i < 8; ++i) {
// warmup
await new Promise((resolve, reject) => {
const info = new Info(name, resolve)
try {
const p = fn(info)
waitMaybePromiseLike(p).catch((err) => reject(err))
} catch (err) {
reject(err)
}
})
}
let timing = 0
const minSamples = options.minSamples ?? 128
for (let j = 0; (j < minSamples || timing < 800_000_000) && (typeof options.maxSamples === 'number' ? options.maxSamples > j : true); ++j) {
let resolve = (value) => {}
let reject = (reason) => {}
const promise = new Promise(
(_resolve, _reject) => { resolve = _resolve; reject = _reject }
)
const info = new Info(name, resolve)
try {
const p = fn(info)
await waitMaybePromiseLike(p)
} catch (err) {
reject(err)
}
await promise
samples.push({ time: info.diff() })
timing += info.diff()
}
const average =
samples.map((v) => v.time).reduce((a, b) => a + b, 0) / samples.length
results.push({
name: names[i],
average,
samples: samples.length,
fn,
iterationPerSecond: 1e9 / average,
min: samples.reduce((a, acc) => Math.min(a, acc.time), samples[0].time),
max: samples.reduce((a, acc) => Math.max(a, acc.time), samples[0].time)
})
}
return results
}
module.exports = { bench }
================================================
FILE: benchmarks/benchmark-http2.js
================================================
'use strict'
const os = require('node:os')
const path = require('node:path')
const http2 = require('node:http2')
const { readFileSync } = require('node:fs')
const { Writable } = require('node:stream')
const { isMainThread } = require('node:worker_threads')
const { Pool, Client, fetch, Agent, setGlobalDispatcher } = require('..')
const ca = readFileSync(path.join(__dirname, '..', 'test', 'fixtures', 'ca.pem'), 'utf8')
const servername = 'agent1'
const iterations = (parseInt(process.env.SAMPLES, 10) || 10) + 1
const errorThreshold = parseInt(process.env.ERROR_THRESHOLD, 10) || 3
const connections = parseInt(process.env.CONNECTIONS, 10) || 50
const pipelining = parseInt(process.env.PIPELINING, 10) || 10
const parallelRequests = parseInt(process.env.PARALLEL, 10) || 100
const headersTimeout = parseInt(process.env.HEADERS_TIMEOUT, 10) || 0
const bodyTimeout = parseInt(process.env.BODY_TIMEOUT, 10) || 0
const dest = {}
if (process.env.PORT) {
dest.port = process.env.PORT
dest.url = `https://localhost:${process.env.PORT}`
} else {
dest.url = 'https://localhost'
dest.socketPath = path.join(os.tmpdir(), 'undici.sock')
}
const httpsBaseOptions = {
ca,
servername,
protocol: 'https:',
hostname: 'localhost',
method: 'GET',
path: '/',
query: {
frappucino: 'muffin',
goat: 'scone',
pond: 'moose',
foo: ['bar', 'baz', 'bal'],
bool: true,
numberKey: 256
},
...dest
}
const undiciOptions = {
path: '/',
method: 'GET',
headersTimeout,
bodyTimeout
}
const http2NativeClient = http2.connect(httpsBaseOptions.url, {
rejectUnauthorized: false
})
const Class = connections > 1 ? Pool : Client
const dispatcher = new Class(httpsBaseOptions.url, {
allowH2: true,
pipelining,
connections,
connect: {
rejectUnauthorized: false,
ca,
servername
},
...dest
})
setGlobalDispatcher(new Agent({
allowH2: true,
pipelining,
connections,
connect: {
rejectUnauthorized: false,
ca,
servername
}
}))
class SimpleRequest {
constructor (resolve) {
this.dst = new Writable({
write (chunk, encoding, callback) {
callback()
}
}).on('finish', resolve)
}
onConnect (abort) { }
onHeaders (statusCode, headers, resume) {
this.dst.on('drain', resume)
}
onData (chunk) {
return this.dst.write(chunk)
}
onComplete () {
this.dst.end()
}
onError (err) {
throw err
}
}
function makeParallelRequests (cb) {
const res = Promise.all(Array.from(Array(parallelRequests)).map(() => new Promise(cb)))
res.catch(console.error)
return res
}
function printResults (results) {
// Sort results by least performant first, then compare relative performances and also printing padding
let last
const rows = Object.entries(results)
// If any failed, put on the top of the list, otherwise order by mean, ascending
.sort((a, b) => (!a[1].success ? -1 : b[1].mean - a[1].mean))
.map(([name, result]) => {
if (!result.success) {
return {
Tests: name,
Samples: result.size,
Result: 'Errored',
Tolerance: 'N/A',
'Difference with Slowest': 'N/A'
}
}
// Calculate throughput and relative performance
const { size, mean, standardError } = result
const relative = last !== 0 ? (last / mean - 1) * 100 : 0
// Save the slowest for relative comparison
if (typeof last === 'undefined') {
last = mean
}
console.log(mean)
return {
Tests: name,
Samples: size,
Result: `${((1e9 * parallelRequests) / mean).toFixed(2)} req/sec`,
Tolerance: `± ${((standardError / mean) * 100).toFixed(2)} %`,
'Difference with slowest': relative > 0 ? `+ ${relative.toFixed(2)} %` : '-'
}
})
return console.table(rows)
}
const experiments = {
'native - http2' () {
return makeParallelRequests(resolve => {
const stream = http2NativeClient.request({
[http2.constants.HTTP2_HEADER_PATH]: httpsBaseOptions.path,
[http2.constants.HTTP2_HEADER_METHOD]: httpsBaseOptions.method
})
stream.end().on('response', () => {
stream.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('error', (err) => {
console.log('http2 - request - response - error', err)
})
.on('finish', () => {
resolve()
})
})
})
},
'undici - pipeline' () {
return makeParallelRequests(resolve => {
dispatcher
.pipeline(undiciOptions, data => {
return data.body
})
.end()
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
},
'undici - request' () {
return makeParallelRequests(resolve => {
try {
dispatcher.request(undiciOptions).then(({ body }) => {
body
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('error', (err) => {
console.log('undici - request - dispatcher.request - body - error', err)
})
.on('finish', () => {
resolve()
})
})
} catch (err) {
console.error('undici - request - dispatcher.request - requestCount', err)
}
})
},
'undici - stream' () {
return makeParallelRequests(resolve => {
return dispatcher
.stream(undiciOptions, () => {
return new Writable({
write (chunk, encoding, callback) {
callback()
}
})
})
.then(resolve)
})
},
'undici - dispatch' () {
return makeParallelRequests(resolve => {
dispatcher.dispatch(undiciOptions, new SimpleRequest(resolve))
})
}
}
if (process.env.PORT) {
// fetch does not support the socket
experiments['undici - fetch'] = () => {
return makeParallelRequests(resolve => {
fetch(dest.url, {}).then(res => {
res.body.pipeTo(new WritableStream({ write () { }, close () { resolve() } }))
}).catch(console.log)
})
}
}
async function main () {
const { cronometro } = await import('cronometro')
cronometro(
experiments,
{
iterations,
errorThreshold,
print: false
},
(err, results) => {
if (err) {
throw err
}
printResults(results)
dispatcher.destroy()
http2NativeClient.close()
}
)
}
if (isMainThread) {
main()
} else {
module.exports = main
}
================================================
FILE: benchmarks/benchmark-https.js
================================================
'use strict'
const https = require('node:https')
const os = require('node:os')
const path = require('node:path')
const { readFileSync } = require('node:fs')
const { Writable } = require('node:stream')
const { isMainThread } = require('node:worker_threads')
const { Pool, Client, fetch, Agent, setGlobalDispatcher } = require('..')
const ca = readFileSync(path.join(__dirname, '..', 'test', 'fixtures', 'ca.pem'), 'utf8')
const servername = 'agent1'
const iterations = (parseInt(process.env.SAMPLES, 10) || 10) + 1
const errorThreshold = parseInt(process.env.ERROR_THRESHOLD, 10) || 3
const connections = parseInt(process.env.CONNECTIONS, 10) || 50
const pipelining = parseInt(process.env.PIPELINING, 10) || 10
const parallelRequests = parseInt(process.env.PARALLEL, 10) || 100
const headersTimeout = parseInt(process.env.HEADERS_TIMEOUT, 10) || 0
const bodyTimeout = parseInt(process.env.BODY_TIMEOUT, 10) || 0
const dest = {}
if (process.env.PORT) {
dest.port = process.env.PORT
dest.url = `https://localhost:${process.env.PORT}`
} else {
dest.url = 'https://localhost'
dest.socketPath = path.join(os.tmpdir(), 'undici.sock')
}
const httpsBaseOptions = {
ca,
servername,
protocol: 'https:',
hostname: 'localhost',
method: 'GET',
path: '/',
query: {
frappucino: 'muffin',
goat: 'scone',
pond: 'moose',
foo: ['bar', 'baz', 'bal'],
bool: true,
numberKey: 256
},
...dest
}
const httpsNoKeepAliveOptions = {
...httpsBaseOptions,
agent: new https.Agent({
keepAlive: false,
maxSockets: connections,
// rejectUnauthorized: false,
ca,
servername
})
}
const httpsKeepAliveOptions = {
...httpsBaseOptions,
agent: new https.Agent({
keepAlive: true,
maxSockets: connections,
// rejectUnauthorized: false,
ca,
servername
})
}
const undiciOptions = {
path: '/',
method: 'GET',
headersTimeout,
bodyTimeout
}
const Class = connections > 1 ? Pool : Client
const dispatcher = new Class(httpsBaseOptions.url, {
pipelining,
connections,
connect: {
// rejectUnauthorized: false,
ca,
servername
},
...dest
})
setGlobalDispatcher(new Agent({
pipelining,
connections,
connect: {
// rejectUnauthorized: false,
ca,
servername
}
}))
class SimpleRequest {
constructor (resolve) {
this.dst = new Writable({
write (chunk, encoding, callback) {
callback()
}
}).on('finish', resolve)
}
onConnect (abort) { }
onHeaders (statusCode, headers, resume) {
this.dst.on('drain', resume)
}
onData (chunk) {
return this.dst.write(chunk)
}
onComplete () {
this.dst.end()
}
onError (err) {
throw err
}
}
function makeParallelRequests (cb) {
return Promise.all(Array.from(Array(parallelRequests)).map(() => new Promise(cb)))
}
function printResults (results) {
// Sort results by least performant first, then compare relative performances and also printing padding
let last
const rows = Object.entries(results)
// If any failed, put on the top of the list, otherwise order by mean, ascending
.sort((a, b) => (!a[1].success ? -1 : b[1].mean - a[1].mean))
.map(([name, result]) => {
if (!result.success) {
return {
Tests: name,
Samples: result.size,
Result: 'Errored',
Tolerance: 'N/A',
'Difference with Slowest': 'N/A'
}
}
// Calculate throughput and relative performance
const { size, mean, standardError } = result
const relative = last !== 0 ? (last / mean - 1) * 100 : 0
// Save the slowest for relative comparison
if (typeof last === 'undefined') {
last = mean
}
return {
Tests: name,
Samples: size,
Result: `${((parallelRequests * 1e9) / mean).toFixed(2)} req/sec`,
Tolerance: `± ${((standardError / mean) * 100).toFixed(2)} %`,
'Difference with slowest': relative > 0 ? `+ ${relative.toFixed(2)} %` : '-'
}
})
return console.table(rows)
}
const experiments = {
'https - no keepalive' () {
return makeParallelRequests(resolve => {
https.get(httpsNoKeepAliveOptions, res => {
res
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
})
},
'https - keepalive' () {
return makeParallelRequests(resolve => {
https.get(httpsKeepAliveOptions, res => {
res
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
})
},
'undici - pipeline' () {
return makeParallelRequests(resolve => {
dispatcher
.pipeline(undiciOptions, data => {
return data.body
})
.end()
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
},
'undici - request' () {
return makeParallelRequests(resolve => {
dispatcher.request(undiciOptions).then(({ body }) => {
body
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
})
},
'undici - stream' () {
return makeParallelRequests(resolve => {
return dispatcher
.stream(undiciOptions, () => {
return new Writable({
write (chunk, encoding, callback) {
callback()
}
})
})
.then(resolve)
})
},
'undici - dispatch' () {
return makeParallelRequests(resolve => {
dispatcher.dispatch(undiciOptions, new SimpleRequest(resolve))
})
}
}
if (process.env.PORT) {
// fetch does not support the socket
experiments['undici - fetch'] = () => {
return makeParallelRequests(resolve => {
fetch(dest.url, {}).then(res => {
res.body.pipeTo(new WritableStream({ write () { }, close () { resolve() } }))
}).catch(console.log)
})
}
}
async function main () {
const { cronometro } = await import('cronometro')
cronometro(
experiments,
{
iterations,
errorThreshold,
print: false
},
(err, results) => {
if (err) {
throw err
}
printResults(results)
dispatcher.destroy()
}
)
}
if (isMainThread) {
main()
} else {
module.exports = main
}
================================================
FILE: benchmarks/benchmark.js
================================================
'use strict'
const http = require('node:http')
const os = require('node:os')
const path = require('node:path')
const { Writable } = require('node:stream')
const { isMainThread } = require('node:worker_threads')
const { Pool, Client, fetch, Agent, setGlobalDispatcher } = require('..')
const { makeParallelRequests, printResults } = require('./_util')
let nodeFetch
const axios = require('axios')
let superagent
let got
const { promisify } = require('node:util')
const request = promisify(require('request'))
const iterations = (parseInt(process.env.SAMPLES, 10) || 10) + 1
const errorThreshold = parseInt(process.env.ERROR_THRESHOLD, 10) || 3
const connections = parseInt(process.env.CONNECTIONS, 10) || 50
const pipelining = parseInt(process.env.PIPELINING, 10) || 10
const headersTimeout = parseInt(process.env.HEADERS_TIMEOUT, 10) || 0
const bodyTimeout = parseInt(process.env.BODY_TIMEOUT, 10) || 0
const dest = {}
if (process.env.PORT) {
dest.port = process.env.PORT
dest.url = `http://localhost:${process.env.PORT}`
} else {
dest.url = 'http://localhost'
dest.socketPath = path.join(os.tmpdir(), 'undici.sock')
}
/** @type {http.RequestOptions} */
const httpBaseOptions = {
protocol: 'http:',
hostname: 'localhost',
method: 'GET',
path: '/',
...dest
}
/** @type {http.RequestOptions} */
const httpNoKeepAliveOptions = {
...httpBaseOptions,
agent: new http.Agent({
keepAlive: false,
maxSockets: connections
})
}
/** @type {http.RequestOptions} */
const httpKeepAliveOptions = {
...httpBaseOptions,
agent: new http.Agent({
keepAlive: true,
maxSockets: connections
})
}
const axiosAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const fetchAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const gotAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const requestAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const superagentAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const undiciOptions = {
path: '/',
method: 'GET',
blocking: false,
reset: false,
headersTimeout,
bodyTimeout
}
const Class = connections > 1 ? Pool : Client
const dispatcher = new Class(httpBaseOptions.url, {
pipelining,
connections,
...dest
})
setGlobalDispatcher(new Agent({
pipelining,
connections,
connect: {
rejectUnauthorized: false
}
}))
class SimpleRequest {
constructor (resolve) {
this.dst = new Writable({
write (chunk, encoding, callback) {
callback()
}
}).on('finish', resolve)
}
onConnect (abort) { }
onHeaders (statusCode, headers, resume) {
this.dst.on('drain', resume)
}
onData (chunk) {
return this.dst.write(chunk)
}
onComplete () {
this.dst.end()
}
onError (err) {
throw err
}
}
const experiments = {
'http - no keepalive' () {
return makeParallelRequests(resolve => {
http.get(httpNoKeepAliveOptions, res => {
res
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
})
},
'http - keepalive' () {
return makeParallelRequests(resolve => {
http.get(httpKeepAliveOptions, res => {
res
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
})
},
'undici - pipeline' () {
return makeParallelRequests(resolve => {
dispatcher
.pipeline(undiciOptions, ({ body }) => {
return body
})
.end()
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
},
'undici - request' () {
return makeParallelRequests(resolve => {
dispatcher.request(undiciOptions).then(({ body }) => {
body
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
})
},
'undici - stream' () {
return makeParallelRequests(resolve => {
return dispatcher
.stream(undiciOptions, () => {
return new Writable({
write (chunk, encoding, callback) {
callback()
}
})
})
.then(resolve)
})
},
'undici - dispatch' () {
return makeParallelRequests(resolve => {
dispatcher.dispatch(undiciOptions, new SimpleRequest(resolve))
})
}
}
if (process.env.PORT) {
// fetch does not support the socket
experiments['undici - fetch'] = () => {
return makeParallelRequests(resolve => {
fetch(dest.url).then(res => {
res.body.pipeTo(new WritableStream({ write () { }, close () { resolve() } }))
}).catch(console.log)
})
}
experiments['node-fetch'] = () => {
return makeParallelRequests(resolve => {
nodeFetch(dest.url, { agent: fetchAgent }).then(res => {
res.body.pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
}).catch(console.log)
})
}
const axiosOptions = {
url: dest.url,
method: 'GET',
responseType: 'stream',
httpAgent: axiosAgent
}
experiments.axios = () => {
return makeParallelRequests(resolve => {
axios.request(axiosOptions).then(res => {
res.data.pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
}).catch(console.log)
})
}
const gotOptions = {
url: dest.url,
method: 'GET',
agent: {
http: gotAgent
},
// avoid body processing
isStream: true
}
experiments.got = () => {
return makeParallelRequests(resolve => {
got(gotOptions).pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
})
}
const requestOptions = {
url: dest.url,
method: 'GET',
agent: requestAgent,
// avoid body toString
encoding: null
}
experiments.request = () => {
return makeParallelRequests(resolve => {
request(requestOptions).then(() => {
// already body consumed
resolve()
}).catch(console.log)
})
}
experiments.superagent = () => {
return makeParallelRequests(resolve => {
superagent.get(dest.url).pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
})
}
}
async function main () {
const { cronometro } = await import('cronometro')
const _nodeFetch = await import('node-fetch')
nodeFetch = _nodeFetch.default
const _got = await import('got')
got = _got.default
const _superagent = await import('superagent')
// https://github.com/ladjs/superagent/issues/1540#issue-561464561
superagent = _superagent.agent().use((req) => req.agent(superagentAgent))
cronometro(
experiments,
{
iterations,
errorThreshold,
print: false
},
(err, results) => {
if (err) {
throw err
}
printResults(results)
dispatcher.destroy()
}
)
}
if (isMainThread) {
main()
} else {
module.exports = main
}
================================================
FILE: benchmarks/cache/date.mjs
================================================
'use strict'
import { group, bench, run } from 'mitata'
import { parseHttpDate } from '../../lib/util/date.js'
const DATES = [
// IMF
'Sun, 06 Nov 1994 08:49:37 GMT',
'Thu, 18 Aug 1950 02:01:18 GMT',
'Wed, 11 Dec 2024 23:20:57 GMT',
'Wed, aa Dec 2024 23:20:57 GMT',
'aaa, 06 Dec 2024 23:20:57 GMT',
'Wed, 01 aaa 2024 23:20:57 GMT',
'Wed, 6 Dec 2024 23:20:07 GMT',
'Wed, 06 Dec 2024 3:20:07 GMT',
'Wed, 06 Dec 2024 23:1:07 GMT',
'Wed, 06 Dec 2024 23:01:7 GMT',
'Wed, 06 Dec aaaa 23:01:07 GMT',
'Wed, 06 Dec 2024 aa:01:07 GMT',
'Wed, 06 Dec 2024 23:aa:07 GMT',
'Wed, 06 Dec 2024 23:01:aa GMT',
// RFC850
'Sunday, 06-Nov-94 08:49:37 GMT',
'Thursday, 18-Aug-50 02:01:18 GMT',
'Wednesday, 11-Dec-24 23:20:57 GMT',
'Wednesday, aa Dec 2024 23:20:57 GMT',
'aaa, 06 Dec 2024 23:20:57 GMT',
'Wednesday, 01-aaa-24 23:20:57 GMT',
'Wednesday, 6-Dec-24 23:20:07 GMT',
'Wednesday, 06-Dec-24 3:20:07 GMT',
'Wednesday, 06-Dec-24 23:1:07 GMT',
'Wednesday, 06-Dec-24 23:01:7 GMT',
'Wednesday, 06 Dec-aa 23:01:07 GMT',
'Wednesday, 06-Dec-24 aa:01:07 GMT',
'Wednesday, 06-Dec-24 23:aa:07 GMT',
'Wednesday, 06-Dec-24 23:01:aa GMT',
// asctime()
'Sun Nov 6 08:49:37 1994',
'Thu Aug 18 02:01:18 1950',
'Wed Dec 11 23:20:57 2024',
'Wed Dec aa 23:20:57 2024',
'aaa Dec 06 23:20:57 2024',
'Wed aaa 01 23:20:57 2024',
'Wed Dec 6 23:20:07 2024',
'Wed Dec 06 3:20:07 2024',
'Wed Dec 06 23:1:07 2024',
'Wed Dec 06 23:01:7 2024',
'Wed 06 Dec 23:01:07 aaaa',
'Wed Dec 06 aa:01:07 2024',
'Wed Dec 06 23:aa:07 2024',
'Wed Dec 06 23:01:aa 2024'
]
group(() => {
bench('parseHttpDate', () => {
for (const date of DATES) {
parseHttpDate(date)
}
})
bench('new Date()', () => {
for (const date of DATES) {
// eslint-disable-next-line no-new
new Date(date)
}
})
})
await run()
================================================
FILE: benchmarks/cache/get-field-values.mjs
================================================
import { bench, group, run } from 'mitata'
import { getFieldValues } from '../../lib/web/cache/util.js'
const values = [
'',
'foo',
'invälid',
'foo, ',
'foo, bar',
'foo, bar, baz',
'foo, bar, baz, ',
'foo, bar, baz, , '
]
group('getFieldValues', () => {
bench('getFieldValues', () => {
for (let i = 0; i < values.length; ++i) {
getFieldValues(values[i])
}
})
})
await run()
================================================
FILE: benchmarks/cookies/is-ctl-excluding-htab.mjs
================================================
import { bench, group, run } from 'mitata'
import { isCTLExcludingHtab } from '../../lib/web/cookies/util.js'
const valid = 'Space=Cat; Secure; HttpOnly; Max-Age=2'
const invalid = 'Space=Cat; Secure; HttpOnly; Max-Age=2\x7F'
group('isCTLExcludingHtab', () => {
bench(`valid: ${valid}`, () => {
return isCTLExcludingHtab(valid)
})
bench(`invalid: ${invalid}`, () => {
return isCTLExcludingHtab(invalid)
})
})
await run()
================================================
FILE: benchmarks/cookies/to-imf-date.mjs
================================================
import { bench, group, run } from 'mitata'
import { toIMFDate } from '../../lib/web/cookies/util.js'
const date = new Date()
group('toIMFDate', () => {
bench(`toIMFDate: ${date}`, () => {
return toIMFDate(date)
})
})
await run()
================================================
FILE: benchmarks/cookies/validate-cookie-name.mjs
================================================
import { bench, group, run } from 'mitata'
import { validateCookieName } from '../../lib/web/cookies/util.js'
const valid = 'Cat'
group('validateCookieName', () => {
bench(`valid: ${valid}`, () => {
return validateCookieName(valid)
})
})
await run()
================================================
FILE: benchmarks/cookies/validate-cookie-value.mjs
================================================
import { bench, group, run } from 'mitata'
import { validateCookieValue } from '../../lib/web/cookies/util.js'
const valid = 'Cat'
const wrappedValid = `"${valid}"`
group('validateCookieValue', () => {
bench(`valid: ${valid}`, () => {
return validateCookieValue(valid)
})
bench(`valid: ${wrappedValid}`, () => {
return validateCookieValue(wrappedValid)
})
})
await run()
================================================
FILE: benchmarks/core/is-blob-like.mjs
================================================
import { bench, group, run } from 'mitata'
import { isBlobLike } from '../../lib/core/util.js'
const buffer = Buffer.alloc(1)
const blob = new Blob(['asd'], {
type: 'application/json'
})
const file = new File(['asd'], 'file.txt', {
type: 'text/plain'
})
const blobLikeStream = {
[Symbol.toStringTag]: 'Blob',
stream: () => {}
}
const fileLikeStream = {
stream: () => {},
[Symbol.toStringTag]: 'File'
}
const blobLikeArrayBuffer = {
[Symbol.toStringTag]: 'Blob',
arrayBuffer: () => {}
}
const fileLikeArrayBuffer = {
[Symbol.toStringTag]: 'File',
arrayBuffer: () => {}
}
group('isBlobLike', () => {
bench('blob', () => {
return isBlobLike(blob)
})
bench('file', () => {
return isBlobLike(file)
})
bench('blobLikeStream', () => {
return isBlobLike(blobLikeStream)
})
bench('fileLikeStream', () => {
return isBlobLike(fileLikeStream)
})
bench('fileLikeArrayBuffer', () => {
return isBlobLike(fileLikeArrayBuffer)
})
bench('blobLikeArrayBuffer', () => {
return isBlobLike(blobLikeArrayBuffer)
})
bench('buffer', () => {
return isBlobLike(buffer)
})
bench('null', () => {
return isBlobLike(null)
})
bench('string', () => {
return isBlobLike('invalid')
})
})
await run()
================================================
FILE: benchmarks/core/is-valid-header-char.mjs
================================================
import { bench, group, run } from 'mitata'
import { isValidHeaderChar } from '../../lib/core/util.js'
const html = 'text/html'
const json = 'application/json; charset=UTF-8'
const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/
/**
* @param {string} characters
*/
function charCodeAtApproach (characters) {
// Validate if characters is a valid field-vchar.
// field-value = *( field-content / obs-fold )
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
// field-vchar = VCHAR / obs-text
for (let i = 0; i < characters.length; ++i) {
const code = characters.charCodeAt(i)
// not \x20-\x7e, \t and \x80-\xff
if ((code < 0x20 && code !== 0x09) || code === 0x7f || code > 0xff) {
return false
}
}
return true
}
group(`isValidHeaderChar# ${html}`, () => {
bench('regexp.test', () => {
return !headerCharRegex.test(html)
})
bench('regexp.exec', () => {
return headerCharRegex.exec(html) === null
})
bench('charCodeAt', () => {
return charCodeAtApproach(html)
})
bench('isValidHeaderChar', () => {
return isValidHeaderChar(html)
})
})
group(`isValidHeaderChar# ${json}`, () => {
bench('regexp.test', () => {
return !headerCharRegex.test(json)
})
bench('regexp.exec', () => {
return headerCharRegex.exec(json) === null
})
bench('charCodeAt', () => {
return charCodeAtApproach(json)
})
bench('isValidHeaderChar', () => {
return isValidHeaderChar(json)
})
})
await run()
================================================
FILE: benchmarks/core/is-valid-port.mjs
================================================
import { bench, group, run } from 'mitata'
import { isValidPort } from '../../lib/core/util.js'
const string = '1234'
const number = 1234
group('isValidPort', () => {
bench('string', () => {
return isValidPort(string)
})
bench('number', () => {
return isValidPort(number)
})
})
await run()
================================================
FILE: benchmarks/core/parse-headers.mjs
================================================
import { bench, group, run } from 'mitata'
import { parseHeaders } from '../../lib/core/util.js'
const target = [
{
'Content-Type': 'application/json',
Date: 'Wed, 01 Nov 2023 00:00:00 GMT',
'Powered-By': 'NodeJS',
'Content-Encoding': 'gzip',
'Set-Cookie': '__Secure-ID=123; Secure; Domain=example.com',
'Content-Length': '150',
Vary: 'Accept-Encoding, Accept, X-Requested-With'
},
{
'Content-Type': 'text/html; charset=UTF-8',
'Content-Length': '1234',
Date: 'Wed, 06 Dec 2023 12:47:57 GMT',
Server: 'Bing'
},
{
'Content-Type': 'image/jpeg',
'Content-Length': '56789',
Date: 'Wed, 06 Dec 2023 12:48:12 GMT',
Server: 'Bing',
ETag: '"a1b2c3d4e5f6g7h8i9j0"'
},
{
Cookie: 'session_id=1234567890abcdef',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
Host: 'www.bing.com',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br'
},
{
Location: 'https://www.bing.com/search?q=bing',
Status: '302 Found',
Date: 'Wed, 06 Dec 2023 12:48:27 GMT',
Server: 'Bing',
'Content-Type': 'text/html; charset=UTF-8',
'Content-Length': '0'
},
{
'Content-Type':
'multipart/form-data; boundary=----WebKitFormBoundary1234567890',
'Content-Length': '98765',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
Host: 'www.bing.com',
Accept: '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br'
},
{
'Content-Type': 'application/json; charset=UTF-8',
'Content-Length': '2345',
Date: 'Wed, 06 Dec 2023 12:48:42 GMT',
Server: 'Bing',
Status: '200 OK',
'Cache-Control': 'no-cache, no-store, must-revalidate'
},
{
Host: 'www.example.com',
Connection: 'keep-alive',
Accept: 'text/html, application/xhtml+xml, application/xml;q=0.9,;q=0.8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
]
const headers = Array.from(target, (x) =>
Object.entries(x)
.flat()
.map((c) => Buffer.from(c))
)
const headersIrregular = Array.from(
target,
(x) => Object.entries(x)
.flat()
.map((c) => Buffer.from(c.toUpperCase()))
)
// avoid JIT bias
bench('noop', () => {})
bench('noop', () => {})
bench('noop', () => {})
bench('noop', () => {})
bench('noop', () => {})
bench('noop', () => {})
group('parseHeaders', () => {
bench('parseHeaders', () => {
for (let i = 0; i < headers.length; ++i) {
parseHeaders(headers[i])
}
})
bench('parseHeaders (irregular)', () => {
for (let i = 0; i < headersIrregular.length; ++i) {
parseHeaders(headersIrregular[i])
}
})
})
await new Promise((resolve) => setTimeout(resolve, 7000))
await run()
================================================
FILE: benchmarks/core/parse-raw-headers.mjs
================================================
import { bench, group, run } from 'mitata'
import { parseRawHeaders } from '../../lib/core/util.js'
const rawHeadersMixed = ['key', 'value', Buffer.from('key'), Buffer.from('value')]
const rawHeadersOnlyStrings = ['key', 'value', 'key', 'value']
const rawHeadersOnlyBuffers = [Buffer.from('key'), Buffer.from('value'), Buffer.from('key'), Buffer.from('value')]
const rawHeadersContent = ['content-length', 'value', 'content-disposition', 'form-data; name="fieldName"']
group('parseRawHeaders', () => {
bench('only strings', () => {
parseRawHeaders(rawHeadersOnlyStrings)
})
bench('only buffers', () => {
parseRawHeaders(rawHeadersOnlyBuffers)
})
bench('mixed', () => {
parseRawHeaders(rawHeadersMixed)
})
bench('content-disposition special case', () => {
parseRawHeaders(rawHeadersContent)
})
})
await run()
================================================
FILE: benchmarks/core/request-instantiation.mjs
================================================
import { bench, run } from 'mitata'
import Request from '../../lib/core/request.js'
import DecoratorHandler from '../../lib/handler/decorator-handler.js'
const handler = new DecoratorHandler({})
bench('new Request()', () => {
return new Request('https://localhost', { path: '/', method: 'get', body: null }, handler)
})
await run()
================================================
FILE: benchmarks/core/tree.mjs
================================================
import { bench, group, run } from 'mitata'
import { tree } from '../../lib/core/tree.js'
const contentLength = Buffer.from('Content-Length')
const contentLengthUpperCase = Buffer.from('Content-Length'.toUpperCase())
const contentLengthLowerCase = Buffer.from('Content-Length'.toLowerCase())
group('tree.search', () => {
bench('content-length', () => {
tree.lookup(contentLengthLowerCase)
})
bench('CONTENT-LENGTH', () => {
tree.lookup(contentLengthUpperCase)
})
bench('Content-Length', () => {
tree.lookup(contentLength)
})
})
await run()
================================================
FILE: benchmarks/fetch/body-arraybuffer.mjs
================================================
import { group, bench, run } from 'mitata'
import { Response } from '../../lib/web/fetch/response.js'
const settings = {
small: 2 << 8,
middle: 2 << 12,
long: 2 << 16
}
for (const [name, length] of Object.entries(settings)) {
const buffer = Buffer.allocUnsafe(length).map(() => (Math.random() * 100) | 0)
group(`${name} (length ${length})`, () => {
bench('Response#arrayBuffer', async () => {
return await new Response(buffer).arrayBuffer()
})
// for comparison
bench('Response#text', async () => {
return await new Response(buffer).text()
})
})
}
await run()
================================================
FILE: benchmarks/fetch/bytes-match.mjs
================================================
import { createHash } from 'node:crypto'
import { bench, run } from 'mitata'
import { bytesMatch } from '../../lib/web/fetch/util.js'
const body = Buffer.from('Hello world!')
const validSha256Base64 = `sha256-${createHash('sha256').update(body).digest('base64')}`
const invalidSha256Base64 = `sha256-${createHash('sha256').update(body).digest('base64')}`
const validSha256Base64Url = `sha256-${createHash('sha256').update(body).digest('base64url')}`
const invalidSha256Base64Url = `sha256-${createHash('sha256').update(body).digest('base64url')}`
bench('bytesMatch valid sha256 and base64', () => {
bytesMatch(body, validSha256Base64)
})
bench('bytesMatch invalid sha256 and base64', () => {
bytesMatch(body, invalidSha256Base64)
})
bench('bytesMatch valid sha256 and base64url', () => {
bytesMatch(body, validSha256Base64Url)
})
bench('bytesMatch invalid sha256 and base64url', () => {
bytesMatch(body, invalidSha256Base64Url)
})
await run()
================================================
FILE: benchmarks/fetch/headers-length32.mjs
================================================
import { bench, run } from 'mitata'
import { Headers, getHeadersList } from '../../lib/web/fetch/headers.js'
const headers = new Headers(
[
'Origin-Agent-Cluster',
'RTT',
'Accept-CH-Lifetime',
'X-Frame-Options',
'Sec-CH-UA-Platform-Version',
'Digest',
'Cache-Control',
'Sec-CH-UA-Platform',
'If-Range',
'SourceMap',
'Strict-Transport-Security',
'Want-Digest',
'Cross-Origin-Resource-Policy',
'Width',
'Accept-CH',
'Via',
'Set-Cookie',
'Server',
'Sec-Fetch-Dest',
'Sec-CH-UA-Model',
'Access-Control-Request-Method',
'Access-Control-Request-Headers',
'Date',
'Expires',
'DNT',
'Proxy-Authorization',
'Alt-Svc',
'Alt-Used',
'ETag',
'Sec-Fetch-User',
'Sec-CH-UA-Full-Version-List',
'Referrer-Policy'
].map((v) => [v, ''])
)
const headersList = getHeadersList(headers)
const kHeadersSortedMap = Reflect.ownKeys(headersList).find(
(c) => String(c) === 'Symbol(headers map sorted)'
)
bench('Headers@@iterator', () => {
headersList[kHeadersSortedMap] = null
return [...headers]
})
await run()
================================================
FILE: benchmarks/fetch/headers.mjs
================================================
import { bench, group, run } from 'mitata'
import { Headers, getHeadersList } from '../../lib/web/fetch/headers.js'
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
const charactersLength = characters.length
function generateAsciiString (length) {
let result = ''
for (let i = 0; i < length; ++i) {
result += characters[Math.floor(Math.random() * charactersLength)]
}
return result
}
const settings = {
'fast-path (tiny array)': 4,
'fast-path (small array)': 8,
'fast-path (middle array)': 16,
'fast-path': 32,
'slow-path': 64
}
for (const [name, length] of Object.entries(settings)) {
const headers = new Headers(
Array.from(Array(length), () => [generateAsciiString(12), ''])
)
const headersSorted = new Headers(headers)
const headersList = getHeadersList(headers)
const headersListSorted = getHeadersList(headersSorted)
const kHeadersSortedMap = Reflect.ownKeys(headersList).find(
(c) => String(c) === 'Symbol(headers map sorted)'
)
group(`length ${length} #${name}`, () => {
bench('Headers@@iterator', () => {
// prevention of memoization of results
headersList[kHeadersSortedMap] = null
return [...headers]
})
bench('Headers@@iterator (sorted)', () => {
// prevention of memoization of results
headersListSorted[kHeadersSortedMap] = null
return [...headersSorted]
})
})
}
await run()
================================================
FILE: benchmarks/fetch/is-valid-encoded-url.mjs
================================================
import { bench, run } from 'mitata'
import { isValidEncodedURL } from '../../lib/web/fetch/util.js'
const validUrl = 'https://example.com'
const invalidUrl = 'https://example.com\x00'
bench('isValidEncodedURL valid', () => {
isValidEncodedURL(validUrl)
})
bench('isValidEncodedURL invalid', () => {
isValidEncodedURL(invalidUrl)
})
await run()
================================================
FILE: benchmarks/fetch/is-valid-header-value.mjs
================================================
import { bench, run } from 'mitata'
import { isValidHeaderValue } from '../../lib/web/fetch/util.js'
const valid = 'valid123'
const invalidNUL = 'invalid\x00'
const invalidCR = 'invalid\r'
const invalidLF = 'invalid\n'
const invalidTrailingTab = 'invalid\t'
const invalidLeadingTab = '\tinvalid'
const invalidTrailingSpace = 'invalid '
const invalidLeadingSpace = ' invalid'
bench('isValidHeaderValue valid', () => {
isValidHeaderValue(valid)
})
bench('isValidHeaderValue invalid containing NUL', () => {
isValidHeaderValue(invalidNUL)
})
bench('isValidHeaderValue invalid containing CR', () => {
isValidHeaderValue(invalidCR)
})
bench('isValidHeaderValue invalid containing LF', () => {
isValidHeaderValue(invalidLF)
})
bench('isValidHeaderValue invalid trailing TAB', () => {
isValidHeaderValue(invalidTrailingTab)
})
bench('isValidHeaderValue invalid leading TAB', () => {
isValidHeaderValue(invalidLeadingTab)
})
bench('isValidHeaderValue invalid trailing SPACE', () => {
isValidHeaderValue(invalidTrailingSpace)
})
bench('isValidHeaderValue invalid leading SPACE', () => {
isValidHeaderValue(invalidLeadingSpace)
})
await run()
================================================
FILE: benchmarks/fetch/isomorphic-encode.mjs
================================================
import { bench, group, run } from 'mitata'
import { isomorphicEncode } from '../../lib/web/fetch/util.js'
const characters =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
const charactersLength = characters.length
function generateAsciiString (length) {
let result = ''
for (let i = 0; i < length; ++i) {
result += characters[Math.floor(Math.random() * charactersLength)]
}
return result
}
const invalidIsomorphicEncodeValueRegex = /[^\x00-\xFF]/ // eslint-disable-line
function isomorphicEncode1 (input) {
for (let i = 0; i < input.length; i++) {
if (input.charCodeAt(i) > 0xff) {
throw new TypeError('Unreachable')
}
}
return input
}
function isomorphicEncode2 (input) {
if (invalidIsomorphicEncodeValueRegex.test(input)) {
throw new TypeError('Unreachable')
}
return input
}
const settings = {
small: 10,
middle: 30,
long: 70
}
for (const [runName, length] of Object.entries(settings)) {
const value = generateAsciiString(length);
[
{ name: `${runName} (valid)`, value },
{
name: `${runName} (invalid)`,
value: `${value.slice(0, -1)}${String.fromCharCode(0xff + 1)}`
}
].forEach(({ name, value }) => {
group(name, () => {
[
{
name: 'original',
fn: isomorphicEncode
},
{
name: 'String#charCodeAt',
fn: isomorphicEncode1
},
{
name: 'RegExp#test',
fn: isomorphicEncode2
}
].forEach(({ name, fn }) => {
bench(name, () => {
try {
return fn(value)
} catch (err) {}
})
})
})
})
}
await run()
================================================
FILE: benchmarks/fetch/request-creation.mjs
================================================
import { bench, run } from 'mitata'
import { Request } from '../../lib/web/fetch/request.js'
const input = 'https://example.com/post'
bench('new Request(input)', () => new Request(input, undefined))
await run()
================================================
FILE: benchmarks/fetch/url-has-https-scheme.mjs
================================================
import { bench, run } from 'mitata'
import { urlHasHttpsScheme } from '../../lib/web/fetch/util.js'
const httpString = 'http://example.com'
const httpObject = { protocol: 'http:' }
const httpsString = 'https://example.com'
const httpsObject = { protocol: 'https:' }
bench('urlHasHttpsScheme "http:" String', () => {
urlHasHttpsScheme(httpString)
})
bench('urlHasHttpsScheme "https:" String', () => {
urlHasHttpsScheme(httpsString)
})
bench('urlHasHttpsScheme "http:" Object', () => {
urlHasHttpsScheme(httpObject)
})
bench('urlHasHttpsScheme "https:" Object', () => {
urlHasHttpsScheme(httpsObject)
})
await run()
================================================
FILE: benchmarks/package.json
================================================
{
"name": "benchmarks",
"scripts": {
"bench": "PORT=3042 concurrently -k -s first npm:bench:server npm:bench:run",
"bench:h2": "PORT=3052 concurrently -k -s first npm:bench:server:h2 npm:bench:run:h2",
"bench-post": "PORT=3042 concurrently -k -s first npm:bench:server npm:bench-post:run",
"bench:server": "node ./server.js",
"bench:server:h2": "node ./server-http2.js",
"prebench:run": "node ./wait.js",
"bench:run": "SAMPLES=100 CONNECTIONS=50 node ./benchmark.js",
"bench:run:h2": "SAMPLES=100 CONNECTIONS=50 node ./benchmark-http2.js",
"prebench-post:run": "node ./wait.js",
"bench-post:run": "SAMPLES=100 CONNECTIONS=50 node ./post-benchmark.js"
},
"dependencies": {
"axios": "^1.6.7",
"concurrently": "^9.0.0",
"cronometro": "^5.3.0",
"got": "^14.2.0",
"mitata": "^1.0.4",
"node-fetch": "^3.3.2",
"request": "^2.88.2",
"superagent": "^10.0.0",
"tinybench": "^5.0.0",
"uWebSockets.js": "uNetworking/uWebSockets.js#v20.58.0",
"wait-on": "^9.0.1"
}
}
================================================
FILE: benchmarks/post-benchmark.js
================================================
'use strict'
const http = require('node:http')
const os = require('node:os')
const path = require('node:path')
const { Writable, Readable, pipeline } = require('node:stream')
const { isMainThread } = require('node:worker_threads')
const { Pool, Client, fetch, Agent, setGlobalDispatcher } = require('..')
const { makeParallelRequests, printResults } = require('./_util')
let nodeFetch
const axios = require('axios')
let superagent
let got
const { promisify } = require('node:util')
const request = promisify(require('request'))
const iterations = (parseInt(process.env.SAMPLES, 10) || 10) + 1
const errorThreshold = parseInt(process.env.ERROR_THRESHOLD, 10) || 3
const connections = parseInt(process.env.CONNECTIONS, 10) || 50
const pipelining = parseInt(process.env.PIPELINING, 10) || 10
const headersTimeout = parseInt(process.env.HEADERS_TIMEOUT, 10) || 0
const bodyTimeout = parseInt(process.env.BODY_TIMEOUT, 10) || 0
const dest = {}
const data = '_'.repeat(128 * 1024)
const dataLength = `${Buffer.byteLength(data)}`
if (process.env.PORT) {
dest.port = process.env.PORT
dest.url = `http://localhost:${process.env.PORT}`
} else {
dest.url = 'http://localhost'
dest.socketPath = path.join(os.tmpdir(), 'undici.sock')
}
const headers = {
'Content-Type': 'text/plain; charset=UTF-8',
'Content-Length': dataLength
}
/** @type {http.RequestOptions} */
const httpBaseOptions = {
protocol: 'http:',
hostname: 'localhost',
method: 'POST',
path: '/',
headers,
...dest
}
/** @type {http.RequestOptions} */
const httpNoKeepAliveOptions = {
...httpBaseOptions,
agent: new http.Agent({
keepAlive: false,
maxSockets: connections
})
}
/** @type {http.RequestOptions} */
const httpKeepAliveOptions = {
...httpBaseOptions,
agent: new http.Agent({
keepAlive: true,
maxSockets: connections
})
}
const axiosAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const fetchAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const gotAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const requestAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
const superagentAgent = new http.Agent({
keepAlive: true,
maxSockets: connections
})
/** @type {import("..").Dispatcher.DispatchOptions} */
const undiciOptions = {
path: '/',
method: 'POST',
headersTimeout,
bodyTimeout,
body: data,
headers
}
const Class = connections > 1 ? Pool : Client
const dispatcher = new Class(httpBaseOptions.url, {
pipelining,
connections,
...dest
})
setGlobalDispatcher(new Agent({
pipelining,
connections,
connect: {
rejectUnauthorized: false
}
}))
class SimpleRequest {
constructor (resolve) {
this.dst = new Writable({
write (chunk, encoding, callback) {
callback()
}
}).on('finish', resolve)
}
onConnect (abort) { }
onHeaders (statusCode, headers, resume) {
this.dst.on('drain', resume)
}
onData (chunk) {
return this.dst.write(chunk)
}
onComplete () {
this.dst.end()
}
onError (err) {
throw err
}
}
const experiments = {
'http - no keepalive' () {
return makeParallelRequests(resolve => {
const request = http.request(httpNoKeepAliveOptions, res => {
res
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
request.end(data)
})
},
'http - keepalive' () {
return makeParallelRequests(resolve => {
const request = http.request(httpKeepAliveOptions, res => {
res
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
request.end(data)
})
},
'undici - pipeline' () {
return makeParallelRequests(resolve => {
pipeline(
new Readable({
read () {
this.push(data)
this.push(null)
}
}),
dispatcher.pipeline(undiciOptions, ({ body }) => {
return body
}),
new Writable({
write (chunk, encoding, callback) {
callback()
}
}),
(err) => {
if (err != null) {
console.log(err)
}
resolve()
}
)
})
},
'undici - request' () {
return makeParallelRequests(resolve => {
dispatcher.request(undiciOptions).then(({ body }) => {
body
.pipe(
new Writable({
write (chunk, encoding, callback) {
callback()
}
})
)
.on('finish', resolve)
})
})
},
'undici - stream' () {
return makeParallelRequests(resolve => {
return dispatcher
.stream(undiciOptions, () => {
return new Writable({
write (chunk, encoding, callback) {
callback()
}
})
})
.then(resolve)
})
},
'undici - dispatch' () {
return makeParallelRequests(resolve => {
dispatcher.dispatch(undiciOptions, new SimpleRequest(resolve))
})
}
}
if (process.env.PORT) {
/** @type {RequestInit} */
const fetchOptions = {
method: 'POST',
body: data,
headers
}
// fetch does not support the socket
experiments['undici - fetch'] = () => {
return makeParallelRequests(resolve => {
fetch(dest.url, fetchOptions).then(res => {
res.body.pipeTo(new WritableStream({ write () { }, close () { resolve() } }))
}).catch(console.log)
})
}
const nodeFetchOptions = {
...fetchOptions,
agent: fetchAgent
}
experiments['node-fetch'] = () => {
return makeParallelRequests(resolve => {
nodeFetch(dest.url, nodeFetchOptions).then(res => {
res.body.pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
}).catch(console.log)
})
}
const axiosOptions = {
url: dest.url,
method: 'POST',
headers,
responseType: 'stream',
httpAgent: axiosAgent,
data
}
experiments.axios = () => {
return makeParallelRequests(resolve => {
axios.request(axiosOptions).then(res => {
res.data.pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
}).catch(console.log)
})
}
const gotOptions = {
url: dest.url,
method: 'POST',
headers,
agent: {
http: gotAgent
},
// avoid body processing
isStream: true,
body: data
}
experiments.got = () => {
return makeParallelRequests(resolve => {
got(gotOptions).pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
})
}
const requestOptions = {
url: dest.url,
method: 'POST',
headers,
agent: requestAgent,
body: data,
// avoid body toString
encoding: null
}
experiments.request = () => {
return makeParallelRequests(resolve => {
request(requestOptions).then(() => {
// already body consumed
resolve()
}).catch(console.log)
})
}
experiments.superagent = () => {
return makeParallelRequests(resolve => {
superagent
.post(dest.url)
.send(data)
.set('Content-Type', 'text/plain; charset=UTF-8')
.set('Content-Length', dataLength)
.pipe(new Writable({
write (chunk, encoding, callback) {
callback()
}
})).on('finish', resolve)
})
}
}
async function main () {
const { cronometro } = await import('cronometro')
const _nodeFetch = await import('node-fetch')
nodeFetch = _nodeFetch.default
const _got = await import('got')
got = _got.default
const _superagent = await import('superagent')
// https://github.com/ladjs/superagent/issues/1540#issue-561464561
superagent = _superagent.agent().use((req) => req.agent(superagentAgent))
cronometro(
experiments,
{
iterations,
errorThreshold,
print: false
},
(err, results) => {
if (err) {
throw err
}
printResults(results)
dispatcher.destroy()
}
)
}
if (isMainThread) {
main()
} else {
module.exports = main
}
================================================
FILE: benchmarks/server-http2.js
================================================
'use strict'
const { unlinkSync, readFileSync } = require('node:fs')
const { createSecureServer } = require('node:http2')
const os = require('node:os')
const path = require('node:path')
const cluster = require('node:cluster')
const key = readFileSync(path.join(__dirname, '..', 'test', 'fixtures', 'key.pem'), 'utf8')
const cert = readFileSync(path.join(__dirname, '..', 'test', 'fixtures', 'cert.pem'), 'utf8')
const socketPath = path.join(os.tmpdir(), 'undici.sock')
const port = process.env.PORT || socketPath
const timeout = parseInt(process.env.TIMEOUT, 10) || 1
const workers = parseInt(process.env.WORKERS) || os.cpus().length
const sessionTimeout = 600e3 // 10 minutes
if (cluster.isPrimary) {
try {
unlinkSync(socketPath)
} catch (_) {
// Do nothing if the socket does not exist
}
for (let i = 0; i < workers; i++) {
cluster.fork()
}
} else {
const buf = Buffer.alloc(64 * 1024, '_')
const server = createSecureServer(
{
key,
cert,
allowHTTP1: true,
sessionTimeout
}
)
server.on('stream', (stream) => {
setTimeout(() => {
stream.setEncoding('utf-8').end(buf)
}, timeout)
stream.respond({
'content-type': 'text/plain; charset=utf-8',
':status': 200
})
})
server.keepAliveTimeout = 600e3
server.listen(port)
}
================================================
FILE: benchmarks/server-https.js
================================================
'use strict'
const { unlinkSync, readFileSync } = require('node:fs')
const { createServer } = require('node:https')
const os = require('node:os')
const path = require('node:path')
const cluster = require('node:cluster')
const key = readFileSync(path.join(__dirname, '..', 'test', 'fixtures', 'key.pem'), 'utf8')
const cert = readFileSync(path.join(__dirname, '..', 'test', 'fixtures', 'cert.pem'), 'utf8')
const socketPath = path.join(os.tmpdir(), 'undici.sock')
const port = process.env.PORT || socketPath
const timeout = parseInt(process.env.TIMEOUT, 10) || 1
const workers = parseInt(process.env.WORKERS) || os.cpus().length
if (cluster.isPrimary) {
try {
unlinkSync(socketPath)
} catch (_) {
// Do nothing if the socket does not exist
}
for (let i = 0; i < workers; i++) {
cluster.fork()
}
} else {
const buf = Buffer.alloc(64 * 1024, '_')
const server = createServer({
key,
cert,
keepAliveTimeout: 600e3
}, (req, res) => {
setTimeout(() => {
res.end(buf)
}, timeout)
})
server.listen(port)
}
================================================
FILE: benchmarks/server.js
================================================
'use strict'
const { unlinkSync } = require('node:fs')
const { createServer } = require('node:http')
const os = require('node:os')
const path = require('node:path')
const cluster = require('node:cluster')
const socketPath = path.join(os.tmpdir(), 'undici.sock')
const port = process.env.PORT || socketPath
const timeout = parseInt(process.env.TIMEOUT, 10) || 1
const workers = parseInt(process.env.WORKERS) || os.cpus().length
if (cluster.isPrimary) {
try {
unlinkSync(socketPath)
} catch (_) {
// Do nothing if the socket does not exist
}
for (let i = 0; i < workers; i++) {
cluster.fork()
}
} else {
const buf = Buffer.alloc(64 * 1024, '_')
const headers = {
'Content-Length': `${buf.byteLength}`,
'Content-Type': 'text/plain; charset=UTF-8'
}
let i = 0
const server = createServer((_req, res) => {
i++
setTimeout(() => {
res.writeHead(200, headers)
res.end(buf)
}, timeout)
}).listen(port)
server.keepAliveTimeout = 600e3
setInterval(() => {
console.log(`Worker ${process.pid} processed ${i} requests`)
}, 5000)
}
================================================
FILE: benchmarks/timers/compare-timer-getters.mjs
================================================
import { bench, group, run } from 'mitata'
group('timers', () => {
bench('Date.now()', () => {
Date.now()
})
bench('performance.now()', () => {
performance.now()
})
bench('Math.trunc(performance.now())', () => {
Math.trunc(performance.now())
})
bench('process.uptime()', () => {
process.uptime()
})
})
await run()
================================================
FILE: benchmarks/utils/date.mjs
================================================
import { Bench } from 'tinybench'
import { parseHttpDate } from '../../lib/util/date.js'
const asctime = 'Sun Nov 6 08:49:37 1994'
const rfc850 = 'Sunday, 06-Nov-94 08:49:37 GMT'
const imf = 'Sun, 06 Nov 1994 08:49:37 GMT'
console.assert(parseHttpDate(asctime) instanceof Date, 'asctime should return a Date')
console.assert(parseHttpDate(rfc850) instanceof Date, 'rfc850 should return a Date')
console.assert(parseHttpDate(imf) instanceof Date, 'imf should return a Date')
const bench = new Bench({ name: 'parseHttpDate' })
bench
.add('asctime', () => {
parseHttpDate(asctime)
})
.add('rfc850', () => {
parseHttpDate(rfc850)
})
.add('imf', () => {
parseHttpDate(imf)
})
await bench.run()
console.log(bench.name)
console.table(bench.table())
================================================
FILE: benchmarks/wait.js
================================================
'use strict'
const os = require('node:os')
const path = require('node:path')
const waitOn = require('wait-on')
const socketPath = path.join(os.tmpdir(), 'undici.sock')
let resources
if (process.env.PORT) {
resources = [`http-get://localhost:${process.env.PORT}/`]
} else {
resources = [`http-get://unix:${socketPath}:/`]
}
waitOn({
resources,
timeout: 5000
}).catch((err) => {
console.error(err)
process.exitCode = 1
})
================================================
FILE: benchmarks/webidl/webidl-is.mjs
================================================
import { bench, run, barplot } from 'mitata'
import { Headers, FormData } from '../../index.js'
import { webidl } from '../../lib/web/webidl/index.js'
const headers = new Headers()
const fd = new FormData()
barplot(() => {
bench('webidl.is.FormData (ok)', () => {
return webidl.is.FormData(fd)
})
bench('webidl.is.FormData (bad)', () => {
return !webidl.is.FormData(headers)
})
bench('instanceof (ok)', () => {
return fd instanceof FormData
})
bench('instanceof (bad)', () => {
return !(headers instanceof FormData)
})
})
await run()
================================================
FILE: benchmarks/websocket/generate-mask.mjs
================================================
import { randomBytes } from 'node:crypto'
import { bench, summary, run } from 'mitata'
import { generateMask } from '../../lib/web/websocket/frame.js'
summary(() => {
bench('generateMask', () => generateMask())
bench('crypto.randomBytes(4)', () => randomBytes(4))
})
await run()
================================================
FILE: benchmarks/websocket/is-valid-subprotocol.mjs
================================================
import { bench, group, run } from 'mitata'
import { isValidSubprotocol } from '../../lib/web/websocket/util.js'
const valid = 'valid'
const invalid = 'invalid '
group('isValidSubprotocol', () => {
bench(`valid: ${valid}`, () => {
return isValidSubprotocol(valid)
})
bench(`invalid: ${invalid}`, () => {
return isValidSubprotocol(invalid)
})
})
await run()
================================================
FILE: benchmarks/websocket/messageevent.mjs
================================================
import { bench, group, run } from 'mitata'
import { createFastMessageEvent, MessageEvent as UndiciMessageEvent } from '../../lib/web/websocket/events.js'
const { port1, port2 } = new MessageChannel()
group('MessageEvent instantiation', () => {
bench('undici - fast MessageEvent init', () => {
return createFastMessageEvent('event', { data: null, ports: [port1, port2] })
})
bench('undici - MessageEvent init', () => {
return new UndiciMessageEvent('event', { data: null, ports: [port1, port2] })
})
bench('global - MessageEvent init', () => {
// eslint-disable-next-line no-restricted-globals
return new MessageEvent('event', { data: null, ports: [port1, port2] })
})
})
await run()
================================================
FILE: benchmarks/websocket-benchmark.mjs
================================================
// @ts-check
import { bench } from './_util/runner.js'
import { formatBytes } from './_util/index.js'
import { WebSocket, WebSocketStream } from '../index.js'
import { WebSocket as WsWebSocket } from 'ws'
/**
* @type {Record<string, { fn: (ws: any, binary: string | Uint8Array) => import('./_util/runner.js').BenchMarkHandler; connect: (url: string) => Promise<any>; binaries: (string | Uint8Array)[] }>}
*/
const experiments = {}
/**
* @type {Record<string, { bytes: number; binaryType: 'string' | 'binary' }>}
*/
const experimentsInfo = {}
/**
* @type {any[]}
*/
const connections = []
const binary = Buffer.alloc(256 * 1024, '_')
const binaries = [binary, binary.subarray(0, 256 * 1024).toString('utf-8')]
experiments['undici'] = {
fn: (ws, binary) => {
if (!(ws instanceof WebSocket)) {
throw new Error("'undici' websocket are expected.")
}
return (ev) => {
ws.addEventListener(
'message',
() => {
ev.end()
},
{ once: true }
)
ev.start()
ws.send(binary)
}
},
connect: async (url) => {
const ws = new WebSocket(url)
await /** @type {Promise<void>} */ (
new Promise((resolve, reject) => {
function onOpen () {
resolve()
ws.removeEventListener('open', onOpen)
ws.removeEventListener('error', onError)
}
function onError (err) {
reject(err)
ws.removeEventListener('open', onOpen)
ws.removeEventListener('error', onError)
}
ws.addEventListener('open', onOpen)
ws.addEventListener('error', onError)
})
)
// avoid create blob
ws.binaryType = 'arraybuffer'
return ws
},
binaries
}
experiments['undici - stream'] = {
fn: (ws, binary) => {
/** @type {ReadableStreamDefaultReader<string | Uint8Array>} */
const reader = ws.reader
/** @type {WritableStreamDefaultWriter<string | BufferSource>} */
const writer = ws.writer
return async (ev) => {
ev.start()
await writer.write(binary)
await reader.read()
ev.end()
}
},
connect: async (url) => {
const ws = new WebSocketStream(url)
const { readable, writable } = await ws.opened
const reader = readable.getReader()
const writer = writable.getWriter()
// @ts-ignore
return { reader, writer, close: () => ws.close() }
},
binaries
}
experiments['ws'] = {
fn: (ws, binary) => {
if (!(ws instanceof WsWebSocket)) {
throw new Error("'ws' websocket are expected.")
}
return (ev) => {
ws.once('message', () => {
ev.end()
})
ev.start()
ws.send(binary)
}
},
connect: async (url) => {
const ws = new WsWebSocket(url, { maxPayload: 1024 * 1024 * 1024 })
await /** @type {Promise<void>} */ (
new Promise((resolve, reject) => {
function onOpen () {
resolve()
ws.off('open', onOpen)
ws.off('error', onError)
}
function onError (err) {
reject(err)
ws.off('open', onOpen)
ws.off('error', onError)
}
ws.on('open', onOpen)
ws.on('error', onError)
})
)
ws.binaryType = 'arraybuffer'
return ws
},
binaries
}
async function init () {
/** @type {Record<string, import('./_util/runner.js').BenchMarkHandler>} */
const round = {}
const keys = Object.keys(experiments)
for (let i = 0; i < keys.length; ++i) {
const name = keys[i]
const { fn, connect, binaries } = experiments[name]
const ws = await connect('ws://localhost:8080')
const needShowBytes = binaries.length !== 2 || typeof binaries[0] === typeof binaries[1]
for (let i = 0; i < binaries.length; ++i) {
const binary = binaries[i]
const bytes = Buffer.byteLength(binary)
const binaryType = typeof binary === 'string' ? 'string' : 'binary'
const roundName = needShowBytes
? `${name} [${formatBytes(bytes)} (${binaryType})]`
: `${name} [${binaryType}]`
round[roundName] = fn(ws, binary)
experimentsInfo[roundName] = { bytes, binaryType }
}
connections.push(ws)
}
return round
}
init()
.then((round) => bench(round, {
minSamples: 2048
}))
.then((results) => {
print(results)
for (const ws of connections) {
ws.close()
}
}, (err) => {
process.nextTick((err) => {
throw err
}, err)
})
/**
* @param {{ name: string; average: number; iterationPerSecond: number; }[]} results
*/
function print (results) {
for (const { name, average, iterationPerSecond } of results) {
const { bytes } = experimentsInfo[name]
console.log(
`${name}: transferred ${formatBytes((bytes / average) * 1e9)} Bytes/s (${iterationPerSecond.toFixed(4)} per/sec)`
)
}
}
export {}
================================================
FILE: benchmarks/websocket-echo-server.mjs
================================================
import { Worker, isMainThread, parentPort, threadId } from 'node:worker_threads'
import { cpus } from 'node:os'
import url from 'node:url'
import uws from 'uWebSockets.js'
const __filename = url.fileURLToPath(import.meta.url)
const app = uws.App()
if (isMainThread) {
for (let i = cpus().length - 1; i >= 0; --i) {
new Worker(__filename).on('message', (workerAppDescriptor) => {
app.addChildAppDescriptor(workerAppDescriptor)
})
}
} else {
app
.ws('/*', {
compression: uws.DISABLED,
maxPayloadLength: 1024 * 1024 * 1024,
maxBackpressure: 1 * 1024 * 1024,
idleTimeout: 60,
message: (ws, message, isBinary) => {
/* Here we echo the message back, using compression if available */
const ok = ws.send(message, isBinary) // eslint-disable-line
}
})
.get('/*', (res, req) => {
/* It does Http as well */
res
.writeStatus('200 OK')
.end('Hello there!')
})
parentPort.postMessage(app.getDescriptor())
}
app.listen(8080, (listenSocket) => {
if (listenSocket) {
if (threadId === 0) {
console.log('Listening to port 8080')
} else {
console.log(`Listening to port 8080 from thread ${threadId}`)
}
}
})
================================================
FILE: build/wasm.js
================================================
'use strict'
const WASM_BUILDER_CONTAINER = 'ghcr.io/nodejs/wasm-builder@sha256:975f391d907e42a75b8c72eb77c782181e941608687d4d8694c3e9df415a0970' // v0.0.9
const { execSync, execFileSync } = require('node:child_process')
const { writeFileSync, readFileSync } = require('node:fs')
const { join, resolve } = require('node:path')
const ROOT = resolve(__dirname, '../')
const WASM_SRC = resolve(__dirname, '../deps/llhttp')
const WASM_OUT = resolve(__dirname, '../lib/llhttp')
// These are defined by build environment
const WASM_CC = process.env.WASM_CC || 'clang'
let WASM_CFLAGS = process.env.WASM_CFLAGS || '--sysroot=/usr/share/wasi-sysroot -target wasm32-unknown-wasi'
let WASM_LDFLAGS = process.env.WASM_LDFLAGS || ''
const WASM_LDLIBS = process.env.WASM_LDLIBS || ''
const WASM_OPT = process.env.WASM_OPT || 'wasm-opt'
// For compatibility with Node.js' `configure --shared-builtin-undici/undici-path ...`
const EXTERNAL_PATH = process.env.EXTERNAL_PATH
// These are relevant for undici and should not be overridden
WASM_CFLAGS += ' -Ofast -fno-exceptions -fvisibility=hidden -mexec-model=reactor'
WASM_LDFLAGS += ' -Wl,-error-limit=0 -Wl,-O3 -Wl,--lto-O3 -Wl,--strip-all'
WASM_LDFLAGS += ' -Wl,--allow-undefined -Wl,--export-dynamic -Wl,--export-table'
WASM_LDFLAGS += ' -Wl,--export=malloc -Wl,--export=free -Wl,--no-entry'
const WASM_OPT_FLAGS = '-O4 --converge --strip-debug --strip-dwarf --strip-producers'
const writeWasmChunk = (path, dest) => {
const base64 = readFileSync(join(WASM_OUT, path)).toString('base64')
writeFileSync(join(WASM_OUT, dest), `'use strict'
const { Buffer } = require('node:buffer')
const wasmBase64 = '${base64}'
let wasmBuffer
Object.defineProperty(module, 'exports', {
get: () => {
return wasmBuffer
? wasmBuffer
: (wasmBuffer = Buffer.from(wasmBase64, 'base64'))
}
})
`)
}
let platform = process.env.WASM_PLATFORM
if (!platform && process.argv[2]) {
platform = execSync('docker info -f "{{.OSType}}/{{.Architecture}}"').toString().trim()
}
if (process.argv[2] === '--docker') {
let cmd = `docker run --rm --platform=${platform.toString().trim()} `
if (process.platform === 'linux') {
cmd += ` --user ${process.getuid()}:${process.getegid()}`
}
cmd += ` --mount type=bind,source=${ROOT}/lib/llhttp,target=/home/node/build/lib/llhttp \
--mount type=bind,source=${ROOT}/build,target=/home/node/build/build \
--mount type=bind,source=${ROOT}/deps,target=/home/node/build/deps \
-t ${WASM_BUILDER_CONTAINER} node build/wasm.js`
console.log(`> ${cmd}\n\n`)
execSync(cmd, { stdio: 'inherit' })
process.exit(0) // eslint-disable-line n/no-process-exit
}
const hasApk = (function () {
try { execSync('command -v apk'); return true } catch { return false }
})()
const hasOptimizer = (function () {
try { execSync(`${WASM_OPT} --version`); return true } catch { return false }
})()
if (hasApk) {
// Gather information about the tools used for the build
const buildInfo = execSync('apk info -v').toString()
if (!buildInfo.includes('wasi-sdk')) {
throw new Error('Failed to generate build environment information')
}
console.log(buildInfo)
}
// Build wasm binary
execSync(`${WASM_CC} ${WASM_CFLAGS} ${WASM_LDFLAGS} \
${join(WASM_SRC, 'src')}/*.c \
-I${join(WASM_SRC, 'include')} \
-o ${join(WASM_OUT, 'llhttp.wasm')} \
${WASM_LDLIBS}`, { stdio: 'inherit' })
if (hasOptimizer) {
execSync(`${WASM_OPT} ${WASM_OPT_FLAGS} -o ${join(WASM_OUT, 'llhttp.wasm')} ${join(WASM_OUT, 'llhttp.wasm')}`, { stdio: 'inherit' })
}
writeWasmChunk('llhttp.wasm', 'llhttp-wasm.js')
// Build wasm simd binary
execSync(`${WASM_CC} ${WASM_CFLAGS} -msimd128 ${WASM_LDFLAGS} \
${join(WASM_SRC, 'src')}/*.c \
-I${join(WASM_SRC, 'include')} \
-o ${join(WASM_OUT, 'llhttp_simd.wasm')} \
${WASM_LDLIBS}`, { stdio: 'inherit' })
if (hasOptimizer) {
// Split WASM_OPT_FLAGS into an array, if not empty
const wasmOptFlagsArray = WASM_OPT_FLAGS ? WASM_OPT_FLAGS.split(/\s+/).filter(Boolean) : []
execFileSync(
WASM_OPT,
[
...wasmOptFlagsArray,
'--enable-simd',
'-o',
join(WASM_OUT, 'llhttp_simd.wasm'),
join(WASM_OUT, 'llhttp_simd.wasm')
],
{ stdio: 'inherit' }
)
}
writeWasmChunk('llhttp_simd.wasm', 'llhttp_simd-wasm.js')
// For compatibility with Node.js' `configure --shared-builtin-undici/undici-path ...`
if (EXTERNAL_PATH) {
writeFileSync(join(ROOT, 'loader.js'), `
'use strict'
globalThis.__UNDICI_IS_NODE__ = true
module.exports = require('node:module').createRequire('${EXTERNAL_PATH}/loader.js')('./index-fetch.js')
delete globalThis.__UNDICI_IS_NODE__
`)
}
================================================
FILE: deps/llhttp/include/llhttp.h
================================================
#ifndef INCLUDE_LLHTTP_H_
#define INCLUDE_LLHTTP_H_
#define LLHTTP_VERSION_MAJOR 9
#define LLHTTP_VERSION_MINOR 3
#define LLHTTP_VERSION_PATCH 0
#ifndef INCLUDE_LLHTTP_ITSELF_H_
#define INCLUDE_LLHTTP_ITSELF_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
typedef struct llhttp__internal_s llhttp__internal_t;
struct llhttp__internal_s {
int32_t _index;
void* _span_pos0;
void* _span_cb0;
int32_t error;
const char* reason;
const char* error_pos;
void* data;
void* _current;
uint64_t content_length;
uint8_t type;
uint8_t method;
uint8_t http_major;
uint8_t http_minor;
uint8_t header_state;
uint16_t lenient_flags;
uint8_t upgrade;
uint8_t finish;
uint16_t flags;
uint16_t status_code;
uint8_t initial_message_completed;
void* settings;
};
int llhttp__internal_init(llhttp__internal_t* s);
int llhttp__internal_execute(llhttp__internal_t* s, const char* p, const char* endp);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INCLUDE_LLHTTP_ITSELF_H_ */
#ifndef LLLLHTTP_C_HEADERS_
#define LLLLHTTP_C_HEADERS_
#ifdef __cplusplus
extern "C" {
#endif
enum llhttp_errno {
HPE_OK = 0,
HPE_INTERNAL = 1,
HPE_STRICT = 2,
HPE_CR_EXPECTED = 25,
HPE_LF_EXPECTED = 3,
HPE_UNEXPECTED_CONTENT_LENGTH = 4,
HPE_UNEXPECTED_SPACE = 30,
HPE_CLOSED_CONNECTION = 5,
HPE_INVALID_METHOD = 6,
HPE_INVALID_URL = 7,
HPE_INVALID_CONSTANT = 8,
HPE_INVALID_VERSION = 9,
HPE_INVALID_HEADER_TOKEN = 10,
HPE_INVALID_CONTENT_LENGTH = 11,
HPE_INVALID_CHUNK_SIZE = 12,
HPE_INVALID_STATUS = 13,
HPE_INVALID_EOF_STATE = 14,
HPE_INVALID_TRANSFER_ENCODING = 15,
HPE_CB_MESSAGE_BEGIN = 16,
HPE_CB_HEADERS_COMPLETE = 17,
HPE_CB_MESSAGE_COMPLETE = 18,
HPE_CB_CHUNK_HEADER = 19,
HPE_CB_CHUNK_COMPLETE = 20,
HPE_PAUSED = 21,
HPE_PAUSED_UPGRADE = 22,
HPE_PAUSED_H2_UPGRADE = 23,
HPE_USER = 24,
HPE_CB_URL_COMPLETE = 26,
HPE_CB_STATUS_COMPLETE = 27,
HPE_CB_METHOD_COMPLETE = 32,
HPE_CB_VERSION_COMPLETE = 33,
HPE_CB_HEADER_FIELD_COMPLETE = 28,
HPE_CB_HEADER_VALUE_COMPLETE = 29,
HPE_CB_CHUNK_EXTENSION_NAME_COMPLETE = 34,
HPE_CB_CHUNK_EXTENSION_VALUE_COMPLETE = 35,
HPE_CB_RESET = 31,
HPE_CB_PROTOCOL_COMPLETE = 38
};
typedef enum llhttp_errno llhttp_errno_t;
enum llhttp_flags {
F_CONNECTION_KEEP_ALIVE = 0x1,
F_CONNECTION_CLOSE = 0x2,
F_CONNECTION_UPGRADE = 0x4,
F_CHUNKED = 0x8,
F_UPGRADE = 0x10,
F_CONTENT_LENGTH = 0x20,
F_SKIPBODY = 0x40,
F_TRAILING = 0x80,
F_TRANSFER_ENCODING = 0x200
};
typedef enum llhttp_flags llhttp_flags_t;
enum llhttp_lenient_flags {
LENIENT_HEADERS = 0x1,
LENIENT_CHUNKED_LENGTH = 0x2,
LENIENT_KEEP_ALIVE = 0x4,
LENIENT_TRANSFER_ENCODING = 0x8,
LENIENT_VERSION = 0x10,
LENIENT_DATA_AFTER_CLOSE = 0x20,
LENIENT_OPTIONAL_LF_AFTER_CR = 0x40,
LENIENT_OPTIONAL_CRLF_AFTER_CHUNK = 0x80,
LENIENT_OPTIONAL_CR_BEFORE_LF = 0x100,
LENIENT_SPACES_AFTER_CHUNK_SIZE = 0x200
};
typedef enum llhttp_lenient_flags llhttp_lenient_flags_t;
enum llhttp_type {
HTTP_BOTH = 0,
HTTP_REQUEST = 1,
HTTP_RESPONSE = 2
};
typedef enum llhttp_type llhttp_type_t;
enum llhttp_finish {
HTTP_FINISH_SAFE = 0,
HTTP_FINISH_SAFE_WITH_CB = 1,
HTTP_FINISH_UNSAFE = 2
};
typedef enum llhttp_finish llhttp_finish_t;
enum llhttp_method {
HTTP_DELETE = 0,
HTTP_GET = 1,
HTTP_HEAD = 2,
HTTP_POST = 3,
HTTP_PUT = 4,
HTTP_CONNECT = 5,
HTTP_OPTIONS = 6,
HTTP_TRACE = 7,
HTTP_COPY = 8,
HTTP_LOCK = 9,
HTTP_MKCOL = 10,
HTTP_MOVE = 11,
HTTP_PROPFIND = 12,
HTTP_PROPPATCH = 13,
HTTP_SEARCH = 14,
HTTP_UNLOCK = 15,
HTTP_BIND = 16,
HTTP_REBIND = 17,
HTTP_UNBIND = 18,
HTTP_ACL = 19,
HTTP_REPORT = 20,
HTTP_MKACTIVITY = 21,
HTTP_CHECKOUT = 22,
HTTP_MERGE = 23,
HTTP_MSEARCH = 24,
HTTP_NOTIFY = 25,
HTTP_SUBSCRIBE = 26,
HTTP_UNSUBSCRIBE = 27,
HTTP_PATCH = 28,
HTTP_PURGE = 29,
HTTP_MKCALENDAR = 30,
HTTP_LINK = 31,
HTTP_UNLINK = 32,
HTTP_SOURCE = 33,
HTTP_PRI = 34,
HTTP_DESCRIBE = 35,
HTTP_ANNOUNCE = 36,
HTTP_SETUP = 37,
HTTP_PLAY = 38,
HTTP_PAUSE = 39,
HTTP_TEARDOWN = 40,
HTTP_GET_PARAMETER = 41,
HTTP_SET_PARAMETER = 42,
HTTP_REDIRECT = 43,
HTTP_RECORD = 44,
HTTP_FLUSH = 45,
HTTP_QUERY = 46
};
typedef enum llhttp_method llhttp_method_t;
enum llhttp_status {
HTTP_STATUS_CONTINUE = 100,
HTTP_STATUS_SWITCHING_PROTOCOLS = 101,
HTTP_STATUS_PROCESSING = 102,
HTTP_STATUS_EARLY_HINTS = 103,
HTTP_STATUS_RESPONSE_IS_STALE = 110,
HTTP_STATUS_REVALIDATION_FAILED = 111,
HTTP_STATUS_DISCONNECTED_OPERATION = 112,
HTTP_STATUS_HEURISTIC_EXPIRATION = 113,
HTTP_STATUS_MISCELLANEOUS_WARNING = 199,
HTTP_STATUS_OK = 200,
HTTP_STATUS_CREATED = 201,
HTTP_STATUS_ACCEPTED = 202,
HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203,
HTTP_STATUS_NO_CONTENT = 204,
HTTP_STATUS_RESET_CONTENT = 205,
HTTP_STATUS_PARTIAL_CONTENT = 206,
HTTP_STATUS_MULTI_STATUS = 207,
HTTP_STATUS_ALREADY_REPORTED = 208,
HTTP_STATUS_TRANSFORMATION_APPLIED = 214,
HTTP_STATUS_IM_USED = 226,
HTTP_STATUS_MISCELLANEOUS_PERSISTENT_WARNING = 299,
HTTP_STATUS_MULTIPLE_CHOICES = 300,
HTTP_STATUS_MOVED_PERMANENTLY = 301,
HTTP_STATUS_FOUND = 302,
HTTP_STATUS_SEE_OTHER = 303,
HTTP_STATUS_NOT_MODIFIED = 304,
HTTP_STATUS_USE_PROXY = 305,
HTTP_STATUS_SWITCH_PROXY = 306,
HTTP_STATUS_TEMPORARY_REDIRECT = 307,
HTTP_STATUS_PERMANENT_REDIRECT = 308,
HTTP_STATUS_BAD_REQUEST = 400,
HTTP_STATUS_UNAUTHORIZED = 401,
HTTP_STATUS_PAYMENT_REQUIRED = 402,
HTTP_STATUS_FORBIDDEN = 403,
HTTP_STATUS_NOT_FOUND = 404,
HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
HTTP_STATUS_NOT_ACCEPTABLE = 406,
HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
HTTP_STATUS_REQUEST_TIMEOUT = 408,
HTTP_STATUS_CONFLICT = 409,
HTTP_STATUS_GONE = 410,
HTTP_STATUS_LENGTH_REQUIRED = 411,
HTTP_STATUS_PRECONDITION_FAILED = 412,
HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
HTTP_STATUS_URI_TOO_LONG = 414,
HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416,
HTTP_STATUS_EXPECTATION_FAILED = 417,
HTTP_STATUS_IM_A_TEAPOT = 418,
HTTP_STATUS_PAGE_EXPIRED = 419,
HTTP_STATUS_ENHANCE_YOUR_CALM = 420,
HTTP_STATUS_MISDIRECTED_REQUEST = 421,
HTTP_STATUS_UNPROCESSABLE_ENTITY = 422,
HTTP_STATUS_LOCKED = 423,
HTTP_STATUS_FAILED_DEPENDENCY = 424,
HTTP_STATUS_TOO_EARLY = 425,
HTTP_STATUS_UPGRADE_REQUIRED = 426,
HTTP_STATUS_PRECONDITION_REQUIRED = 428,
HTTP_STATUS_TOO_MANY_REQUESTS = 429,
HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL = 430,
HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HTTP_STATUS_LOGIN_TIMEOUT = 440,
HTTP_STATUS_NO_RESPONSE = 444,
HTTP_STATUS_RETRY_WITH = 449,
HTTP_STATUS_BLOCKED_BY_PARENTAL_CONTROL = 450,
HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
HTTP_STATUS_CLIENT_CLOSED_LOAD_BALANCED_REQUEST = 460,
HTTP_STATUS_INVALID_X_FORWARDED_FOR = 463,
HTTP_STATUS_REQUEST_HEADER_TOO_LARGE = 494,
HTTP_STATUS_SSL_CERTIFICATE_ERROR = 495,
HTTP_STATUS_SSL_CERTIFICATE_REQUIRED = 496,
HTTP_STATUS_HTTP_REQUEST_SENT_TO_HTTPS_PORT = 497,
HTTP_STATUS_INVALID_TOKEN = 498,
HTTP_STATUS_CLIENT_CLOSED_REQUEST = 499,
HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
HTTP_STATUS_NOT_IMPLEMENTED = 501,
HTTP_STATUS_BAD_GATEWAY = 502,
HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
HTTP_STATUS_GATEWAY_TIMEOUT = 504,
HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505,
HTTP_STATUS_VARIANT_ALSO_NEGOTIATES = 506,
HTTP_STATUS_INSUFFICIENT_STORAGE = 507,
HTTP_STATUS_LOOP_DETECTED = 508,
HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509,
HTTP_STATUS_NOT_EXTENDED = 510,
HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511,
HTTP_STATUS_WEB_SERVER_UNKNOWN_ERROR = 520,
HTTP_STATUS_WEB_SERVER_IS_DOWN = 521,
HTTP_STATUS_CONNECTION_TIMEOUT = 522,
HTTP_STATUS_ORIGIN_IS_UNREACHABLE = 523,
HTTP_STATUS_TIMEOUT_OCCURED = 524,
HTTP_STATUS_SSL_HANDSHAKE_FAILED = 525,
HTTP_STATUS_INVALID_SSL_CERTIFICATE = 526,
HTTP_STATUS_RAILGUN_ERROR = 527,
HTTP_STATUS_SITE_IS_OVERLOADED = 529,
HTTP_STATUS_SITE_IS_FROZEN = 530,
HTTP_STATUS_IDENTITY_PROVIDER_AUTHENTICATION_ERROR = 561,
HTTP_STATUS_NETWORK_READ_TIMEOUT = 598,
HTTP_STATUS_NETWORK_CONNECT_TIMEOUT = 599
};
typedef enum llhttp_status llhttp_status_t;
#define HTTP_ERRNO_MAP(XX) \
XX(0, OK, OK) \
XX(1, INTERNAL, INTERNAL) \
XX(2, STRICT, STRICT) \
XX(25, CR_EXPECTED, CR_EXPECTED) \
XX(3, LF_EXPECTED, LF_EXPECTED) \
XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \
XX(30, UNEXPECTED_SPACE, UNEXPECTED_SPACE) \
XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \
XX(6, INVALID_METHOD, INVALID_METHOD) \
XX(7, INVALID_URL, INVALID_URL) \
XX(8, INVALID_CONSTANT, INVALID_CONSTANT) \
XX(9, INVALID_VERSION, INVALID_VERSION) \
XX(10, INVALID_HEADER_TOKEN, INVALID_HEADER_TOKEN) \
XX(11, INVALID_CONTENT_LENGTH, INVALID_CONTENT_LENGTH) \
XX(12, INVALID_CHUNK_SIZE, INVALID_CHUNK_SIZE) \
XX(13, INVALID_STATUS, INVALID_STATUS) \
XX(14, INVALID_EOF_STATE, INVALID_EOF_STATE) \
XX(15, INVALID_TRANSFER_ENCODING, INVALID_TRANSFER_ENCODING) \
XX(16, CB_MESSAGE_BEGIN, CB_MESSAGE_BEGIN) \
XX(17, CB_HEADERS_COMPLETE, CB_HEADERS_COMPLETE) \
XX(18, CB_MESSAGE_COMPLETE, CB_MESSAGE_COMPLETE) \
XX(19, CB_CHUNK_HEADER, CB_CHUNK_HEADER) \
XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \
XX(21, PAUSED, PAUSED) \
XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \
XX(23, PAUSED_H2_UPGRADE, PAUSED_H2_UPGRADE) \
XX(24, USER, USER) \
XX(26, CB_URL_COMPLETE, CB_URL_COMPLETE) \
XX(27, CB_STATUS_COMPLETE, CB_STATUS_COMPLETE) \
XX(32, CB_METHOD_COMPLETE, CB_METHOD_COMPLETE) \
XX(33, CB_VERSION_COMPLETE, CB_VERSION_COMPLETE) \
XX(28, CB_HEADER_FIELD_COMPLETE, CB_HEADER_FIELD_COMPLETE) \
XX(29, CB_HEADER_VALUE_COMPLETE, CB_HEADER_VALUE_COMPLETE) \
XX(34, CB_CHUNK_EXTENSION_NAME_COMPLETE, CB_CHUNK_EXTENSION_NAME_COMPLETE) \
XX(35, CB_CHUNK_EXTENSION_VALUE_COMPLETE, CB_CHUNK_EXTENSION_VALUE_COMPLETE) \
XX(31, CB_RESET, CB_RESET) \
XX(38, CB_PROTOCOL_COMPLETE, CB_PROTOCOL_COMPLETE) \
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
XX(30, MKCALENDAR, MKCALENDAR) \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
XX(33, SOURCE, SOURCE) \
XX(46, QUERY, QUERY) \
#define RTSP_METHOD_MAP(XX) \
XX(1, GET, GET) \
XX(3, POST, POST) \
XX(6, OPTIONS, OPTIONS) \
XX(35, DESCRIBE, DESCRIBE) \
XX(36, ANNOUNCE, ANNOUNCE) \
XX(37, SETUP, SETUP) \
XX(38, PLAY, PLAY) \
XX(39, PAUSE, PAUSE) \
XX(40, TEARDOWN, TEARDOWN) \
XX(41, GET_PARAMETER, GET_PARAMETER) \
XX(42, SET_PARAMETER, SET_PARAMETER) \
XX(43, REDIRECT, REDIRECT) \
XX(44, RECORD, RECORD) \
XX(45, FLUSH, FLUSH) \
#define HTTP_ALL_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
XX(30, MKCALENDAR, MKCALENDAR) \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
XX(33, SOURCE, SOURCE) \
XX(34, PRI, PRI) \
XX(35, DESCRIBE, DESCRIBE) \
XX(36, ANNOUNCE, ANNOUNCE) \
XX(37, SETUP, SETUP) \
XX(38, PLAY, PLAY) \
XX(39, PAUSE, PAUSE) \
XX(40, TEARDOWN, TEARDOWN) \
XX(41, GET_PARAMETER, GET_PARAMETER) \
XX(42, SET_PARAMETER, SET_PARAMETER) \
XX(43, REDIRECT, REDIRECT) \
XX(44, RECORD, RECORD) \
XX(45, FLUSH, FLUSH) \
XX(46, QUERY, QUERY) \
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, CONTINUE) \
XX(101, SWITCHING_PROTOCOLS, SWITCHING_PROTOCOLS) \
XX(102, PROCESSING, PROCESSING) \
XX(103, EARLY_HINTS, EARLY_HINTS) \
XX(110, RESPONSE_IS_STALE, RESPONSE_IS_STALE) \
XX(111, REVALIDATION_FAILED, REVALIDATION_FAILED) \
XX(112, DISCONNECTED_OPERATION, DISCONNECTED_OPERATION) \
XX(113, HEURISTIC_EXPIRATION, HEURISTIC_EXPIRATION) \
XX(199, MISCELLANEOUS_WARNING, MISCELLANEOUS_WARNING) \
XX(200, OK, OK) \
XX(201, CREATED, CREATED) \
XX(202, ACCEPTED, ACCEPTED) \
XX(203, NON_AUTHORITATIVE_INFORMATION, NON_AUTHORITATIVE_INFORMATION) \
XX(204, NO_CONTENT, NO_CONTENT) \
XX(205, RESET_CONTENT, RESET_CONTENT) \
XX(206, PARTIAL_CONTENT, PARTIAL_CONTENT) \
XX(207, MULTI_STATUS, MULTI_STATUS) \
XX(208, ALREADY_REPORTED, ALREADY_REPORTED) \
XX(214, TRANSFORMATION_APPLIED, TRANSFORMATION_APPLIED) \
XX(226, IM_USED, IM_USED) \
XX(299, MISCELLANEOUS_PERSISTENT_WARNING, MISCELLANEOUS_PERSISTENT_WARNING) \
XX(300, MULTIPLE_CHOICES, MULTIPLE_CHOICES) \
XX(301, MOVED_PERMANENTLY, MOVED_PERMANENTLY) \
XX(302, FOUND, FOUND) \
XX(303, SEE_OTHER, SEE_OTHER) \
XX(304, NOT_MODIFIED, NOT_MODIFIED) \
XX(305, USE_PROXY, USE_PROXY) \
XX(306, SWITCH_PROXY, SWITCH_PROXY) \
XX(307, TEMPORARY_REDIRECT, TEMPORARY_REDIRECT) \
XX(308, PERMANENT_REDIRECT, PERMANENT_REDIRECT) \
XX(400, BAD_REQUEST, BAD_REQUEST) \
XX(401, UNAUTHORIZED, UNAUTHORIZED) \
XX(402, PAYMENT_REQUIRED, PAYMENT_REQUIRED) \
XX(403, FORBIDDEN, FORBIDDEN) \
XX(404, NOT_FOUND, NOT_FOUND) \
XX(405, METHOD_NOT_ALLOWED, METHOD_NOT_ALLOWED) \
XX(406, NOT_ACCEPTABLE, NOT_ACCEPTABLE) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, PROXY_AUTHENTICATION_REQUIRED) \
XX(408, REQUEST_TIMEOUT, REQUEST_TIMEOUT) \
XX(409, CONFLICT, CONFLICT) \
XX(410, GONE, GONE) \
XX(411, LENGTH_REQUIRED, LENGTH_REQUIRED) \
XX(412, PRECONDITION_FAILED, PRECONDITION_FAILED) \
XX(413, PAYLOAD_TOO_LARGE, PAYLOAD_TOO_LARGE) \
XX(414, URI_TOO_LONG, URI_TOO_LONG) \
XX(415, UNSUPPORTED_MEDIA_TYPE, UNSUPPORTED_MEDIA_TYPE) \
XX(416, RANGE_NOT_SATISFIABLE, RANGE_NOT_SATISFIABLE) \
XX(417, EXPECTATION_FAILED, EXPECTATION_FAILED) \
XX(418, IM_A_TEAPOT, IM_A_TEAPOT) \
XX(419, PAGE_EXPIRED, PAGE_EXPIRED) \
XX(420, ENHANCE_YOUR_CALM, ENHANCE_YOUR_CALM) \
XX(421, MISDIRECTED_REQUEST, MISDIRECTED_REQUEST) \
XX(422, UNPROCESSABLE_ENTITY, UNPROCESSABLE_ENTITY) \
XX(423, LOCKED, LOCKED) \
XX(424, FAILED_DEPENDENCY, FAILED_DEPENDENCY) \
XX(425, TOO_EARLY, TOO_EARLY) \
XX(426, UPGRADE_REQUIRED, UPGRADE_REQUIRED) \
XX(428, PRECONDITION_REQUIRED, PRECONDITION_REQUIRED) \
XX(429, TOO_MANY_REQUESTS, TOO_MANY_REQUESTS) \
XX(430, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, REQUEST_HEADER_FIELDS_TOO_LARGE) \
XX(440, LOGIN_TIMEOUT, LOGIN_TIMEOUT) \
XX(444, NO_RESPONSE, NO_RESPONSE) \
XX(449, RETRY_WITH, RETRY_WITH) \
XX(450, BLOCKED_BY_PARENTAL_CONTROL, BLOCKED_BY_PARENTAL_CONTROL) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, UNAVAILABLE_FOR_LEGAL_REASONS) \
XX(460, CLIENT_CLOSED_LOAD_BALANCED_REQUEST, CLIENT_CLOSED_LOAD_BALANCED_REQUEST) \
XX(463, INVALID_X_FORWARDED_FOR, INVALID_X_FORWARDED_FOR) \
XX(494, REQUEST_HEADER_TOO_LARGE, REQUEST_HEADER_TOO_LARGE) \
XX(495, SSL_CERTIFICATE_ERROR, SSL_CERTIFICATE_ERROR) \
XX(496, SSL_CERTIFICATE_REQUIRED, SSL_CERTIFICATE_REQUIRED) \
XX(497, HTTP_REQUEST_SENT_TO_HTTPS_PORT, HTTP_REQUEST_SENT_TO_HTTPS_PORT) \
XX(498, INVALID_TOKEN, INVALID_TOKEN) \
XX(499, CLIENT_CLOSED_REQUEST, CLIENT_CLOSED_REQUEST) \
XX(500, INTERNAL_SERVER_ERROR, INTERNAL_SERVER_ERROR) \
XX(501, NOT_IMPLEMENTED, NOT_IMPLEMENTED) \
XX(502, BAD_GATEWAY, BAD_GATEWAY) \
XX(503, SERVICE_UNAVAILABLE, SERVICE_UNAVAILABLE) \
XX(504, GATEWAY_TIMEOUT, GATEWAY_TIMEOUT) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP_VERSION_NOT_SUPPORTED) \
XX(506, VARIANT_ALSO_NEGOTIATES, VARIANT_ALSO_NEGOTIATES) \
XX(507, INSUFFICIENT_STORAGE, INSUFFICIENT_STORAGE) \
XX(508, LOOP_DETECTED, LOOP_DETECTED) \
XX(509, BANDWIDTH_LIMIT_EXCEEDED, BANDWIDTH_LIMIT_EXCEEDED) \
XX(510, NOT_EXTENDED, NOT_EXTENDED) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, NETWORK_AUTHENTICATION_REQUIRED) \
XX(520, WEB_SERVER_UNKNOWN_ERROR, WEB_SERVER_UNKNOWN_ERROR) \
XX(521, WEB_SERVER_IS_DOWN, WEB_SERVER_IS_DOWN) \
XX(522, CONNECTION_TIMEOUT, CONNECTION_TIMEOUT) \
XX(523, ORIGIN_IS_UNREACHABLE, ORIGIN_IS_UNREACHABLE) \
XX(524, TIMEOUT_OCCURED, TIMEOUT_OCCURED) \
XX(525, SSL_HANDSHAKE_FAILED, SSL_HANDSHAKE_FAILED) \
XX(526, INVALID_SSL_CERTIFICATE, INVALID_SSL_CERTIFICATE) \
XX(527, RAILGUN_ERROR, RAILGUN_ERROR) \
XX(529, SITE_IS_OVERLOADED, SITE_IS_OVERLOADED) \
XX(530, SITE_IS_FROZEN, SITE_IS_FROZEN) \
XX(561, IDENTITY_PROVIDER_AUTHENTICATION_ERROR, IDENTITY_PROVIDER_AUTHENTICATION_ERROR) \
XX(598, NETWORK_READ_TIMEOUT, NETWORK_READ_TIMEOUT) \
XX(599, NETWORK_CONNECT_TIMEOUT, NETWORK_CONNECT_TIMEOUT) \
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LLLLHTTP_C_HEADERS_ */
#ifndef INCLUDE_LLHTTP_API_H_
#define INCLUDE_LLHTTP_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#if defined(__wasm__)
#define LLHTTP_EXPORT __attribute__((visibility("default")))
#elif defined(_WIN32)
#define LLHTTP_EXPORT __declspec(dllexport)
#else
#define LLHTTP_EXPORT
#endif
typedef llhttp__internal_t llhttp_t;
typedef struct llhttp_settings_s llhttp_settings_t;
typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length);
typedef int (*llhttp_cb)(llhttp_t*);
struct llhttp_settings_s {
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_begin;
/* Possible return values 0, -1, HPE_USER */
llhttp_data_cb on_protocol;
llhttp_data_cb on_url;
llhttp_data_cb on_status;
llhttp_data_cb on_method;
llhttp_data_cb on_version;
llhttp_data_cb on_header_field;
llhttp_data_cb on_header_value;
llhttp_data_cb on_chunk_extension_name;
llhttp_data_cb on_chunk_extension_value;
/* Possible return values:
* 0 - Proceed normally
* 1 - Assume that request/response has no body, and proceed to parsing the
* next message
* 2 - Assume absence of body (as above) and make `llhttp_execute()` return
* `HPE_PAUSED_UPGRADE`
* -1 - Error
* `HPE_PAUSED`
*/
llhttp_cb on_headers_complete;
/* Possible return values 0, -1, HPE_USER */
llhttp_data_cb on_body;
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_complete;
llhttp_cb on_protocol_complete;
llhttp_cb on_url_complete;
llhttp_cb on_status_complete;
llhttp_cb on_method_complete;
llhttp_cb on_version_complete;
llhttp_cb on_header_field_complete;
llhttp_cb on_header_value_complete;
llhttp_cb on_chunk_extension_name_complete;
llhttp_cb on_chunk_extension_value_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
* Possible return values 0, -1, `HPE_PAUSED`
*/
llhttp_cb on_chunk_header;
llhttp_cb on_chunk_complete;
llhttp_cb on_reset;
};
/* Initialize the parser with specific type and user settings.
*
* NOTE: lifetime of `settings` has to be at least the same as the lifetime of
* the `parser` here. In practice, `settings` has to be either a static
* variable or be allocated with `malloc`, `new`, etc.
*/
LLHTTP_EXPORT
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
const llhttp_settings_t* settings);
LLHTTP_EXPORT
llhttp_t* llhttp_alloc(llhttp_type_t type);
LLHTTP_EXPORT
void llhttp_free(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_type(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_major(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_minor(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_method(llhttp_t* parser);
LLHTTP_EXPORT
int llhttp_get_status_code(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_upgrade(llhttp_t* parser);
/* Reset an already initialized parser back to the start state, preserving the
* existing parser type, callback settings, user data, and lenient flags.
*/
LLHTTP_EXPORT
void llhttp_reset(llhttp_t* parser);
/* Initialize the settings object */
LLHTTP_EXPORT
void llhttp_settings_init(llhttp_settings_t* settings);
/* Parse full or partial request/response, invoking user callbacks along the
* way.
*
* If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing
* interrupts, and such errno is returned from `llhttp_execute()`. If
* `HPE_PAUSED` was used as a errno, the execution can be resumed with
* `llhttp_resume()` call.
*
* In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE`
* is returned after fully parsing the request/response. If the user wishes to
* continue parsing, they need to invoke `llhttp_resume_after_upgrade()`.
*
* NOTE: if this function ever returns a non-pause type error, it will continue
* to return the same error upon each successive call up until `llhttp_init()`
* is called.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
/* This method should be called when the other side has no further bytes to
* send (e.g. shutdown of readable side of the TCP connection.)
*
* Requests without `Content-Length` and other messages might require treating
* all incoming bytes as the part of the body, up to the last byte of the
* connection. This method will invoke `on_message_complete()` callback if the
* request was terminated safely. Otherwise a error code would be returned.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_finish(llhttp_t* parser);
/* Returns `1` if the incoming message is parsed until the last byte, and has
* to be completed by calling `llhttp_finish()` on EOF
*/
LLHTTP_EXPORT
int llhttp_message_needs_eof(const llhttp_t* parser);
/* Returns `1` if there might be any other messages following the last that was
* successfully parsed.
*/
LLHTTP_EXPORT
int llhttp_should_keep_alive(const llhttp_t* parser);
/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
* appropriate error reason.
*
* Important: do not call this from user callbacks! User callbacks must return
* `HPE_PAUSED` if pausing is required.
*/
LLHTTP_EXPORT
void llhttp_pause(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
*/
LLHTTP_EXPORT
void llhttp_resume(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
*/
LLHTTP_EXPORT
void llhttp_resume_after_upgrade(llhttp_t* parser);
/* Returns the latest return error */
LLHTTP_EXPORT
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
/* Returns the verbal explanation of the latest returned error.
*
* Note: User callback should set error reason when returning the error. See
* `llhttp_set_error_reason()` for details.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_reason(const llhttp_t* parser);
/* Assign verbal description to the returned error. Must be called in user
* callbacks right before returning the errno.
*
* Note: `HPE_USER` error code might be useful in user callbacks.
*/
LLHTTP_EXPORT
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
/* Returns the pointer to the last parsed byte before the returned error. The
* pointer is relative to the `data` argument of `llhttp_execute()`.
*
* Note: this method might be useful for counting the number of parsed bytes.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_pos(const llhttp_t* parser);
/* Returns textual name of error code */
LLHTTP_EXPORT
const char* llhttp_errno_name(llhttp_errno_t err);
/* Returns textual name of HTTP method */
LLHTTP_EXPORT
const char* llhttp_method_name(llhttp_method_t method);
/* Returns textual name of HTTP status */
LLHTTP_EXPORT
const char* llhttp_status_name(llhttp_status_t status);
/* Enables/disables lenient header value parsing (disabled by default).
*
* Lenient parsing disables header value token checks, extending llhttp's
* protocol support to highly non-compliant clients/server. No
* `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when
* lenient parsing is "on".
*
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and
* `Content-Length` headers (disabled by default).
*
* Normally `llhttp` would error when `Transfer-Encoding` is present in
* conjunction with `Content-Length`. This error is important to prevent HTTP
* request smuggling, but may be less desirable for small number of cases
* involving legacy servers.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
* requests responses.
*
* Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
* the HTTP request/response after the request/response with `Connection: close`
* and `Content-Length`. This is important to prevent cache poisoning attacks,
* but might interact badly with outdated and insecure clients. With this flag
* the extra request/response will be parsed normally.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* poisoning attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_keep_alive(llh
gitextract_26dbkv5y/
├── .c8rc.json
├── .dockerignore
├── .editorconfig
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.md
│ │ └── feature-request.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── autobahn.yml
│ ├── backport.yml
│ ├── bench.yml
│ ├── ci.yml
│ ├── codeql.yml
│ ├── nodejs-nightly.yml
│ ├── nodejs-shared.yml
│ ├── nodejs.yml
│ ├── release-create-pr.yml
│ ├── release.yml
│ ├── scorecard.yml
│ ├── triggered-autobahn.yml
│ └── update-submodules.yml
├── .gitignore
├── .gitmodules
├── .husky/
│ └── pre-commit
├── .npmignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── SECURITY.md
├── benchmarks/
│ ├── _util/
│ │ ├── index.js
│ │ └── runner.js
│ ├── benchmark-http2.js
│ ├── benchmark-https.js
│ ├── benchmark.js
│ ├── cache/
│ │ ├── date.mjs
│ │ └── get-field-values.mjs
│ ├── cookies/
│ │ ├── is-ctl-excluding-htab.mjs
│ │ ├── to-imf-date.mjs
│ │ ├── validate-cookie-name.mjs
│ │ └── validate-cookie-value.mjs
│ ├── core/
│ │ ├── is-blob-like.mjs
│ │ ├── is-valid-header-char.mjs
│ │ ├── is-valid-port.mjs
│ │ ├── parse-headers.mjs
│ │ ├── parse-raw-headers.mjs
│ │ ├── request-instantiation.mjs
│ │ └── tree.mjs
│ ├── fetch/
│ │ ├── body-arraybuffer.mjs
│ │ ├── bytes-match.mjs
│ │ ├── headers-length32.mjs
│ │ ├── headers.mjs
│ │ ├── is-valid-encoded-url.mjs
│ │ ├── is-valid-header-value.mjs
│ │ ├── isomorphic-encode.mjs
│ │ ├── request-creation.mjs
│ │ └── url-has-https-scheme.mjs
│ ├── package.json
│ ├── post-benchmark.js
│ ├── server-http2.js
│ ├── server-https.js
│ ├── server.js
│ ├── timers/
│ │ └── compare-timer-getters.mjs
│ ├── utils/
│ │ └── date.mjs
│ ├── wait.js
│ ├── webidl/
│ │ └── webidl-is.mjs
│ ├── websocket/
│ │ ├── generate-mask.mjs
│ │ ├── is-valid-subprotocol.mjs
│ │ └── messageevent.mjs
│ ├── websocket-benchmark.mjs
│ └── websocket-echo-server.mjs
├── build/
│ └── wasm.js
├── deps/
│ └── llhttp/
│ ├── include/
│ │ └── llhttp.h
│ └── src/
│ ├── api.c
│ ├── http.c
│ └── llhttp.c
├── docs/
│ ├── .nojekyll
│ ├── CNAME
│ ├── docs/
│ │ ├── api/
│ │ │ ├── Agent.md
│ │ │ ├── BalancedPool.md
│ │ │ ├── CacheStorage.md
│ │ │ ├── CacheStore.md
│ │ │ ├── Client.md
│ │ │ ├── ClientStats.md
│ │ │ ├── Connector.md
│ │ │ ├── ContentType.md
│ │ │ ├── Cookies.md
│ │ │ ├── Debug.md
│ │ │ ├── DiagnosticsChannel.md
│ │ │ ├── Dispatcher.md
│ │ │ ├── EnvHttpProxyAgent.md
│ │ │ ├── Errors.md
│ │ │ ├── EventSource.md
│ │ │ ├── Fetch.md
│ │ │ ├── GlobalInstallation.md
│ │ │ ├── H2CClient.md
│ │ │ ├── MockAgent.md
│ │ │ ├── MockCallHistory.md
│ │ │ ├── MockCallHistoryLog.md
│ │ │ ├── MockClient.md
│ │ │ ├── MockErrors.md
│ │ │ ├── MockPool.md
│ │ │ ├── Pool.md
│ │ │ ├── PoolStats.md
│ │ │ ├── ProxyAgent.md
│ │ │ ├── RedirectHandler.md
│ │ │ ├── RetryAgent.md
│ │ │ ├── RetryHandler.md
│ │ │ ├── RoundRobinPool.md
│ │ │ ├── SnapshotAgent.md
│ │ │ ├── Socks5ProxyAgent.md
│ │ │ ├── Util.md
│ │ │ ├── WebSocket.md
│ │ │ └── api-lifecycle.md
│ │ └── best-practices/
│ │ ├── client-certificate.md
│ │ ├── crawling.md
│ │ ├── mocking-request.md
│ │ ├── proxy.md
│ │ ├── undici-vs-builtin-fetch.md
│ │ └── writing-tests.md
│ ├── docsify/
│ │ └── sidebar.md
│ ├── examples/
│ │ ├── README.md
│ │ ├── ca-fingerprint/
│ │ │ └── index.js
│ │ ├── eventsource.js
│ │ ├── fetch.js
│ │ ├── proxy/
│ │ │ ├── fetch.mjs
│ │ │ ├── index.js
│ │ │ ├── proxy.js
│ │ │ └── websocket.js
│ │ ├── proxy-agent.js
│ │ ├── request.js
│ │ ├── snapshot-testing.js
│ │ └── socks5-proxy.js
│ ├── index.html
│ └── package.json
├── eslint.config.js
├── index-fetch.js
├── index.d.ts
├── index.js
├── lib/
│ ├── api/
│ │ ├── abort-signal.js
│ │ ├── api-connect.js
│ │ ├── api-pipeline.js
│ │ ├── api-request.js
│ │ ├── api-stream.js
│ │ ├── api-upgrade.js
│ │ ├── index.js
│ │ └── readable.js
│ ├── cache/
│ │ ├── memory-cache-store.js
│ │ └── sqlite-cache-store.js
│ ├── core/
│ │ ├── connect.js
│ │ ├── constants.js
│ │ ├── diagnostics.js
│ │ ├── errors.js
│ │ ├── request.js
│ │ ├── socks5-client.js
│ │ ├── socks5-utils.js
│ │ ├── symbols.js
│ │ ├── tree.js
│ │ └── util.js
│ ├── dispatcher/
│ │ ├── agent.js
│ │ ├── balanced-pool.js
│ │ ├── client-h1.js
│ │ ├── client-h2.js
│ │ ├── client.js
│ │ ├── dispatcher-base.js
│ │ ├── dispatcher.js
│ │ ├── env-http-proxy-agent.js
│ │ ├── fixed-queue.js
│ │ ├── h2c-client.js
│ │ ├── pool-base.js
│ │ ├── pool.js
│ │ ├── proxy-agent.js
│ │ ├── retry-agent.js
│ │ ├── round-robin-pool.js
│ │ └── socks5-proxy-agent.js
│ ├── encoding/
│ │ └── index.js
│ ├── global.js
│ ├── handler/
│ │ ├── cache-handler.js
│ │ ├── cache-revalidation-handler.js
│ │ ├── decorator-handler.js
│ │ ├── deduplication-handler.js
│ │ ├── redirect-handler.js
│ │ ├── retry-handler.js
│ │ ├── unwrap-handler.js
│ │ └── wrap-handler.js
│ ├── interceptor/
│ │ ├── cache.js
│ │ ├── decompress.js
│ │ ├── deduplicate.js
│ │ ├── dns.js
│ │ ├── dump.js
│ │ ├── redirect.js
│ │ ├── response-error.js
│ │ └── retry.js
│ ├── llhttp/
│ │ ├── .gitkeep
│ │ ├── constants.d.ts
│ │ ├── constants.js
│ │ ├── llhttp-wasm.js
│ │ ├── llhttp.wasm
│ │ ├── llhttp_simd-wasm.js
│ │ ├── llhttp_simd.wasm
│ │ ├── utils.d.ts
│ │ └── utils.js
│ ├── mock/
│ │ ├── mock-agent.js
│ │ ├── mock-call-history.js
│ │ ├── mock-client.js
│ │ ├── mock-errors.js
│ │ ├── mock-interceptor.js
│ │ ├── mock-pool.js
│ │ ├── mock-symbols.js
│ │ ├── mock-utils.js
│ │ ├── pending-interceptors-formatter.js
│ │ ├── snapshot-agent.js
│ │ ├── snapshot-recorder.js
│ │ └── snapshot-utils.js
│ ├── util/
│ │ ├── cache.js
│ │ ├── date.js
│ │ ├── promise.js
│ │ ├── runtime-features.js
│ │ ├── stats.js
│ │ └── timers.js
│ └── web/
│ ├── cache/
│ │ ├── cache.js
│ │ ├── cachestorage.js
│ │ └── util.js
│ ├── cookies/
│ │ ├── constants.js
│ │ ├── index.js
│ │ ├── parse.js
│ │ └── util.js
│ ├── eventsource/
│ │ ├── eventsource-stream.js
│ │ ├── eventsource.js
│ │ └── util.js
│ ├── fetch/
│ │ ├── LICENSE
│ │ ├── body.js
│ │ ├── constants.js
│ │ ├── data-url.js
│ │ ├── formdata-parser.js
│ │ ├── formdata.js
│ │ ├── global.js
│ │ ├── headers.js
│ │ ├── index.js
│ │ ├── request.js
│ │ ├── response.js
│ │ └── util.js
│ ├── infra/
│ │ └── index.js
│ ├── subresource-integrity/
│ │ ├── Readme.md
│ │ └── subresource-integrity.js
│ ├── webidl/
│ │ └── index.js
│ └── websocket/
│ ├── connection.js
│ ├── constants.js
│ ├── events.js
│ ├── frame.js
│ ├── permessage-deflate.js
│ ├── receiver.js
│ ├── sender.js
│ ├── stream/
│ │ ├── websocketerror.js
│ │ └── websocketstream.js
│ ├── util.js
│ └── websocket.js
├── package.json
├── scripts/
│ ├── clean-coverage.js
│ ├── generate-pem.js
│ ├── generate-undici-types-package-json.js
│ ├── platform-shell.js
│ ├── release.js
│ └── strip-comments.js
├── test/
│ ├── autobahn/
│ │ ├── .gitignore
│ │ ├── client.js
│ │ ├── config/
│ │ │ └── fuzzingserver.json
│ │ ├── report.js
│ │ └── run.sh
│ ├── busboy/
│ │ ├── LICENSE
│ │ ├── formdata-test.js
│ │ ├── issue-3676.js
│ │ ├── issue-3760.js
│ │ ├── issue-4660.js
│ │ ├── issue-4671.js
│ │ ├── test-parser.js
│ │ ├── test-types-multipart-charsets.js
│ │ └── test-types-multipart.js
│ ├── cache/
│ │ ├── cache.js
│ │ ├── cachestorage.js
│ │ └── get-field-values.js
│ ├── cache-interceptor/
│ │ ├── cache-store-test-utils.js
│ │ ├── cache-tests-worker.mjs
│ │ ├── cache-tests.mjs
│ │ ├── cache-utils.js
│ │ ├── memory-cache-store-tests.js
│ │ ├── sqlite-cache-store-tests.js
│ │ └── utils.js
│ ├── client-connect.js
│ ├── client-head-reset-override.js
│ ├── client-idempotent-body.js
│ ├── client-keep-alive.js
│ ├── client-node-max-header-size.js
│ ├── client-pipeline.js
│ ├── client-pipelining.js
│ ├── client-post.js
│ ├── client-reconnect.js
│ ├── client-request.js
│ ├── client-stream.js
│ ├── client-timeout.js
│ ├── client-unref.js
│ ├── client-upgrade.js
│ ├── client-wasm.js
│ ├── client-write-max-listeners.js
│ ├── client.js
│ ├── close-and-destroy.js
│ ├── connect-abort.js
│ ├── connect-errconnect.js
│ ├── connect-pre-shared-session.js
│ ├── connect-timeout.js
│ ├── content-length.js
│ ├── cookie/
│ │ ├── cookies.js
│ │ ├── global-headers.js
│ │ ├── is-ctl-excluding-htab.js
│ │ ├── npm-cookie.js
│ │ ├── to-imf-date.js
│ │ ├── validate-cookie-name.js
│ │ ├── validate-cookie-path.js
│ │ └── validate-cookie-value.js
│ ├── decorator-handler.js
│ ├── dispatcher.js
│ ├── env-http-proxy-agent-nodejs-bundle.js
│ ├── env-http-proxy-agent.js
│ ├── errors.js
│ ├── esm-wrapper.js
│ ├── eventsource/
│ │ ├── eventsource-attributes.js
│ │ ├── eventsource-close.js
│ │ ├── eventsource-connect.js
│ │ ├── eventsource-constructor-stringify.js
│ │ ├── eventsource-constructor.js
│ │ ├── eventsource-custom-dispatcher.js
│ │ ├── eventsource-message.js
│ │ ├── eventsource-properties.js
│ │ ├── eventsource-reconnect.js
│ │ ├── eventsource-redirecting.js
│ │ ├── eventsource-request-status-error.js
│ │ ├── eventsource-stream-bom.js
│ │ ├── eventsource-stream-parse-line.js
│ │ ├── eventsource-stream-process-event.js
│ │ ├── eventsource-stream.js
│ │ ├── eventsource.js
│ │ └── util.js
│ ├── examples.js
│ ├── fetch/
│ │ ├── 401-statuscode-no-infinite-loop.js
│ │ ├── 407-statuscode-window-null.js
│ │ ├── abort.js
│ │ ├── abort2.js
│ │ ├── about-uri.js
│ │ ├── blob-uri.js
│ │ ├── bundle.js
│ │ ├── client-error-stack-trace.js
│ │ ├── client-fetch.js
│ │ ├── client-node-max-header-size.js
│ │ ├── content-length.js
│ │ ├── cookies.js
│ │ ├── data-uri.js
│ │ ├── encoding.js
│ │ ├── exiting.js
│ │ ├── export-env-proxy-agent.js
│ │ ├── fetch-leak.js
│ │ ├── fetch-timeouts.js
│ │ ├── fetch-url-after-redirect.js
│ │ ├── fire-and-forget.js
│ │ ├── formdata-inspect-custom.js
│ │ ├── formdata.js
│ │ ├── general.js
│ │ ├── headers-case.js
│ │ ├── headers-inspect-custom.js
│ │ ├── headers.js
│ │ ├── headerslist-sortedarray.js
│ │ ├── http2.js
│ │ ├── includes-credentials.js
│ │ ├── integrity.js
│ │ ├── issue-1447.js
│ │ ├── issue-1711.js
│ │ ├── issue-2009.js
│ │ ├── issue-2021.js
│ │ ├── issue-2171.js
│ │ ├── issue-2242.js
│ │ ├── issue-2294-patch-method.js
│ │ ├── issue-2318.js
│ │ ├── issue-2828.js
│ │ ├── issue-2898-comment.js
│ │ ├── issue-2898.js
│ │ ├── issue-3267.js
│ │ ├── issue-3334.js
│ │ ├── issue-3616.js
│ │ ├── issue-3624.js
│ │ ├── issue-3630.js
│ │ ├── issue-3767.js
│ │ ├── issue-4105.js
│ │ ├── issue-4627.js
│ │ ├── issue-4647.js
│ │ ├── issue-4789.js
│ │ ├── issue-4799.js
│ │ ├── issue-4836.js
│ │ ├── issue-4897.js
│ │ ├── issue-node-46525.js
│ │ ├── issue-rsshub-15532.js
│ │ ├── iterators.js
│ │ ├── long-lived-abort-controller.js
│ │ ├── max-listeners.js
│ │ ├── pull-dont-push.js
│ │ ├── readable-stream-from.js
│ │ ├── redirect-cross-origin-header.js
│ │ ├── redirect.js
│ │ ├── referrrer-policy.js
│ │ ├── relative-url.js
│ │ ├── request-inspect-custom.js
│ │ ├── request.js
│ │ ├── resource-timing.js
│ │ ├── response-inspect-custom.js
│ │ ├── response-json.js
│ │ ├── response.js
│ │ ├── spread.js
│ │ ├── user-agent.js
│ │ └── util.js
│ ├── fixed-queue.js
│ ├── fixtures/
│ │ ├── ca.pem
│ │ ├── cert.pem
│ │ ├── docker/
│ │ │ ├── dante/
│ │ │ │ ├── Dockerfile
│ │ │ │ └── danted.conf
│ │ │ └── docker-compose.yml
│ │ ├── duplicate-debug.js
│ │ ├── fetch.js
│ │ ├── interceptors/
│ │ │ └── retry-event-loop.js
│ │ ├── key.pem
│ │ ├── socks5-test-server.js
│ │ ├── undici.js
│ │ └── websocket.js
│ ├── fuzzing/
│ │ ├── client/
│ │ │ ├── client-fuzz-body.js
│ │ │ ├── client-fuzz-headers.js
│ │ │ ├── client-fuzz-options.js
│ │ │ └── index.js
│ │ ├── fuzzing.test.js
│ │ └── server/
│ │ ├── index.js
│ │ ├── server-fuzz-append-data.js
│ │ └── server-fuzz-split-data.js
│ ├── gc.js
│ ├── get-head-body.js
│ ├── h2c-client.js
│ ├── headers-as-array.js
│ ├── headers-crlf.js
│ ├── http-100.js
│ ├── http-req-destroy.js
│ ├── http2-abort.js
│ ├── http2-agent.js
│ ├── http2-alpn.js
│ ├── http2-body.js
│ ├── http2-connection.js
│ ├── http2-continue.js
│ ├── http2-dispatcher.js
│ ├── http2-goaway.js
│ ├── http2-instantiation.js
│ ├── http2-late-data.js
│ ├── http2-pseudo-headers.js
│ ├── http2-resume-null-request.js
│ ├── http2-stream.js
│ ├── http2-timeout.js
│ ├── http2-trailers.js
│ ├── http2-window-size.js
│ ├── https.js
│ ├── imports/
│ │ └── undici-import.ts
│ ├── inflight-and-close.js
│ ├── infra/
│ │ └── collect-a-sequence-of-code-points.js
│ ├── install.js
│ ├── interceptors/
│ │ ├── cache-async-store.js
│ │ ├── cache-query-params.js
│ │ ├── cache-revalidate-stale.js
│ │ ├── cache.js
│ │ ├── decompress.js
│ │ ├── deduplicate.js
│ │ ├── dns.js
│ │ ├── dump-interceptor.js
│ │ ├── redirect-cross-origin-fix.js
│ │ ├── redirect-issue-3803.js
│ │ ├── redirect.js
│ │ ├── response-error.js
│ │ └── retry.js
│ ├── invalid-headers.js
│ ├── ip-prioritization.js
│ ├── issue-1757.js
│ ├── issue-2065.js
│ ├── issue-2078.js
│ ├── issue-2283.js
│ ├── issue-2349.js
│ ├── issue-2590.js
│ ├── issue-3356.js
│ ├── issue-3410.js
│ ├── issue-3904.js
│ ├── issue-3934.js
│ ├── issue-3959.js
│ ├── issue-4244.js
│ ├── issue-4691.js
│ ├── issue-4806.js
│ ├── issue-4880.js
│ ├── issue-803.js
│ ├── issue-810.js
│ ├── jest/
│ │ ├── instanceof-error.test.js
│ │ ├── issue-1757.test.js
│ │ ├── mock-agent.test.js
│ │ ├── mock-scope.test.js
│ │ ├── parser-timeout.test.js
│ │ ├── test.js
│ │ └── util-timers.test.js
│ ├── max-headers.js
│ ├── max-response-size.js
│ ├── mock-agent.js
│ ├── mock-call-history-log.js
│ ├── mock-call-history.js
│ ├── mock-client.js
│ ├── mock-delayed-abort.js
│ ├── mock-errors.js
│ ├── mock-interceptor-unused-assertions.js
│ ├── mock-interceptor.js
│ ├── mock-pool.js
│ ├── mock-scope.js
│ ├── mock-utils.js
│ ├── no-strict-content-length.js
│ ├── node-fetch/
│ │ ├── LICENSE
│ │ ├── headers.js
│ │ ├── main.js
│ │ ├── mock.js
│ │ ├── request.js
│ │ ├── response.js
│ │ └── utils/
│ │ ├── dummy.txt
│ │ ├── read-stream.js
│ │ └── server.js
│ ├── node-platform-objects.js
│ ├── node-test/
│ │ ├── abort-controller.js
│ │ ├── abort-event-emitter.js
│ │ ├── agent.js
│ │ ├── async_hooks.js
│ │ ├── autoselectfamily.js
│ │ ├── balanced-pool.js
│ │ ├── ca-fingerprint.js
│ │ ├── client-abort.js
│ │ ├── client-connect.js
│ │ ├── client-dispatch.js
│ │ ├── client-errors.js
│ │ ├── debug.js
│ │ ├── diagnostics-channel/
│ │ │ ├── connect-error.js
│ │ │ ├── error.js
│ │ │ ├── get-h2.js
│ │ │ ├── get.js
│ │ │ ├── post-stream.js
│ │ │ └── post.js
│ │ ├── large-body.js
│ │ ├── tree.js
│ │ ├── unix.js
│ │ ├── util.js
│ │ └── validations.js
│ ├── parser-issues.js
│ ├── pipeline-pipelining.js
│ ├── pool-connection-error-memory-leak.js
│ ├── pool.js
│ ├── promises.js
│ ├── proxy-agent.js
│ ├── proxy.js
│ ├── readable.js
│ ├── redirect-pipeline.js
│ ├── redirect-request.js
│ ├── redirect-stream.js
│ ├── request-crlf.js
│ ├── request-signal.js
│ ├── request-timeout.js
│ ├── request-timeout2.js
│ ├── request.js
│ ├── retry-agent.js
│ ├── retry-handler.js
│ ├── retry-handler2.js
│ ├── round-robin-pool.js
│ ├── snapshot-recorder.js
│ ├── snapshot-redirect-interceptor.js
│ ├── snapshot-testing.js
│ ├── socket-back-pressure.js
│ ├── socket-timeout.js
│ ├── socks5-client.js
│ ├── socks5-proxy-agent.js
│ ├── socks5-utils.js
│ ├── stream-compat.js
│ ├── subresource-integrity/
│ │ ├── apply-algorithm-to-bytes.js
│ │ ├── bytes-match.js
│ │ ├── case-sensitive-match.js
│ │ ├── get-strongest-metadata.js
│ │ ├── is-valid-sri-hash-algorithm.js
│ │ └── parse-metadata.js
│ ├── sync-error-in-callback.js
│ ├── timers.js
│ ├── tls-cert-leak.js
│ ├── tls-session-reuse.js
│ ├── tls.js
│ ├── trailers.js
│ ├── types/
│ │ ├── agent.test-d.ts
│ │ ├── api.test-d.ts
│ │ ├── balanced-pool.test-d.ts
│ │ ├── cache-interceptor.test-d.ts
│ │ ├── cache-storage.test-d.ts
│ │ ├── client.test-d.ts
│ │ ├── connector.test-d.ts
│ │ ├── diagnostics-channel.test-d.ts
│ │ ├── dispatcher.events.test-d.ts
│ │ ├── dispatcher.test-d.ts
│ │ ├── dns-interceptor.test-d.ts
│ │ ├── env-http-proxy-agent.test-d.ts
│ │ ├── errors.test-d.ts
│ │ ├── event-source-d.ts
│ │ ├── fetch.test-d.ts
│ │ ├── formdata.test-d.ts
│ │ ├── global-dispatcher.test-d.ts
│ │ ├── header.test-d.ts
│ │ ├── index.test-d.ts
│ │ ├── mock-agent.test-d.ts
│ │ ├── mock-call-history.test-d.ts
│ │ ├── mock-client.test-d.ts
│ │ ├── mock-errors.test-d.ts
│ │ ├── mock-interceptor.test-d.ts
│ │ ├── mock-pool.test-d.ts
│ │ ├── pool.test-d.ts
│ │ ├── proxy-agent.test-d.ts
│ │ ├── readable.test-d.ts
│ │ ├── retry-agent.test-d.ts
│ │ ├── retry-handler.test-d.ts
│ │ ├── snapshot-agent.test-d.ts
│ │ ├── util.test-d.ts
│ │ └── websocket.test-d.ts
│ ├── upgrade-crlf.js
│ ├── util.js
│ ├── utils/
│ │ ├── async-iterators.js
│ │ ├── date.js
│ │ ├── esm-wrapper.mjs
│ │ ├── event-loop-blocker.js
│ │ ├── formdata.js
│ │ ├── hello-world-server.js
│ │ ├── node-http.js
│ │ ├── redirecting-servers.js
│ │ └── stream.js
│ ├── web-platform-tests/
│ │ ├── expectation.json
│ │ ├── runner/
│ │ │ ├── certs/
│ │ │ │ ├── cacert.key
│ │ │ │ ├── cacert.pem
│ │ │ │ ├── web-platform.test.key
│ │ │ │ └── web-platform.test.pem
│ │ │ ├── config.json
│ │ │ ├── test-runner.mjs
│ │ │ └── utils.mjs
│ │ └── wpt-runner.mjs
│ ├── webidl/
│ │ ├── converters.js
│ │ ├── errors.js
│ │ ├── helpers.js
│ │ └── util.js
│ └── websocket/
│ ├── client-received-masked-frame.js
│ ├── close-invalid-status-code.js
│ ├── close-invalid-utf-8.js
│ ├── close.js
│ ├── constructor.js
│ ├── continuation-frames.js
│ ├── custom-headers.js
│ ├── diagnostics-channel-handshake-response.js
│ ├── diagnostics-channel-open-close.js
│ ├── diagnostics-channel-ping-pong.js
│ ├── events.js
│ ├── fragments.js
│ ├── frame.js
│ ├── issue-2679.js
│ ├── issue-2844.js
│ ├── issue-2859.js
│ ├── issue-3202.js
│ ├── issue-3506.js
│ ├── issue-3546.js
│ ├── issue-3697-2399493917.js
│ ├── issue-4273.js
│ ├── issue-4487.js
│ ├── issue-4628.js
│ ├── issue-4889.js
│ ├── messageevent.js
│ ├── opening-handshake.js
│ ├── permessage-deflate-limit.js
│ ├── permessage-deflate-windowbits.js
│ ├── ping-pong.js
│ ├── ping-util.js
│ ├── receive.js
│ ├── receiver-unit.js
│ ├── send-mutable.js
│ ├── send.js
│ ├── stream/
│ │ └── readable-closed-after-close.js
│ ├── util.js
│ └── websocketinit.js
└── types/
├── README.md
├── agent.d.ts
├── api.d.ts
├── balanced-pool.d.ts
├── cache-interceptor.d.ts
├── cache.d.ts
├── client-stats.d.ts
├── client.d.ts
├── connector.d.ts
├── content-type.d.ts
├── cookies.d.ts
├── diagnostics-channel.d.ts
├── dispatcher.d.ts
├── env-http-proxy-agent.d.ts
├── errors.d.ts
├── eventsource.d.ts
├── fetch.d.ts
├── formdata.d.ts
├── global-dispatcher.d.ts
├── global-origin.d.ts
├── h2c-client.d.ts
├── handlers.d.ts
├── header.d.ts
├── index.d.ts
├── interceptors.d.ts
├── mock-agent.d.ts
├── mock-call-history.d.ts
├── mock-client.d.ts
├── mock-errors.d.ts
├── mock-interceptor.d.ts
├── mock-pool.d.ts
├── patch.d.ts
├── pool-stats.d.ts
├── pool.d.ts
├── proxy-agent.d.ts
├── readable.d.ts
├── retry-agent.d.ts
├── retry-handler.d.ts
├── round-robin-pool.d.ts
├── snapshot-agent.d.ts
├── socks5-proxy-agent.d.ts
├── util.d.ts
├── utility.d.ts
├── webidl.d.ts
└── websocket.d.ts
SYMBOL INDEX (2729 symbols across 300 files)
FILE: benchmarks/_util/index.js
function makeParallelRequests (line 5) | function makeParallelRequests (cb) {
function printResults (line 13) | function printResults (results) {
function formatBytes (line 57) | function formatBytes (num) {
FILE: benchmarks/_util/runner.js
class Info (line 5) | class Info {
method constructor (line 21) | constructor (name, callback) {
method name (line 26) | get name () {
method start (line 30) | start () {
method end (line 37) | end () {
method diff (line 46) | diff () {
function bench (line 61) | async function bench (experiments, options = {}) {
FILE: benchmarks/benchmark-http2.js
class SimpleRequest (line 85) | class SimpleRequest {
method constructor (line 86) | constructor (resolve) {
method onConnect (line 94) | onConnect (abort) { }
method onHeaders (line 96) | onHeaders (statusCode, headers, resume) {
method onData (line 100) | onData (chunk) {
method onComplete (line 104) | onComplete () {
method onError (line 108) | onError (err) {
function makeParallelRequests (line 113) | function makeParallelRequests (cb) {
function printResults (line 119) | function printResults (results) {
method 'native - http2' (line 161) | 'native - http2' () {
method 'undici - pipeline' (line 185) | 'undici - pipeline' () {
method 'undici - request' (line 202) | 'undici - request' () {
method 'undici - stream' (line 226) | 'undici - stream' () {
method 'undici - dispatch' (line 239) | 'undici - dispatch' () {
method write (line 251) | write () { }
method close (line 251) | close () { resolve() }
function main (line 257) | async function main () {
FILE: benchmarks/benchmark-https.js
class SimpleRequest (line 101) | class SimpleRequest {
method constructor (line 102) | constructor (resolve) {
method onConnect (line 110) | onConnect (abort) { }
method onHeaders (line 112) | onHeaders (statusCode, headers, resume) {
method onData (line 116) | onData (chunk) {
method onComplete (line 120) | onComplete () {
method onError (line 124) | onError (err) {
function makeParallelRequests (line 129) | function makeParallelRequests (cb) {
function printResults (line 133) | function printResults (results) {
method 'https - no keepalive' (line 173) | 'https - no keepalive' () {
method 'https - keepalive' (line 188) | 'https - keepalive' () {
method 'undici - pipeline' (line 203) | 'undici - pipeline' () {
method 'undici - request' (line 220) | 'undici - request' () {
method 'undici - stream' (line 235) | 'undici - stream' () {
method 'undici - dispatch' (line 248) | 'undici - dispatch' () {
method write (line 260) | write () { }
method close (line 260) | close () { resolve() }
function main (line 266) | async function main () {
FILE: benchmarks/benchmark.js
class SimpleRequest (line 113) | class SimpleRequest {
method constructor (line 114) | constructor (resolve) {
method onConnect (line 122) | onConnect (abort) { }
method onHeaders (line 124) | onHeaders (statusCode, headers, resume) {
method onData (line 128) | onData (chunk) {
method onComplete (line 132) | onComplete () {
method onError (line 136) | onError (err) {
method 'http - no keepalive' (line 142) | 'http - no keepalive' () {
method 'http - keepalive' (line 157) | 'http - keepalive' () {
method 'undici - pipeline' (line 172) | 'undici - pipeline' () {
method 'undici - request' (line 189) | 'undici - request' () {
method 'undici - stream' (line 204) | 'undici - stream' () {
method 'undici - dispatch' (line 217) | 'undici - dispatch' () {
method write (line 229) | write () { }
method close (line 229) | close () { resolve() }
method write (line 238) | write (chunk, encoding, callback) {
method write (line 256) | write (chunk, encoding, callback) {
method write (line 276) | write (chunk, encoding, callback) {
method write (line 302) | write (chunk, encoding, callback) {
function main (line 310) | async function main () {
FILE: benchmarks/cache/date.mjs
constant DATES (line 6) | const DATES = [
FILE: benchmarks/core/is-valid-header-char.mjs
function charCodeAtApproach (line 12) | function charCodeAtApproach (characters) {
FILE: benchmarks/fetch/headers.mjs
function generateAsciiString (line 7) | function generateAsciiString (length) {
FILE: benchmarks/fetch/isomorphic-encode.mjs
function generateAsciiString (line 8) | function generateAsciiString (length) {
function isomorphicEncode1 (line 18) | function isomorphicEncode1 (input) {
function isomorphicEncode2 (line 27) | function isomorphicEncode2 (input) {
FILE: benchmarks/post-benchmark.js
class SimpleRequest (line 123) | class SimpleRequest {
method constructor (line 124) | constructor (resolve) {
method onConnect (line 132) | onConnect (abort) { }
method onHeaders (line 134) | onHeaders (statusCode, headers, resume) {
method onData (line 138) | onData (chunk) {
method onComplete (line 142) | onComplete () {
method onError (line 146) | onError (err) {
method 'http - no keepalive' (line 152) | 'http - no keepalive' () {
method 'http - keepalive' (line 168) | 'http - keepalive' () {
method 'undici - pipeline' (line 184) | 'undici - pipeline' () {
method 'undici - request' (line 210) | 'undici - request' () {
method 'undici - stream' (line 225) | 'undici - stream' () {
method 'undici - dispatch' (line 238) | 'undici - dispatch' () {
method write (line 256) | write () { }
method close (line 256) | close () { resolve() }
method write (line 269) | write (chunk, encoding, callback) {
method write (line 289) | write (chunk, encoding, callback) {
method write (line 311) | write (chunk, encoding, callback) {
method write (line 344) | write (chunk, encoding, callback) {
function main (line 352) | async function main () {
FILE: benchmarks/websocket-benchmark.mjs
function onOpen (line 50) | function onOpen () {
function onError (line 55) | function onError (err) {
function onOpen (line 123) | function onOpen () {
function onError (line 128) | function onError (err) {
function init (line 146) | async function init () {
function print (line 198) | function print (results) {
FILE: build/wasm.js
constant WASM_BUILDER_CONTAINER (line 3) | const WASM_BUILDER_CONTAINER = 'ghcr.io/nodejs/wasm-builder@sha256:975f3...
constant ROOT (line 9) | const ROOT = resolve(__dirname, '../')
constant WASM_SRC (line 10) | const WASM_SRC = resolve(__dirname, '../deps/llhttp')
constant WASM_OUT (line 11) | const WASM_OUT = resolve(__dirname, '../lib/llhttp')
constant WASM_CC (line 14) | const WASM_CC = process.env.WASM_CC || 'clang'
constant WASM_CFLAGS (line 15) | let WASM_CFLAGS = process.env.WASM_CFLAGS || '--sysroot=/usr/share/wasi-...
constant WASM_LDFLAGS (line 16) | let WASM_LDFLAGS = process.env.WASM_LDFLAGS || ''
constant WASM_LDLIBS (line 17) | const WASM_LDLIBS = process.env.WASM_LDLIBS || ''
constant WASM_OPT (line 18) | const WASM_OPT = process.env.WASM_OPT || 'wasm-opt'
constant EXTERNAL_PATH (line 21) | const EXTERNAL_PATH = process.env.EXTERNAL_PATH
constant WASM_OPT_FLAGS (line 29) | const WASM_OPT_FLAGS = '-O4 --converge --strip-debug --strip-dwarf --str...
FILE: deps/llhttp/include/llhttp.h
type llhttp__internal_t (line 17) | typedef struct llhttp__internal_s llhttp__internal_t;
type llhttp__internal_s (line 18) | struct llhttp__internal_s {
type llhttp_errno (line 57) | enum llhttp_errno {
type llhttp_errno_t (line 96) | typedef enum llhttp_errno llhttp_errno_t;
type llhttp_flags (line 98) | enum llhttp_flags {
type llhttp_flags_t (line 109) | typedef enum llhttp_flags llhttp_flags_t;
type llhttp_lenient_flags (line 111) | enum llhttp_lenient_flags {
type llhttp_lenient_flags_t (line 123) | typedef enum llhttp_lenient_flags llhttp_lenient_flags_t;
type llhttp_type (line 125) | enum llhttp_type {
type llhttp_type_t (line 130) | typedef enum llhttp_type llhttp_type_t;
type llhttp_finish (line 132) | enum llhttp_finish {
type llhttp_finish_t (line 137) | typedef enum llhttp_finish llhttp_finish_t;
type llhttp_method (line 139) | enum llhttp_method {
type llhttp_method_t (line 188) | typedef enum llhttp_method llhttp_method_t;
type llhttp_status (line 190) | enum llhttp_status {
type llhttp_status_t (line 291) | typedef enum llhttp_status llhttp_status_t;
type llhttp__internal_t (line 561) | typedef llhttp__internal_t llhttp_t;
type llhttp_settings_t (line 562) | typedef struct llhttp_settings_s llhttp_settings_t;
type llhttp_settings_s (line 567) | struct llhttp_settings_s {
FILE: deps/llhttp/src/api.c
function llhttp_init (line 33) | void llhttp_init(llhttp_t* parser, llhttp_type_t type,
function wasm_on_headers_complete_wrap (line 54) | static int wasm_on_headers_complete_wrap(llhttp_t* p) {
function llhttp_t (line 71) | llhttp_t* llhttp_alloc(llhttp_type_t type) {
function llhttp_free (line 77) | void llhttp_free(llhttp_t* parser) {
function llhttp_get_type (line 85) | uint8_t llhttp_get_type(llhttp_t* parser) {
function llhttp_get_http_major (line 89) | uint8_t llhttp_get_http_major(llhttp_t* parser) {
function llhttp_get_http_minor (line 93) | uint8_t llhttp_get_http_minor(llhttp_t* parser) {
function llhttp_get_method (line 97) | uint8_t llhttp_get_method(llhttp_t* parser) {
function llhttp_get_status_code (line 101) | int llhttp_get_status_code(llhttp_t* parser) {
function llhttp_get_upgrade (line 105) | uint8_t llhttp_get_upgrade(llhttp_t* parser) {
function llhttp_reset (line 110) | void llhttp_reset(llhttp_t* parser) {
function llhttp_errno_t (line 125) | llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t...
function llhttp_settings_init (line 130) | void llhttp_settings_init(llhttp_settings_t* settings) {
function llhttp_errno_t (line 135) | llhttp_errno_t llhttp_finish(llhttp_t* parser) {
function llhttp_pause (line 160) | void llhttp_pause(llhttp_t* parser) {
function llhttp_resume (line 170) | void llhttp_resume(llhttp_t* parser) {
function llhttp_resume_after_upgrade (line 179) | void llhttp_resume_after_upgrade(llhttp_t* parser) {
function llhttp_errno_t (line 188) | llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
function llhttp_set_error_reason (line 198) | void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
function llhttp_set_lenient_headers (line 237) | void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
function llhttp_set_lenient_chunked_length (line 246) | void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) {
function llhttp_set_lenient_keep_alive (line 255) | void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
function llhttp_set_lenient_transfer_encoding (line 263) | void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled) {
function llhttp_set_lenient_version (line 271) | void llhttp_set_lenient_version(llhttp_t* parser, int enabled) {
function llhttp_set_lenient_data_after_close (line 279) | void llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled) {
function llhttp_set_lenient_optional_lf_after_cr (line 287) | void llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabl...
function llhttp_set_lenient_optional_crlf_after_chunk (line 295) | void llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int ...
function llhttp_set_lenient_optional_cr_before_lf (line 303) | void llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enab...
function llhttp_set_lenient_spaces_after_chunk_size (line 311) | void llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int en...
function llhttp__on_message_begin (line 322) | int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* end...
function llhttp__on_protocol (line 329) | int llhttp__on_protocol(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_protocol_complete (line 336) | int llhttp__on_protocol_complete(llhttp_t* s, const char* p, const char*...
function llhttp__on_url (line 343) | int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_url_complete (line 350) | int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_status (line 357) | int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_status_complete (line 364) | int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* e...
function llhttp__on_method (line 371) | int llhttp__on_method(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_method_complete (line 378) | int llhttp__on_method_complete(llhttp_t* s, const char* p, const char* e...
function llhttp__on_version (line 385) | int llhttp__on_version(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_version_complete (line 392) | int llhttp__on_version_complete(llhttp_t* s, const char* p, const char* ...
function llhttp__on_header_field (line 399) | int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_header_field_complete (line 406) | int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const c...
function llhttp__on_header_value (line 413) | int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_header_value_complete (line 420) | int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const c...
function llhttp__on_headers_complete (line 427) | int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* ...
function llhttp__on_message_complete (line 434) | int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* ...
function llhttp__on_body (line 441) | int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_chunk_header (line 448) | int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
function llhttp__on_chunk_extension_name (line 455) | int llhttp__on_chunk_extension_name(llhttp_t* s, const char* p, const ch...
function llhttp__on_chunk_extension_name_complete (line 462) | int llhttp__on_chunk_extension_name_complete(llhttp_t* s, const char* p,...
function llhttp__on_chunk_extension_value (line 469) | int llhttp__on_chunk_extension_value(llhttp_t* s, const char* p, const c...
function llhttp__on_chunk_extension_value_complete (line 476) | int llhttp__on_chunk_extension_value_complete(llhttp_t* s, const char* p...
function llhttp__on_chunk_complete (line 483) | int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* en...
function llhttp__on_reset (line 490) | int llhttp__on_reset(llhttp_t* s, const char* p, const char* endp) {
function llhttp__debug (line 500) | void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
FILE: deps/llhttp/src/http.c
function llhttp__before_headers_complete (line 11) | int llhttp__before_headers_complete(llhttp_t* parser, const char* p,
function llhttp__after_headers_complete (line 37) | int llhttp__after_headers_complete(llhttp_t* parser, const char* p,
function llhttp__after_message_complete (line 116) | int llhttp__after_message_complete(llhttp_t* parser, const char* p,
function llhttp_message_needs_eof (line 129) | int llhttp_message_needs_eof(const llhttp_t* parser) {
function llhttp_should_keep_alive (line 156) | int llhttp_should_keep_alive(const llhttp_t* parser) {
FILE: deps/llhttp/src/llhttp.c
type llparse_match_status_e (line 235) | enum llparse_match_status_e {
type llparse_match_status_t (line 240) | typedef enum llparse_match_status_e llparse_match_status_t;
type llparse_match_s (line 242) | struct llparse_match_s {
type llparse_match_t (line 246) | typedef struct llparse_match_s llparse_match_t;
function llparse_match_t (line 248) | static llparse_match_t llparse__match_sequence_to_lower(
function llparse_match_t (line 280) | static llparse_match_t llparse__match_sequence_to_lower_unsafe(
function llparse_match_t (line 312) | static llparse_match_t llparse__match_sequence_id(
type llparse_state_e (line 344) | enum llparse_state_e {
type llparse_state_t (line 600) | typedef enum llparse_state_e llparse_state_t;
function llhttp__internal__c_load_initial_message_completed (line 642) | int llhttp__internal__c_load_initial_message_completed(
function llhttp__internal__c_update_finish (line 653) | int llhttp__internal__c_update_finish(
function llhttp__internal__c_load_type (line 665) | int llhttp__internal__c_load_type(
function llhttp__internal__c_store_method (line 672) | int llhttp__internal__c_store_method(
function llhttp__internal__c_is_equal_method (line 685) | int llhttp__internal__c_is_equal_method(
function llhttp__internal__c_update_http_major (line 692) | int llhttp__internal__c_update_http_major(
function llhttp__internal__c_update_http_minor (line 700) | int llhttp__internal__c_update_http_minor(
function llhttp__internal__c_test_lenient_flags (line 712) | int llhttp__internal__c_test_lenient_flags(
function llhttp__internal__c_test_lenient_flags_1 (line 719) | int llhttp__internal__c_test_lenient_flags_1(
function llhttp__internal__c_test_flags (line 726) | int llhttp__internal__c_test_flags(
function llhttp__internal__c_is_equal_upgrade (line 741) | int llhttp__internal__c_is_equal_upgrade(
function llhttp__internal__c_update_content_length (line 752) | int llhttp__internal__c_update_content_length(
function llhttp__internal__c_update_initial_message_completed (line 760) | int llhttp__internal__c_update_initial_message_completed(
function llhttp__internal__c_update_finish_1 (line 768) | int llhttp__internal__c_update_finish_1(
function llhttp__internal__c_test_lenient_flags_2 (line 776) | int llhttp__internal__c_test_lenient_flags_2(
function llhttp__internal__c_test_lenient_flags_3 (line 783) | int llhttp__internal__c_test_lenient_flags_3(
function llhttp__internal__c_mul_add_content_length (line 802) | int llhttp__internal__c_mul_add_content_length(
function llhttp__internal__c_test_lenient_flags_4 (line 828) | int llhttp__internal__c_test_lenient_flags_4(
function llhttp__internal__c_is_equal_content_length (line 839) | int llhttp__internal__c_is_equal_content_length(
function llhttp__internal__c_test_lenient_flags_7 (line 846) | int llhttp__internal__c_test_lenient_flags_7(
function llhttp__internal__c_or_flags (line 853) | int llhttp__internal__c_or_flags(
function llhttp__internal__c_test_lenient_flags_8 (line 861) | int llhttp__internal__c_test_lenient_flags_8(
function llhttp__internal__c_update_finish_3 (line 876) | int llhttp__internal__c_update_finish_3(
function llhttp__internal__c_or_flags_1 (line 884) | int llhttp__internal__c_or_flags_1(
function llhttp__internal__c_update_upgrade (line 892) | int llhttp__internal__c_update_upgrade(
function llhttp__internal__c_store_header_state (line 900) | int llhttp__internal__c_store_header_state(
function llhttp__internal__c_load_header_state (line 913) | int llhttp__internal__c_load_header_state(
function llhttp__internal__c_test_flags_4 (line 920) | int llhttp__internal__c_test_flags_4(
function llhttp__internal__c_test_lenient_flags_22 (line 927) | int llhttp__internal__c_test_lenient_flags_22(
function llhttp__internal__c_or_flags_5 (line 934) | int llhttp__internal__c_or_flags_5(
function llhttp__internal__c_update_header_state (line 942) | int llhttp__internal__c_update_header_state(
function llhttp__internal__c_or_flags_6 (line 954) | int llhttp__internal__c_or_flags_6(
function llhttp__internal__c_or_flags_7 (line 962) | int llhttp__internal__c_or_flags_7(
function llhttp__internal__c_or_flags_8 (line 970) | int llhttp__internal__c_or_flags_8(
function llhttp__internal__c_update_header_state_3 (line 978) | int llhttp__internal__c_update_header_state_3(
function llhttp__internal__c_update_header_state_1 (line 986) | int llhttp__internal__c_update_header_state_1(
function llhttp__internal__c_update_header_state_6 (line 994) | int llhttp__internal__c_update_header_state_6(
function llhttp__internal__c_update_header_state_7 (line 1002) | int llhttp__internal__c_update_header_state_7(
function llhttp__internal__c_test_flags_2 (line 1010) | int llhttp__internal__c_test_flags_2(
function llhttp__internal__c_mul_add_content_length_1 (line 1017) | int llhttp__internal__c_mul_add_content_length_1(
function llhttp__internal__c_or_flags_17 (line 1043) | int llhttp__internal__c_or_flags_17(
function llhttp__internal__c_test_flags_3 (line 1051) | int llhttp__internal__c_test_flags_3(
function llhttp__internal__c_test_lenient_flags_20 (line 1058) | int llhttp__internal__c_test_lenient_flags_20(
function llhttp__internal__c_or_flags_18 (line 1065) | int llhttp__internal__c_or_flags_18(
function llhttp__internal__c_and_flags (line 1073) | int llhttp__internal__c_and_flags(
function llhttp__internal__c_update_header_state_8 (line 1081) | int llhttp__internal__c_update_header_state_8(
function llhttp__internal__c_or_flags_20 (line 1089) | int llhttp__internal__c_or_flags_20(
function llhttp__internal__c_load_method (line 1101) | int llhttp__internal__c_load_method(
function llhttp__internal__c_store_http_major (line 1108) | int llhttp__internal__c_store_http_major(
function llhttp__internal__c_store_http_minor (line 1117) | int llhttp__internal__c_store_http_minor(
function llhttp__internal__c_test_lenient_flags_24 (line 1126) | int llhttp__internal__c_test_lenient_flags_24(
function llhttp__internal__c_load_http_major (line 1137) | int llhttp__internal__c_load_http_major(
function llhttp__internal__c_load_http_minor (line 1144) | int llhttp__internal__c_load_http_minor(
function llhttp__internal__c_update_status_code (line 1151) | int llhttp__internal__c_update_status_code(
function llhttp__internal__c_mul_add_status_code (line 1159) | int llhttp__internal__c_mul_add_status_code(
function llhttp__internal__c_update_type (line 1189) | int llhttp__internal__c_update_type(
function llhttp__internal__c_update_type_1 (line 1197) | int llhttp__internal__c_update_type_1(
function llhttp__internal_init (line 1205) | int llhttp__internal_init(llhttp__internal_t* state) {
function llparse_state_t (line 1211) | static llparse_state_t llhttp__internal__run(
function llhttp__internal_execute (line 10067) | int llhttp__internal_execute(llhttp__internal_t* state, const char* p, c...
FILE: docs/examples/ca-fingerprint/index.js
method connect (line 23) | connect (opts, cb) {
function getIssuerCertificate (line 55) | function getIssuerCertificate (socket) {
function getFingerprint (line 75) | function getFingerprint (content, inputEncoding = 'base64', outputEncodi...
FILE: docs/examples/eventsource.js
function main (line 6) | async function main () {
FILE: docs/examples/fetch.js
function main (line 5) | async function main () {
FILE: docs/examples/proxy-agent.js
function main (line 7) | async function main () {
FILE: docs/examples/proxy/index.js
function run (line 12) | async function run () {
FILE: docs/examples/proxy/proxy.js
class HTTPHandler (line 38) | class HTTPHandler {
method constructor (line 39) | constructor (ctx) {
method onConnect (line 52) | onConnect (abort) {
method onHeaders (line 61) | onHeaders (statusCode, headers, resume) {
method onData (line 75) | onData (chunk) {
method onComplete (line 79) | onComplete () {
method onError (line 87) | onError (err) {
class WSHandler (line 95) | class WSHandler {
method constructor (line 96) | constructor (ctx) {
method onConnect (line 111) | onConnect (abort) {
method onUpgrade (line 120) | onUpgrade (statusCode, headers, socket) {
method onError (line 147) | onError (err) {
constant HOP_EXPR (line 157) | const HOP_EXPR = /^(te|host|upgrade|trailers|connection|keep-alive|http2...
function getHeaders (line 162) | function getHeaders ({
function setupSocket (line 239) | function setupSocket (socket) {
function printIp (line 245) | function printIp (address, port) {
class BadGateway (line 260) | class BadGateway extends Error {
method constructor (line 261) | constructor (message = STATUS_CODES[502]) {
method toString (line 265) | toString () {
method name (line 269) | get name () {
method status (line 273) | get status () {
method statusCode (line 277) | get statusCode () {
method expose (line 281) | get expose () {
method headers (line 285) | get headers () {
class LoopDetected (line 290) | class LoopDetected extends Error {
method constructor (line 291) | constructor (message = STATUS_CODES[508]) {
method toString (line 295) | toString () {
method name (line 299) | get name () {
method status (line 303) | get status () {
method statusCode (line 307) | get statusCode () {
method expose (line 311) | get expose () {
method headers (line 315) | get headers () {
FILE: docs/examples/proxy/websocket.js
function createWebSocketServer (line 13) | function createWebSocketServer () {
function run (line 26) | async function run () {
FILE: docs/examples/request.js
function getRequest (line 5) | async function getRequest (port = 3001) {
function postJSONRequest (line 19) | async function postJSONRequest (port = 3001) {
function postFormRequest (line 42) | async function postFormRequest (port = 3001) {
function deleteRequest (line 65) | async function deleteRequest (port = 3001) {
FILE: docs/examples/snapshot-testing.js
function basicSnapshotExample (line 14) | async function basicSnapshotExample () {
function main (line 102) | async function main () {
FILE: docs/examples/socks5-proxy.js
function basicSocks5Example (line 6) | async function basicSocks5Example () {
function authenticatedSocks5Example (line 29) | async function authenticatedSocks5Example () {
function fetchWithSocks5Example (line 57) | async function fetchWithSocks5Example () {
function httpsWithSocks5Example (line 78) | async function httpsWithSocks5Example () {
function connectionPoolingExample (line 99) | async function connectionPoolingExample () {
function errorHandlingExample (line 134) | async function errorHandlingExample () {
function globalDispatcherExample (line 151) | async function globalDispatcherExample () {
function runExamples (line 182) | async function runExamples () {
FILE: index-fetch.js
function appendFetchStackTrace (line 11) | function appendFetchStackTrace (err, filename) {
FILE: index.js
function makeDispatcher (line 72) | function makeDispatcher (fn) {
function appendFetchStackTrace (line 130) | function appendFetchStackTrace (err, filename) {
function install (line 221) | function install () {
FILE: lib/api/abort-signal.js
function abort (line 9) | function abort (self) {
function addSignal (line 18) | function addSignal (self, signal) {
function removeSignal (line 41) | function removeSignal (self) {
FILE: lib/api/api-connect.js
class ConnectHandler (line 9) | class ConnectHandler extends AsyncResource {
method constructor (line 10) | constructor (opts, callback) {
method onConnect (line 35) | onConnect (abort, context) {
method onHeaders (line 47) | onHeaders () {
method onUpgrade (line 51) | onUpgrade (statusCode, rawHeaders, socket) {
method onError (line 73) | onError (err) {
function connect (line 87) | function connect (opts, callback) {
FILE: lib/api/api-pipeline.js
function noop (line 18) | function noop () {}
class PipelineRequest (line 22) | class PipelineRequest extends Readable {
method constructor (line 23) | constructor () {
method _read (line 29) | _read () {
method _destroy (line 38) | _destroy (err, callback) {
class PipelineResponse (line 45) | class PipelineResponse extends Readable {
method constructor (line 46) | constructor (resume) {
method _read (line 51) | _read () {
method _destroy (line 55) | _destroy (err, callback) {
class PipelineHandler (line 64) | class PipelineHandler extends AsyncResource {
method constructor (line 65) | constructor (opts, handler) {
method onConnect (line 149) | onConnect (abort, context) {
method onHeaders (line 163) | onHeaders (statusCode, rawHeaders, resume) {
method onData (line 225) | onData (chunk) {
method onComplete (line 230) | onComplete (trailers) {
method onError (line 235) | onError (err) {
function pipeline (line 242) | function pipeline (opts, handler) {
FILE: lib/api/api-request.js
function noop (line 9) | function noop () {}
class RequestHandler (line 11) | class RequestHandler extends AsyncResource {
method constructor (line 12) | constructor (opts, callback) {
method onConnect (line 76) | onConnect (abort, context) {
method onHeaders (line 88) | onHeaders (statusCode, rawHeaders, resume, statusMessage) {
method onData (line 147) | onData (chunk) {
method onComplete (line 151) | onComplete (trailers) {
method onError (line 156) | onError (err) {
function request (line 191) | function request (opts, callback) {
FILE: lib/api/api-stream.js
function noop (line 10) | function noop () {}
class StreamHandler (line 12) | class StreamHandler extends AsyncResource {
method constructor (line 13) | constructor (opts, factory, callback) {
method onConnect (line 69) | onConnect (abort, context) {
method onHeaders (line 81) | onHeaders (statusCode, rawHeaders, resume, statusMessage) {
method onData (line 143) | onData (chunk) {
method onComplete (line 149) | onComplete (trailers) {
method onError (line 163) | onError (err) {
function stream (line 187) | function stream (opts, factory, callback) {
FILE: lib/api/api-upgrade.js
class UpgradeHandler (line 10) | class UpgradeHandler extends AsyncResource {
method constructor (line 11) | constructor (opts, callback) {
method onConnect (line 37) | onConnect (abort, context) {
method onHeaders (line 49) | onHeaders () {
method onUpgrade (line 53) | onUpgrade (statusCode, rawHeaders, socket) {
method onError (line 70) | onError (err) {
function upgrade (line 84) | function upgrade (opts, callback) {
FILE: lib/api/readable.js
class BodyReadable (line 25) | class BodyReadable extends Readable {
method constructor (line 34) | constructor ({
method _destroy (line 85) | _destroy (err, callback) {
method on (line 110) | on (event, listener) {
method addListener (line 123) | addListener (event, listener) {
method off (line 132) | off (event, listener) {
method removeListener (line 148) | removeListener (event, listener) {
method push (line 156) | push (chunk) {
method text (line 174) | text () {
method json (line 184) | json () {
method blob (line 194) | blob () {
method bytes (line 204) | bytes () {
method arrayBuffer (line 214) | arrayBuffer () {
method formData (line 224) | async formData () {
method bodyUsed (line 237) | get bodyUsed () {
method body (line 246) | get body () {
method dump (line 265) | dump (opts) {
method setEncoding (line 325) | setEncoding (encoding) {
function isLocked (line 338) | function isLocked (bodyReadable) {
function isUnusable (line 348) | function isUnusable (bodyReadable) {
function consume (line 382) | function consume (stream, type) {
function consumeStart (line 428) | function consumeStart (consume) {
function chunksDecode (line 468) | function chunksDecode (chunks, length, encoding) {
function chunksConcat (line 495) | function chunksConcat (chunks, length) {
function consumeEnd (line 520) | function consumeEnd (consume, encoding) {
function consumePush (line 547) | function consumePush (consume, chunk) {
function consumeFinish (line 557) | function consumeFinish (consume, err) {
FILE: lib/cache/memory-cache-store.js
class MemoryCacheStore (line 18) | class MemoryCacheStore extends EventEmitter {
method constructor (line 31) | constructor (opts) {
method size (line 77) | get size () {
method isFull (line 85) | isFull () {
method get (line 93) | get (key) {
method createWriteStream (line 124) | createWriteStream (key, val) {
method delete (line 205) | delete (key) {
function findEntry (line 220) | function findEntry (key, entries, now) {
FILE: lib/cache/sqlite-cache-store.js
constant VERSION (line 8) | const VERSION = 3
constant MAX_ENTRY_SIZE (line 11) | const MAX_ENTRY_SIZE = 2 * 1000 * 1000 * 1000
method constructor (line 78) | constructor (opts) {
method close (line 225) | close () {
method get (line 233) | get (key) {
method set (line 259) | set (key, value) {
method createWriteStream (line 310) | createWriteStream (key, value) {
method delete (line 344) | delete (key) {
method #prune (line 352) | #prune () {
method size (line 378) | get size () {
method #makeValueUrl (line 387) | #makeValueUrl (key) {
method #findValue (line 396) | #findValue (key, canBeExpired = false) {
function headerValueEquals (line 442) | function headerValueEquals (lhs, rhs) {
FILE: lib/core/connect.js
method constructor (line 16) | constructor (maxCachedSessions) {
method get (line 31) | get (sessionKey) {
method set (line 36) | set (sessionKey, session) {
function buildConnector (line 46) | function buildConnector ({ allowH2, useH2c, maxCachedSessions, socketPat...
FILE: lib/core/constants.js
function getHeaderNameAsBuffer (line 122) | function getHeaderNameAsBuffer (header) {
FILE: lib/core/diagnostics.js
function trackClientEvents (line 36) | function trackClientEvents (debugLog = undiciDebugLog) {
function trackRequestEvents (line 106) | function trackRequestEvents (debugLog = undiciDebugLog) {
function trackWebSocketEvents (line 162) | function trackWebSocketEvents (debugLog = websocketDebuglog) {
FILE: lib/core/errors.js
class UndiciError (line 4) | class UndiciError extends Error {
method constructor (line 5) | constructor (message, options) {
method [kUndiciError] (line 15) | get [kUndiciError] () {
method [Symbol.hasInstance] (line 11) | static [Symbol.hasInstance] (instance) {
class ConnectTimeoutError (line 21) | class ConnectTimeoutError extends UndiciError {
method constructor (line 22) | constructor (message) {
method [kConnectTimeoutError] (line 33) | get [kConnectTimeoutError] () {
method [Symbol.hasInstance] (line 29) | static [Symbol.hasInstance] (instance) {
class HeadersTimeoutError (line 39) | class HeadersTimeoutError extends UndiciError {
method constructor (line 40) | constructor (message) {
method [kHeadersTimeoutError] (line 51) | get [kHeadersTimeoutError] () {
method [Symbol.hasInstance] (line 47) | static [Symbol.hasInstance] (instance) {
class HeadersOverflowError (line 57) | class HeadersOverflowError extends UndiciError {
method constructor (line 58) | constructor (message) {
method [kHeadersOverflowError] (line 69) | get [kHeadersOverflowError] () {
method [Symbol.hasInstance] (line 65) | static [Symbol.hasInstance] (instance) {
class BodyTimeoutError (line 75) | class BodyTimeoutError extends UndiciError {
method constructor (line 76) | constructor (message) {
method [kBodyTimeoutError] (line 87) | get [kBodyTimeoutError] () {
method [Symbol.hasInstance] (line 83) | static [Symbol.hasInstance] (instance) {
class InvalidArgumentError (line 93) | class InvalidArgumentError extends UndiciError {
method constructor (line 94) | constructor (message) {
method [kInvalidArgumentError] (line 105) | get [kInvalidArgumentError] () {
method [Symbol.hasInstance] (line 101) | static [Symbol.hasInstance] (instance) {
class InvalidReturnValueError (line 111) | class InvalidReturnValueError extends UndiciError {
method constructor (line 112) | constructor (message) {
method [kInvalidReturnValueError] (line 123) | get [kInvalidReturnValueError] () {
method [Symbol.hasInstance] (line 119) | static [Symbol.hasInstance] (instance) {
class AbortError (line 129) | class AbortError extends UndiciError {
method constructor (line 130) | constructor (message) {
method [kAbortError] (line 141) | get [kAbortError] () {
method [Symbol.hasInstance] (line 137) | static [Symbol.hasInstance] (instance) {
class RequestAbortedError (line 147) | class RequestAbortedError extends AbortError {
method constructor (line 148) | constructor (message) {
method [kRequestAbortedError] (line 159) | get [kRequestAbortedError] () {
method [Symbol.hasInstance] (line 155) | static [Symbol.hasInstance] (instance) {
class InformationalError (line 165) | class InformationalError extends UndiciError {
method constructor (line 166) | constructor (message) {
method [kInformationalError] (line 177) | get [kInformationalError] () {
method [Symbol.hasInstance] (line 173) | static [Symbol.hasInstance] (instance) {
class RequestContentLengthMismatchError (line 183) | class RequestContentLengthMismatchError extends UndiciError {
method constructor (line 184) | constructor (message) {
method [kRequestContentLengthMismatchError] (line 195) | get [kRequestContentLengthMismatchError] () {
method [Symbol.hasInstance] (line 191) | static [Symbol.hasInstance] (instance) {
class ResponseContentLengthMismatchError (line 201) | class ResponseContentLengthMismatchError extends UndiciError {
method constructor (line 202) | constructor (message) {
method [kResponseContentLengthMismatchError] (line 213) | get [kResponseContentLengthMismatchError] () {
method [Symbol.hasInstance] (line 209) | static [Symbol.hasInstance] (instance) {
class ClientDestroyedError (line 219) | class ClientDestroyedError extends UndiciError {
method constructor (line 220) | constructor (message) {
method [kClientDestroyedError] (line 231) | get [kClientDestroyedError] () {
method [Symbol.hasInstance] (line 227) | static [Symbol.hasInstance] (instance) {
class ClientClosedError (line 237) | class ClientClosedError extends UndiciError {
method constructor (line 238) | constructor (message) {
method [kClientClosedError] (line 249) | get [kClientClosedError] () {
method [Symbol.hasInstance] (line 245) | static [Symbol.hasInstance] (instance) {
class SocketError (line 255) | class SocketError extends UndiciError {
method constructor (line 256) | constructor (message, socket) {
method [kSocketError] (line 268) | get [kSocketError] () {
method [Symbol.hasInstance] (line 264) | static [Symbol.hasInstance] (instance) {
class NotSupportedError (line 274) | class NotSupportedError extends UndiciError {
method constructor (line 275) | constructor (message) {
method [kNotSupportedError] (line 286) | get [kNotSupportedError] () {
method [Symbol.hasInstance] (line 282) | static [Symbol.hasInstance] (instance) {
class BalancedPoolMissingUpstreamError (line 292) | class BalancedPoolMissingUpstreamError extends UndiciError {
method constructor (line 293) | constructor (message) {
method [kBalancedPoolMissingUpstreamError] (line 304) | get [kBalancedPoolMissingUpstreamError] () {
method [Symbol.hasInstance] (line 300) | static [Symbol.hasInstance] (instance) {
class HTTPParserError (line 310) | class HTTPParserError extends Error {
method constructor (line 311) | constructor (message, code, data) {
method [kHTTPParserError] (line 322) | get [kHTTPParserError] () {
method [Symbol.hasInstance] (line 318) | static [Symbol.hasInstance] (instance) {
class ResponseExceededMaxSizeError (line 328) | class ResponseExceededMaxSizeError extends UndiciError {
method constructor (line 329) | constructor (message) {
method [kResponseExceededMaxSizeError] (line 340) | get [kResponseExceededMaxSizeError] () {
method [Symbol.hasInstance] (line 336) | static [Symbol.hasInstance] (instance) {
class RequestRetryError (line 346) | class RequestRetryError extends UndiciError {
method constructor (line 347) | constructor (message, code, { headers, data }) {
method [kRequestRetryError] (line 361) | get [kRequestRetryError] () {
method [Symbol.hasInstance] (line 357) | static [Symbol.hasInstance] (instance) {
class ResponseError (line 367) | class ResponseError extends UndiciError {
method constructor (line 368) | constructor (message, code, { headers, body }) {
method [kResponseError] (line 382) | get [kResponseError] () {
method [Symbol.hasInstance] (line 378) | static [Symbol.hasInstance] (instance) {
class SecureProxyConnectionError (line 388) | class SecureProxyConnectionError extends UndiciError {
method constructor (line 389) | constructor (cause, message, options = {}) {
method [kSecureProxyConnectionError] (line 401) | get [kSecureProxyConnectionError] () {
method [Symbol.hasInstance] (line 397) | static [Symbol.hasInstance] (instance) {
class MaxOriginsReachedError (line 407) | class MaxOriginsReachedError extends UndiciError {
method constructor (line 408) | constructor (message) {
method [kMaxOriginsReachedError] (line 419) | get [kMaxOriginsReachedError] () {
method [Symbol.hasInstance] (line 415) | static [Symbol.hasInstance] (instance) {
class Socks5ProxyError (line 424) | class Socks5ProxyError extends UndiciError {
method constructor (line 425) | constructor (message, code) {
class MessageSizeExceededError (line 434) | class MessageSizeExceededError extends UndiciError {
method constructor (line 435) | constructor (message) {
method [kMessageSizeExceededError] (line 446) | get [kMessageSizeExceededError] () {
method [Symbol.hasInstance] (line 442) | static [Symbol.hasInstance] (instance) {
FILE: lib/core/request.js
class Request (line 32) | class Request {
method constructor (line 33) | constructor (origin, {
method onBodySent (line 217) | onBodySent (chunk) {
method onRequestSent (line 230) | onRequestSent () {
method onConnect (line 244) | onConnect (abort) {
method onResponseStarted (line 256) | onResponseStarted () {
method onHeaders (line 260) | onHeaders (statusCode, headers, resume, statusText) {
method onData (line 275) | onData (chunk) {
method onUpgrade (line 290) | onUpgrade (statusCode, headers, socket) {
method onComplete (line 297) | onComplete (trailers) {
method onError (line 316) | onError (error) {
method onFinally (line 331) | onFinally () {
method addHeader (line 343) | addHeader (key, value) {
function processHeader (line 349) | function processHeader (request, key, val) {
FILE: lib/core/socks5-client.js
constant SOCKS_VERSION (line 12) | const SOCKS_VERSION = 0x05
constant AUTH_METHODS (line 15) | const AUTH_METHODS = {
constant COMMANDS (line 23) | const COMMANDS = {
constant ADDRESS_TYPES (line 30) | const ADDRESS_TYPES = {
constant REPLY_CODES (line 37) | const REPLY_CODES = {
constant STATES (line 50) | const STATES = {
class Socks5Client (line 64) | class Socks5Client extends EventEmitter {
method constructor (line 65) | constructor (socket, options = {}) {
method onData (line 93) | onData (data) {
method onError (line 117) | onError (err) {
method onClose (line 127) | onClose () {
method destroy (line 136) | destroy () {
method handshake (line 145) | handshake () {
method handleHandshakeResponse (line 172) | handleHandshakeResponse () {
method sendAuthRequest (line 204) | sendAuthRequest () {
method handleAuthResponse (line 239) | handleAuthResponse () {
method connect (line 265) | connect (address, port) {
method buildConnectRequest (line 280) | buildConnectRequest (command, address, port) {
method handleConnectResponse (line 304) | handleConnectResponse () {
method getReplyErrorMessage (line 376) | getReplyErrorMessage (reply) {
FILE: lib/core/socks5-utils.js
function parseAddress (line 12) | function parseAddress (address) {
function parseIPv6 (line 47) | function parseIPv6 (address) {
function buildAddressBuffer (line 90) | function buildAddressBuffer (type, addressBuffer, port) {
function parseResponseAddress (line 107) | function parseResponseAddress (buffer, offset = 0) {
function createReplyError (line 179) | function createReplyError (replyCode) {
FILE: lib/core/tree.js
class TstNode (line 8) | class TstNode {
method constructor (line 24) | constructor (key, value, index) {
method add (line 45) | add (key, value) {
method search (line 91) | search (key) {
class TernarySearchTree (line 124) | class TernarySearchTree {
method insert (line 133) | insert (key, value) {
method lookup (line 145) | lookup (key) {
FILE: lib/core/util.js
class BodyAsyncIterable (line 17) | class BodyAsyncIterable {
method constructor (line 18) | constructor (body) {
method [Symbol.asyncIterator] (line 23) | async * [Symbol.asyncIterator] () {
function noop (line 30) | function noop () {}
function wrapRequestBody (line 36) | function wrapRequestBody (body) {
function isStream (line 81) | function isStream (obj) {
function isBlobLike (line 90) | function isBlobLike (object) {
function pathHasQueryOrFragment (line 111) | function pathHasQueryOrFragment (url) {
function serializePathWithQuery (line 123) | function serializePathWithQuery (url, queryParams) {
function isValidPort (line 141) | function isValidPort (port) {
function isHttpOrHttpsPrefixed (line 156) | function isHttpOrHttpsPrefixed (value) {
function parseURL (line 177) | function parseURL (url) {
function parseOrigin (line 255) | function parseOrigin (url) {
function getHostname (line 269) | function getHostname (host) {
function getServerName (line 289) | function getServerName (host) {
function deepClone (line 310) | function deepClone (obj) {
function isAsyncIterable (line 318) | function isAsyncIterable (obj) {
function isIterable (line 326) | function isIterable (obj) {
function hasSafeIterator (line 338) | function hasSafeIterator (obj) {
function bodyLength (line 348) | function bodyLength (body) {
function isDestroyed (line 369) | function isDestroyed (body) {
function destroy (line 378) | function destroy (stream, err) {
constant KEEPALIVE_TIMEOUT_EXPR (line 401) | const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/
function parseKeepAliveTimeout (line 406) | function parseKeepAliveTimeout (val) {
function headerNameToString (line 416) | function headerNameToString (value) {
function bufferToLowerCasedHeaderName (line 427) | function bufferToLowerCasedHeaderName (value) {
function parseHeaders (line 436) | function parseHeaders (headers, obj) {
function parseRawHeaders (line 466) | function parseRawHeaders (headers) {
function encodeRawHeaders (line 494) | function encodeRawHeaders (headers) {
function isBuffer (line 505) | function isBuffer (buffer) {
function assertRequestHandler (line 518) | function assertRequestHandler (handler, method, upgrade) {
function isDisturbed (line 565) | function isDisturbed (body) {
function getSocketInfo (line 586) | function getSocketInfo (socket) {
function ReadableStreamFrom (line 603) | function ReadableStreamFrom (iterable) {
function isFormDataLike (line 643) | function isFormDataLike (object) {
function addAbortListener (line 657) | function addAbortListener (signal, listener) {
function isTokenCharCode (line 690) | function isTokenCharCode (c) {
function isValidHTTPToken (line 700) | function isValidHTTPToken (characters) {
function isValidHeaderValue (line 727) | function isValidHeaderValue (characters) {
function parseRangeHeader (line 746) | function parseRangeHeader (range) {
function addListener (line 766) | function addListener (obj, name, listener) {
function removeAllListeners (line 778) | function removeAllListeners (obj) {
function errorRequest (line 793) | function errorRequest (client, request, err) {
function onConnectTimeout (line 856) | function onConnectTimeout (socket, opts) {
function getProtocolFromUrlString (line 878) | function getProtocolFromUrlString (urlString) {
FILE: lib/dispatcher/agent.js
function defaultFactory (line 18) | function defaultFactory (origin, opts) {
class Agent (line 24) | class Agent extends DispatcherBase {
method constructor (line 25) | constructor ({ factory = defaultFactory, maxOrigins = Infinity, connec...
method [kRunning] (line 66) | get [kRunning] () {
method [kDispatch] (line 74) | [kDispatch] (opts, handler) {
method [kClose] (line 127) | [kClose] () {
method [kDestroy] (line 137) | [kDestroy] (err) {
method stats (line 147) | get stats () {
FILE: lib/dispatcher/balanced-pool.js
function getGreatestCommonDivisor (line 36) | function getGreatestCommonDivisor (a, b) {
function defaultFactory (line 47) | function defaultFactory (origin, opts) {
class BalancedPool (line 51) | class BalancedPool extends PoolBase {
method constructor (line 52) | constructor (upstreams = [], { factory = defaultFactory, ...opts } = {...
method addUpstream (line 81) | addUpstream (upstream) {
method _updateBalancedPoolStats (line 121) | _updateBalancedPoolStats () {
method removeUpstream (line 130) | removeUpstream (upstream) {
method getUpstream (line 146) | getUpstream (upstream) {
method upstreams (line 156) | get upstreams () {
method [kGetDispatcher] (line 162) | [kGetDispatcher] () {
FILE: lib/dispatcher/client-h1.js
constant EMPTY_BUF (line 57) | const EMPTY_BUF = Buffer.alloc(0)
function lazyllhttp (line 63) | function lazyllhttp () {
constant USE_NATIVE_TIMER (line 192) | const USE_NATIVE_TIMER = 0
constant USE_FAST_TIMER (line 193) | const USE_FAST_TIMER = 1
constant TIMEOUT_HEADERS (line 197) | const TIMEOUT_HEADERS = 2 | USE_FAST_TIMER
constant TIMEOUT_BODY (line 198) | const TIMEOUT_BODY = 4 | USE_FAST_TIMER
constant TIMEOUT_KEEP_ALIVE (line 202) | const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER
class Parser (line 204) | class Parser {
method constructor (line 210) | constructor (client, socket, { exports }) {
method setTimeout (line 239) | setTimeout (delay, type) {
method resume (line 273) | resume () {
method readMore (line 295) | readMore () {
method execute (line 308) | execute (chunk) {
method destroy (line 369) | destroy () {
method onStatus (line 388) | onStatus (buf) {
method onMessageBegin (line 396) | onMessageBegin () {
method onHeaderField (line 416) | onHeaderField (buf) {
method onHeaderValue (line 434) | onHeaderValue (buf) {
method trackHeader (line 464) | trackHeader (len) {
method onUpgrade (line 474) | onUpgrade (head) {
method onHeadersComplete (line 524) | onHeadersComplete (statusCode, upgrade, shouldKeepAlive) {
method onBody (line 634) | onBody (buf) {
method onMessageComplete (line 670) | onMessageComplete () {
function onParserTimeout (line 738) | function onParserTimeout (parserWeakRef) {
function connectH1 (line 766) | function connectH1 (client, socket) {
function onHttpSocketError (line 865) | function onHttpSocketError (err) {
function onHttpSocketReadable (line 883) | function onHttpSocketReadable () {
function onHttpSocketEnd (line 887) | function onHttpSocketEnd () {
function onHttpSocketClose (line 899) | function onHttpSocketClose () {
function onSocketClose (line 945) | function onSocketClose () {
function resumeH1 (line 952) | function resumeH1 (client) {
function shouldSendContentLength (line 983) | function shouldSendContentLength (method) {
function writeH1 (line 992) | function writeH1 (client, request) {
function writeStream (line 1187) | function writeStream (abort, body, client, request, socket, contentLengt...
function writeBuffer (line 1325) | function writeBuffer (abort, body, client, request, socket, contentLengt...
function writeBlob (line 1366) | async function writeBlob (abort, body, client, request, socket, contentL...
function writeIterable (line 1405) | async function writeIterable (abort, body, client, request, socket, cont...
class AsyncWriter (line 1454) | class AsyncWriter {
method constructor (line 1466) | constructor ({ abort, socket, request, contentLength, client, expectsP...
method write (line 1483) | write (chunk) {
method end (line 1548) | end () {
method destroy (line 1598) | destroy (err) {
FILE: lib/dispatcher/client-h2.js
function parseH2Headers (line 71) | function parseH2Headers (headers) {
function connectH2 (line 91) | function connectH2 (client, socket) {
function resumeH2 (line 218) | function resumeH2 (client) {
function applyConnectionWindowSize (line 232) | function applyConnectionWindowSize (connectionWindowSize) {
function onHttp2RemoteSettings (line 242) | function onHttp2RemoteSettings (settings) {
function onHttp2SendPing (line 263) | function onHttp2SendPing (session) {
function onHttp2SessionError (line 288) | function onHttp2SessionError (err) {
function onHttp2FrameError (line 295) | function onHttp2FrameError (type, code, id) {
function onHttp2SessionEnd (line 303) | function onHttp2SessionEnd () {
function onHttp2SessionGoAway (line 317) | function onHttp2SessionGoAway (errorCode) {
function onHttp2SessionClose (line 350) | function onHttp2SessionClose () {
function onHttp2SocketClose (line 376) | function onHttp2SocketClose () {
function onHttp2SocketError (line 397) | function onHttp2SocketError (err) {
function onHttp2SocketEnd (line 405) | function onHttp2SocketEnd () {
function onSocketClose (line 409) | function onSocketClose () {
function shouldSendContentLength (line 414) | function shouldSendContentLength (method) {
function writeH2 (line 418) | function writeH2 (client, request) {
function writeBuffer (line 855) | function writeBuffer (abort, h2stream, body, client, request, socket, co...
function writeStream (line 878) | function writeStream (abort, socket, expectsPayload, h2stream, body, cli...
function writeBlob (line 909) | async function writeBlob (abort, h2stream, body, client, request, socket...
function writeIterable (line 937) | async function writeIterable (abort, h2stream, body, client, request, so...
FILE: lib/dispatcher/client.js
function getPipelining (line 74) | function getPipelining (client) {
class Client (line 81) | class Client extends DispatcherBase {
method constructor (line 87) | constructor (url, {
method pipelining (line 292) | get pipelining () {
method pipelining (line 296) | set pipelining (value) {
method stats (line 301) | get stats () {
method [kPending] (line 305) | get [kPending] () {
method [kRunning] (line 309) | get [kRunning] () {
method [kSize] (line 313) | get [kSize] () {
method [kConnected] (line 317) | get [kConnected] () {
method [kBusy] (line 321) | get [kBusy] () {
method [kConnect] (line 329) | [kConnect] (cb) {
method [kDispatch] (line 334) | [kDispatch] (opts, handler) {
method [kClose] (line 355) | [kClose] () {
method [kDestroy] (line 367) | [kDestroy] (err) {
function onError (line 396) | function onError (client, err) {
function connect (line 421) | function connect (client) {
function handleConnectError (line 516) | function handleConnectError (client, err, { host, hostname, protocol, po...
function emitDrain (line 552) | function emitDrain (client) {
function resume (line 557) | function resume (client, sync) {
function _resume (line 574) | function _resume (client, sync) {
FILE: lib/dispatcher/dispatcher-base.js
class DispatcherBase (line 15) | class DispatcherBase extends Dispatcher {
method destroyed (line 29) | get destroyed () {
method closed (line 34) | get closed () {
method close (line 38) | close (callback) {
method destroy (line 84) | destroy (err, callback) {
method dispatch (line 132) | dispatch (opts, handler) {
FILE: lib/dispatcher/dispatcher.js
class Dispatcher (line 7) | class Dispatcher extends EventEmitter {
method dispatch (line 8) | dispatch () {
method close (line 12) | close () {
method destroy (line 16) | destroy () {
method compose (line 20) | compose (...args) {
FILE: lib/dispatcher/env-http-proxy-agent.js
constant DEFAULT_PORTS (line 8) | const DEFAULT_PORTS = {
class EnvHttpProxyAgent (line 13) | class EnvHttpProxyAgent extends DispatcherBase {
method constructor (line 18) | constructor (opts = {}) {
method [kDispatch] (line 43) | [kDispatch] (opts, handler) {
method [kClose] (line 49) | [kClose] () {
method [kDestroy] (line 57) | [kDestroy] (err) {
method #getProxyAgentForUrl (line 65) | #getProxyAgentForUrl (url) {
method #shouldProxy (line 81) | #shouldProxy (hostname, port) {
method #parseNoProxy (line 112) | #parseNoProxy () {
method #noProxyChanged (line 134) | get #noProxyChanged () {
method #noProxyEnv (line 141) | get #noProxyEnv () {
FILE: lib/dispatcher/fixed-queue.js
class FixedCircularBuffer (line 61) | class FixedCircularBuffer {
method isEmpty (line 72) | isEmpty () {
method isFull (line 77) | isFull () {
method push (line 85) | push (data) {
method shift (line 91) | shift () {
method constructor (line 104) | constructor () {
method isEmpty (line 110) | isEmpty () {
method push (line 115) | push (data) {
method shift (line 125) | shift () {
FILE: lib/dispatcher/h2c-client.js
class H2CClient (line 6) | class H2CClient extends Client {
method constructor (line 7) | constructor (origin, clientOpts) {
FILE: lib/dispatcher/pool-base.js
class PoolBase (line 20) | class PoolBase extends DispatcherBase {
method [kOnDrain] (line 29) | [kOnDrain] (client, origin, targets) {
method [kBusy] (line 75) | get [kBusy] () {
method [kConnected] (line 79) | get [kConnected] () {
method [kFree] (line 87) | get [kFree] () {
method [kPending] (line 95) | get [kPending] () {
method [kRunning] (line 103) | get [kRunning] () {
method [kSize] (line 111) | get [kSize] () {
method stats (line 119) | get stats () {
method [kClose] (line 123) | [kClose] () {
method [kDestroy] (line 140) | [kDestroy] (err) {
method [kDispatch] (line 156) | [kDispatch] (opts, handler) {
method [kAddClient] (line 171) | [kAddClient] (client) {
method [kRemoveClient] (line 191) | [kRemoveClient] (client) {
FILE: lib/dispatcher/pool.js
function defaultFactory (line 23) | function defaultFactory (origin, opts) {
class Pool (line 27) | class Pool extends PoolBase {
method constructor (line 28) | constructor (origin, {
method [kGetDispatcher] (line 99) | [kGetDispatcher] () {
FILE: lib/dispatcher/proxy-agent.js
function defaultProtocolPort (line 21) | function defaultProtocolPort (protocol) {
function defaultFactory (line 25) | function defaultFactory (origin, opts) {
function defaultAgentFactory (line 31) | function defaultAgentFactory (origin, opts) {
class Http1ProxyWrapper (line 38) | class Http1ProxyWrapper extends DispatcherBase {
method constructor (line 41) | constructor (proxyUrl, { headers = {}, connect, factory }) {
method [kDispatch] (line 56) | [kDispatch] (opts, handler) {
method [kClose] (line 86) | [kClose] () {
method [kDestroy] (line 90) | [kDestroy] (err) {
class ProxyAgent (line 95) | class ProxyAgent extends DispatcherBase {
method constructor (line 96) | constructor (opts) {
method dispatch (line 232) | dispatch (opts, handler) {
method #getUrl (line 254) | #getUrl (opts) {
method [kClose] (line 264) | [kClose] () {
method [kDestroy] (line 272) | [kDestroy] () {
function buildHeaders (line 285) | function buildHeaders (headers) {
function throwIfProxyAuthIsSent (line 310) | function throwIfProxyAuthIsSent (headers) {
FILE: lib/dispatcher/retry-agent.js
class RetryAgent (line 6) | class RetryAgent extends Dispatcher {
method constructor (line 9) | constructor (agent, options = {}) {
method dispatch (line 15) | dispatch (opts, handler) {
method close (line 26) | close () {
method destroy (line 30) | destroy () {
FILE: lib/dispatcher/round-robin-pool.js
function defaultFactory (line 24) | function defaultFactory (origin, opts) {
class RoundRobinPool (line 28) | class RoundRobinPool extends PoolBase {
method constructor (line 29) | constructor (origin, {
method [kGetDispatcher] (line 96) | [kGetDispatcher] () {
FILE: lib/dispatcher/socks5-proxy-agent.js
class Socks5ProxyAgent (line 29) | class Socks5ProxyAgent extends DispatcherBase {
method constructor (line 30) | constructor (proxyUrl, options = {}) {
method createSocks5Connection (line 75) | async createSocks5Connection (targetHost, targetPort) {
method [kDispatch] (line 174) | async [kDispatch] (opts, handler) {
method [kClose] (line 236) | async [kClose] () {
method [kDestroy] (line 242) | async [kDestroy] (err) {
FILE: lib/encoding/index.js
function utf8DecodeBytes (line 9) | function utf8DecodeBytes (buffer) {
FILE: lib/global.js
function setGlobalDispatcher (line 13) | function setGlobalDispatcher (agent) {
function getGlobalDispatcher (line 25) | function getGlobalDispatcher () {
FILE: lib/handler/cache-handler.js
function noop (line 11) | function noop () {}
constant HEURISTICALLY_CACHEABLE_STATUS_CODES (line 14) | const HEURISTICALLY_CACHEABLE_STATUS_CODES = [
constant NOT_UNDERSTOOD_STATUS_CODES (line 23) | const NOT_UNDERSTOOD_STATUS_CODES = [
constant MAX_RESPONSE_AGE (line 27) | const MAX_RESPONSE_AGE = 2147483647000
class CacheHandler (line 34) | class CacheHandler {
method constructor (line 70) | constructor ({ store, type, cacheByDefault }, cacheKey, handler) {
method onRequestStart (line 78) | onRequestStart (controller, context) {
method onRequestUpgrade (line 84) | onRequestUpgrade (controller, statusCode, headers, socket) {
method onResponseStart (line 94) | onResponseStart (
method onResponseData (line 316) | onResponseData (controller, chunk) {
method onResponseEnd (line 324) | onResponseEnd (controller, trailers) {
method onResponseError (line 329) | onResponseError (controller, err) {
function canCacheResponse (line 344) | function canCacheResponse (cacheType, statusCode, resHeaders, cacheContr...
function getAge (line 402) | function getAge (ageHeader) {
function determineStaleAt (line 418) | function determineStaleAt (cacheType, now, age, resHeaders, responseDate...
function determineDeleteAt (line 483) | function determineDeleteAt (now, cacheControlDirectives, staleAt) {
function stripNecessaryHeaders (line 517) | function stripNecessaryHeaders (resHeaders, cacheControlDirectives) {
function isValidDate (line 565) | function isValidDate (date) {
FILE: lib/handler/cache-revalidation-handler.js
class CacheRevalidationHandler (line 18) | class CacheRevalidationHandler {
method constructor (line 43) | constructor (callback, handler, allowErrorStatusCodes) {
method onRequestStart (line 53) | onRequestStart (_, context) {
method onRequestUpgrade (line 58) | onRequestUpgrade (controller, statusCode, headers, socket) {
method onResponseStart (line 62) | onResponseStart (
method onResponseData (line 90) | onResponseData (controller, chunk) {
method onResponseEnd (line 98) | onResponseEnd (controller, trailers) {
method onResponseError (line 106) | onResponseError (controller, err) {
FILE: lib/handler/decorator-handler.js
method constructor (line 15) | constructor (handler) {
method onRequestStart (line 22) | onRequestStart (...args) {
method onRequestUpgrade (line 26) | onRequestUpgrade (...args) {
method onResponseStart (line 33) | onResponseStart (...args) {
method onResponseData (line 43) | onResponseData (...args) {
method onResponseEnd (line 50) | onResponseEnd (...args) {
method onResponseError (line 58) | onResponseError (...args) {
method onBodySent (line 66) | onBodySent () {}
FILE: lib/handler/deduplication-handler.js
constant DEFAULT_MAX_BUFFER_SIZE (line 9) | const DEFAULT_MAX_BUFFER_SIZE = 5 * 1024 * 1024
class DeduplicationHandler (line 27) | class DeduplicationHandler {
method constructor (line 93) | constructor (primaryHandler, onComplete, maxBufferSize = DEFAULT_MAX_B...
method addWaitingHandler (line 106) | addWaitingHandler (handler) {
method onRequestStart (line 147) | onRequestStart (controller, context) {
method onRequestUpgrade (line 158) | onRequestUpgrade (controller, statusCode, headers, socket) {
method onResponseStart (line 168) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseData (line 207) | onResponseData (controller, chunk) {
method onResponseEnd (line 249) | onResponseEnd (controller, trailers) {
method onResponseError (line 292) | onResponseError (controller, err) {
method #createWaitingHandler (line 314) | #createWaitingHandler (handler) {
method #bufferWaitingChunk (line 384) | #bufferWaitingChunk (waitingHandler, chunk) {
method #flushWaitingHandler (line 405) | #flushWaitingHandler (waitingHandler) {
method #errorWaitingHandler (line 437) | #errorWaitingHandler (waitingHandler, err) {
method #pruneDoneWaitingHandlers (line 455) | #pruneDoneWaitingHandlers () {
FILE: lib/handler/redirect-handler.js
class BodyAsyncIterable (line 15) | class BodyAsyncIterable {
method constructor (line 16) | constructor (body) {
method [Symbol.asyncIterator] (line 21) | async * [Symbol.asyncIterator] () {
class RedirectHandler (line 28) | class RedirectHandler {
method buildDispatch (line 29) | static buildDispatch (dispatcher, maxRedirections) {
method constructor (line 38) | constructor (dispatch, maxRedirections, opts, handler) {
method onRequestStart (line 86) | onRequestStart (controller, context) {
method onRequestUpgrade (line 90) | onRequestUpgrade (controller, statusCode, headers, socket) {
method onResponseStart (line 94) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseData (line 155) | onResponseData (controller, chunk) {
method onResponseEnd (line 179) | onResponseEnd (controller, trailers) {
method onResponseError (line 195) | onResponseError (controller, error) {
function shouldRemoveHeader (line 201) | function shouldRemoveHeader (header, removeContent, unknownOrigin) {
function cleanRequestHeaders (line 216) | function cleanRequestHeaders (headers, removeContent, unknownOrigin) {
FILE: lib/handler/retry-handler.js
function calculateRetryAfterHeader (line 13) | function calculateRetryAfterHeader (retryAfter) {
class RetryHandler (line 18) | class RetryHandler {
method constructor (line 19) | constructor (opts, { dispatch, handler }) {
method onResponseStartWithRetry (line 74) | onResponseStartWithRetry (controller, statusCode, headers, statusMessa...
method onRequestStart (line 116) | onRequestStart (controller, context) {
method onRequestUpgrade (line 122) | onRequestUpgrade (controller, statusCode, headers, socket) {
method [kRetryHandlerDefaultRetry] (line 126) | static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) {
method onResponseStart (line 184) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseData (line 308) | onResponseData (controller, chunk) {
method onResponseEnd (line 318) | onResponseEnd (controller, trailers) {
method retry (line 331) | retry (controller) {
method onResponseError (line 357) | onResponseError (controller, err) {
FILE: lib/handler/unwrap-handler.js
class UnwrapController (line 8) | class UnwrapController {
method constructor (line 16) | constructor (abort) {
method pause (line 20) | pause () {
method resume (line 24) | resume () {
method abort (line 31) | abort (reason) {
method aborted (line 39) | get aborted () {
method reason (line 43) | get reason () {
method paused (line 47) | get paused () {
method constructor (line 56) | constructor (handler) {
method unwrap (line 60) | static unwrap (handler) {
method onConnect (line 65) | onConnect (abort, context) {
method onResponseStarted (line 70) | onResponseStarted () {
method onUpgrade (line 74) | onUpgrade (statusCode, rawHeaders, socket) {
method onHeaders (line 78) | onHeaders (statusCode, rawHeaders, resume, statusMessage) {
method onData (line 84) | onData (data) {
method onComplete (line 89) | onComplete (rawTrailers) {
method onError (line 93) | onError (err) {
FILE: lib/handler/wrap-handler.js
method constructor (line 8) | constructor (handler) {
method wrap (line 12) | static wrap (handler) {
method onConnect (line 19) | onConnect (abort, context) {
method onResponseStarted (line 23) | onResponseStarted () {
method onHeaders (line 27) | onHeaders (statusCode, rawHeaders, resume, statusMessage) {
method onUpgrade (line 31) | onUpgrade (statusCode, rawHeaders, socket) {
method onData (line 35) | onData (data) {
method onComplete (line 39) | onComplete (trailers) {
method onError (line 43) | onError (err) {
method onRequestStart (line 53) | onRequestStart (controller, context) {
method onRequestUpgrade (line 57) | onRequestUpgrade (controller, statusCode, headers, socket) {
method onResponseStart (line 66) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseData (line 77) | onResponseData (controller, data) {
method onResponseEnd (line 83) | onResponseEnd (controller, trailers) {
method onResponseError (line 92) | onResponseError (controller, err) {
function toRawHeaderValue (line 101) | function toRawHeaderValue (value) {
FILE: lib/interceptor/cache.js
function assertCacheOrigins (line 16) | function assertCacheOrigins (origins, name) {
function needsRevalidation (line 41) | function needsRevalidation (result, cacheControlDirectives, { headers = ...
function isStale (line 65) | function isStale (result, cacheControlDirectives) {
function withinStaleWhileRevalidateWindow (line 98) | function withinStaleWhileRevalidateWindow (result) {
function handleUncachedResponse (line 117) | function handleUncachedResponse (
function sendCachedValue (line 168) | function sendCachedValue (handler, opts, result, age, context, isStale) {
function handleResult (line 250) | function handleResult (
FILE: lib/interceptor/decompress.js
class DecompressHandler (line 33) | class DecompressHandler extends DecoratorHandler {
method constructor (line 41) | constructor (handler, { skipStatusCodes = defaultSkipStatusCodes, skip...
method #shouldSkipDecompression (line 53) | #shouldSkipDecompression (contentEncoding, statusCode) {
method #createDecompressionChain (line 67) | #createDecompressionChain (encodings) {
method #setupDecompressorEvents (line 101) | #setupDecompressorEvents (decompressor, controller) {
method #setupSingleDecompressor (line 122) | #setupSingleDecompressor (controller) {
method #setupMultipleDecompressors (line 136) | #setupMultipleDecompressors (controller) {
method #cleanupDecompressors (line 153) | #cleanupDecompressors () {
method onResponseStart (line 164) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseData (line 198) | onResponseData (controller, chunk) {
method onResponseEnd (line 211) | onResponseEnd (controller, trailers) {
method onResponseError (line 225) | onResponseError (controller, err) {
function createDecompressInterceptor (line 241) | function createDecompressInterceptor (options = {}) {
FILE: lib/interceptor/dns.js
function hasSafeIterator (line 8) | function hasSafeIterator (headers) {
function isHostHeader (line 14) | function isHostHeader (key) {
function normalizeHeaders (line 18) | function normalizeHeaders (headers) {
function hasHostHeader (line 56) | function hasHostHeader (headers) {
function withHostHeader (line 86) | function withHostHeader (host, headers) {
class DNSStorage (line 107) | class DNSStorage {
method constructor (line 111) | constructor (opts) {
method size (line 115) | get size () {
method get (line 119) | get (hostname) {
method set (line 123) | set (hostname, records) {
method delete (line 127) | delete (hostname) {
method full (line 132) | full () {
class DNSInstance (line 137) | class DNSInstance {
method constructor (line 146) | constructor (opts) {
method runLookup (line 156) | runLookup (origin, opts, cb) {
method #defaultLookup (line 241) | #defaultLookup (origin, opts, cb) {
method #defaultPick (line 267) | #defaultPick (origin, hostnameRecords, affinity) {
method pickFamily (line 321) | pickFamily (origin, ipFamily) {
method setRecords (line 353) | setRecords (origin, addresses) {
method deleteRecords (line 377) | deleteRecords (origin) {
method getHandler (line 381) | getHandler (meta, opts) {
class DNSDispatchHandler (line 386) | class DNSDispatchHandler extends DecoratorHandler {
method constructor (line 395) | constructor (state, { origin, handler, dispatch, newOrigin }, opts) {
method onResponseError (line 404) | onResponseError (controller, err) {
FILE: lib/interceptor/dump.js
class DumpHandler (line 6) | class DumpHandler extends DecoratorHandler {
method constructor (line 14) | constructor ({ maxSize, signal }, handler) {
method #abort (line 25) | #abort (reason) {
method onRequestStart (line 30) | onRequestStart (controller, context) {
method onResponseStart (line 37) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseError (line 55) | onResponseError (controller, err) {
method onResponseData (line 66) | onResponseData (controller, chunk) {
method onResponseEnd (line 82) | onResponseEnd (controller, trailers) {
function createDumpInterceptor (line 96) | function createDumpInterceptor (
FILE: lib/interceptor/redirect.js
function createRedirectInterceptor (line 5) | function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirec...
FILE: lib/interceptor/response-error.js
class ResponseErrorHandler (line 7) | class ResponseErrorHandler extends DecoratorHandler {
method constructor (line 14) | constructor (_opts, { handler }) {
method #checkContentType (line 18) | #checkContentType (contentType) {
method onRequestStart (line 22) | onRequestStart (controller, context) {
method onResponseStart (line 32) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseData (line 46) | onResponseData (controller, chunk) {
method onResponseEnd (line 54) | onResponseEnd (controller, trailers) {
method onResponseError (line 84) | onResponseError (controller, err) {
FILE: lib/llhttp/constants.d.ts
type IntDict (line 1) | type IntDict = Record<string, number>;
type CharList (line 18) | type CharList = (string | number)[];
FILE: lib/llhttp/utils.js
function enumToMap (line 4) | function enumToMap(obj, filter = [], exceptions = []) {
FILE: lib/mock/mock-agent.js
class MockAgent (line 31) | class MockAgent extends Dispatcher {
method constructor (line 32) | constructor (opts = {}) {
method get (line 58) | get (origin) {
method dispatch (line 72) | dispatch (opts, handler) {
method close (line 93) | async close () {
method deactivate (line 99) | deactivate () {
method activate (line 103) | activate () {
method enableNetConnect (line 107) | enableNetConnect (matcher) {
method disableNetConnect (line 121) | disableNetConnect () {
method enableCallHistory (line 125) | enableCallHistory () {
method disableCallHistory (line 131) | disableCallHistory () {
method getCallHistory (line 137) | getCallHistory () {
method clearCallHistory (line 141) | clearCallHistory () {
method isMockActive (line 149) | get isMockActive () {
method [kMockAgentRegisterCallHistory] (line 153) | [kMockAgentRegisterCallHistory] () {
method [kMockAgentAddCallHistoryLog] (line 159) | [kMockAgentAddCallHistoryLog] (opts) {
method [kMockAgentSet] (line 169) | [kMockAgentSet] (origin, dispatcher) {
method [kFactory] (line 173) | [kFactory] (origin) {
method [kMockAgentGet] (line 180) | [kMockAgentGet] (origin) {
method [kGetNetConnect] (line 205) | [kGetNetConnect] () {
method pendingInterceptors (line 209) | pendingInterceptors () {
method assertNoPendingInterceptors (line 217) | assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new Pend...
FILE: lib/mock/mock-call-history.js
function handleFilterCallsWithOptions (line 6) | function handleFilterCallsWithOptions (criteria, options, handler, store) {
function buildAndValidateFilterCallsOptions (line 20) | function buildAndValidateFilterCallsOptions (options = {}) {
function makeFilterCalls (line 37) | function makeFilterCalls (parameterName) {
function computeUrlWithMaybeSearchParameters (line 53) | function computeUrlWithMaybeSearchParameters (requestInit) {
class MockCallHistoryLog (line 74) | class MockCallHistoryLog {
method constructor (line 75) | constructor (requestInit = {}) {
method toMap (line 92) | toMap () {
method toString (line 108) | toString () {
class MockCallHistory (line 127) | class MockCallHistory {
method calls (line 130) | calls () {
method firstCall (line 134) | firstCall () {
method lastCall (line 138) | lastCall () {
method nthCall (line 142) | nthCall (number) {
method filterCalls (line 157) | filterCalls (criteria, options) {
method clear (line 228) | clear () {
method [kMockCallHistoryAddLog] (line 232) | [kMockCallHistoryAddLog] (requestInit) {
method [Symbol.iterator] (line 240) | * [Symbol.iterator] () {
FILE: lib/mock/mock-client.js
class MockClient (line 23) | class MockClient extends Client {
method constructor (line 24) | constructor (origin, opts) {
method intercept (line 50) | intercept (opts) {
method cleanMocks (line 57) | cleanMocks () {
method [kClose] (line 61) | async [kClose] () {
method [Symbols.kConnected] (line 43) | get [Symbols.kConnected] () {
FILE: lib/mock/mock-errors.js
class MockNotMatchedError (line 10) | class MockNotMatchedError extends UndiciError {
method constructor (line 11) | constructor (message) {
method [kMockNotMatchedError] (line 22) | get [kMockNotMatchedError] () {
method [Symbol.hasInstance] (line 18) | static [Symbol.hasInstance] (instance) {
FILE: lib/mock/mock-interceptor.js
class MockScope (line 19) | class MockScope {
method constructor (line 20) | constructor (mockDispatch) {
method delay (line 27) | delay (waitInMs) {
method persist (line 39) | persist () {
method times (line 47) | times (repeatTimes) {
class MockInterceptor (line 60) | class MockInterceptor {
method constructor (line 61) | constructor (opts, mockDispatches) {
method createMockScopeDispatchData (line 95) | createMockScopeDispatchData ({ statusCode, data, responseOptions }) {
method validateReplyParameters (line 104) | validateReplyParameters (replyParameters) {
method reply (line 116) | reply (replyOptionsCallbackOrStatusCode) {
method replyWithError (line 166) | replyWithError (error) {
method defaultReplyHeaders (line 178) | defaultReplyHeaders (headers) {
method defaultReplyTrailers (line 190) | defaultReplyTrailers (trailers) {
method replyContentLength (line 202) | replyContentLength () {
FILE: lib/mock/mock-pool.js
class MockPool (line 23) | class MockPool extends Pool {
method constructor (line 24) | constructor (origin, opts) {
method intercept (line 50) | intercept (opts) {
method cleanMocks (line 57) | cleanMocks () {
method [kClose] (line 61) | async [kClose] () {
method [Symbols.kConnected] (line 43) | get [Symbols.kConnected] () {
FILE: lib/mock/mock-utils.js
function matchValue (line 20) | function matchValue (match, value) {
function lowerCaseEntries (line 33) | function lowerCaseEntries (headers) {
function getHeaderByName (line 45) | function getHeaderByName (headers, key) {
function buildHeadersFromArray (line 62) | function buildHeadersFromArray (headers) { // fetch HeadersList
function matchHeaders (line 71) | function matchHeaders (mockDispatch, headers) {
function normalizeSearchParams (line 95) | function normalizeSearchParams (query) {
function safeUrl (line 126) | function safeUrl (path) {
function matchKey (line 140) | function matchKey (mockDispatch, { path, method, body, headers }) {
function getResponseData (line 148) | function getResponseData (data) {
function getMockDispatch (line 164) | function getMockDispatch (mockDispatches, key) {
function addMockDispatch (line 204) | function addMockDispatch (mockDispatches, key, data, opts) {
function deleteMockDispatch (line 212) | function deleteMockDispatch (mockDispatches, key) {
function removeTrailingSlash (line 227) | function removeTrailingSlash (path) {
function buildKey (line 239) | function buildKey (opts) {
function generateKeyValues (line 251) | function generateKeyValues (data) {
function getStatusText (line 273) | function getStatusText (statusCode) {
function getResponse (line 277) | async function getResponse (body) {
function mockDispatch (line 288) | function mockDispatch (opts, handler) {
function buildMockDispatch (line 392) | function buildMockDispatch () {
function checkNetConnect (line 422) | function checkNetConnect (netConnect, origin) {
function normalizeOrigin (line 432) | function normalizeOrigin (origin) {
function buildAndValidateMockOptions (line 444) | function buildAndValidateMockOptions (opts) {
FILE: lib/mock/pending-interceptors-formatter.js
constant PERSISTENT (line 6) | const PERSISTENT = process.versions.icu ? '✅' : 'Y '
constant NOT_PERSISTENT (line 7) | const NOT_PERSISTENT = process.versions.icu ? '❌' : 'N '
method constructor (line 13) | constructor ({ disableColors } = {}) {
method format (line 28) | format (pendingInterceptors) {
FILE: lib/mock/snapshot-agent.js
class SnapshotAgent (line 19) | class SnapshotAgent extends MockAgent {
method constructor (line 20) | constructor (opts = {}) {
method dispatch (line 81) | dispatch (opts, handler) {
method #asyncDispatch (line 125) | async #asyncDispatch (opts, handler) {
method #recordAndReplay (line 133) | #recordAndReplay (opts, handler) {
method #replaySnapshot (line 191) | #replaySnapshot (snapshot, handler) {
method loadSnapshots (line 227) | async loadSnapshots (filePath) {
method saveSnapshots (line 243) | async saveSnapshots (filePath) {
method #setupMockInterceptors (line 260) | #setupMockInterceptors () {
method getRecorder (line 287) | getRecorder () {
method getMode (line 295) | getMode () {
method clearSnapshots (line 303) | clearSnapshots () {
method resetCallCounts (line 311) | resetCallCounts () {
method deleteSnapshot (line 320) | deleteSnapshot (requestOpts) {
method getSnapshotInfo (line 328) | getSnapshotInfo (requestOpts) {
method replaceSnapshots (line 337) | replaceSnapshots (snapshotData) {
method close (line 346) | async close () {
FILE: lib/mock/snapshot-recorder.js
function formatRequestKey (line 91) | function formatRequestKey (opts, headerFilters, matchOptions = {}) {
function filterHeadersForMatching (line 115) | function filterHeadersForMatching (headers, headerFilters, matchOptions ...
function filterHeadersForStorage (line 152) | function filterHeadersForStorage (headers, headerFilters, matchOptions =...
function createRequestHash (line 181) | function createRequestHash (formattedRequest) {
class SnapshotRecorder (line 213) | class SnapshotRecorder {
method constructor (line 239) | constructor (options = {}) {
method record (line 279) | async record (requestOpts, response) {
method isUrlExcluded (line 337) | isUrlExcluded (requestOpts) {
method findSnapshot (line 349) | findSnapshot (requestOpts) {
method loadSnapshots (line 382) | async loadSnapshots (filePath) {
method saveSnapshots (line 418) | async saveSnapshots (filePath) {
method clear (line 442) | clear () {
method getSnapshots (line 450) | getSnapshots () {
method size (line 458) | size () {
method resetCallCounts (line 466) | resetCallCounts () {
method deleteSnapshot (line 477) | deleteSnapshot (requestOpts) {
method getSnapshotInfo (line 488) | getSnapshotInfo (requestOpts) {
method replaceSnapshots (line 509) | replaceSnapshots (snapshotData) {
method #startAutoFlush (line 526) | #startAutoFlush () {
method #stopAutoFlush (line 534) | #stopAutoFlush () {
method #scheduleFlush (line 548) | #scheduleFlush () {
method destroy (line 565) | destroy () {
method close (line 577) | async close () {
FILE: lib/mock/snapshot-utils.js
function createHeaderFilters (line 19) | function createHeaderFilters (matchOptions = {}) {
function isUndiciHeaders (line 59) | function isUndiciHeaders (headers) {
function isUrlExcludedFactory (line 68) | function isUrlExcludedFactory (excludePatterns = []) {
function normalizeHeaders (line 104) | function normalizeHeaders (headers) {
function validateSnapshotMode (line 145) | function validateSnapshotMode (mode) {
FILE: lib/util/cache.js
function makeCacheKey (line 14) | function makeCacheKey (opts) {
function normalizeHeaders (line 37) | function normalizeHeaders (opts) {
function assertCacheKey (line 70) | function assertCacheKey (key) {
function assertCacheValue (line 89) | function assertCacheValue (value) {
function parseCacheControlHeader (line 124) | function parseCacheControlHeader (header) {
function parseVaryHeader (line 280) | function parseVaryHeader (varyHeader, headers) {
function isEtagUsable (line 309) | function isEtagUsable (etag) {
function assertCacheStore (line 338) | function assertCacheStore (store, name = 'CacheStore') {
function assertCacheMethods (line 353) | function assertCacheMethods (methods, name = 'CacheMethods') {
function makeDeduplicationKey (line 376) | function makeDeduplicationKey (cacheKey, excludeHeaders) {
FILE: lib/util/date.js
function parseHttpDate (line 9) | function parseHttpDate (date) {
function parseImfDate (line 27) | function parseImfDate (date) {
function parseAscTimeDate (line 237) | function parseAscTimeDate (date) {
function parseRfc850Date (line 442) | function parseRfc850Date (date) {
FILE: lib/util/promise.js
function createDeferredPromise (line 15) | function createDeferredPromise () {
FILE: lib/util/runtime-features.js
function detectRuntimeFeatureByNodeModule (line 18) | function detectRuntimeFeatureByNodeModule (moduleName) {
function detectRuntimeFeatureByExportedProperty (line 35) | function detectRuntimeFeatureByExportedProperty (moduleName, property) {
function detectRuntimeFeature (line 64) | function detectRuntimeFeature (feature) {
class RuntimeFeatures (line 78) | class RuntimeFeatures {
method clear (line 85) | clear () {
method has (line 93) | has (feature) {
method set (line 103) | set (feature, value) {
method #detectRuntimeFeature (line 114) | #detectRuntimeFeature (feature) {
FILE: lib/util/stats.js
class ClientStats (line 12) | class ClientStats {
method constructor (line 13) | constructor (client) {
class PoolStats (line 21) | class PoolStats {
method constructor (line 22) | constructor (pool) {
FILE: lib/util/timers.js
constant RESOLUTION_MS (line 30) | const RESOLUTION_MS = 1e3
constant TICK_MS (line 40) | const TICK_MS = (RESOLUTION_MS >> 1) - 1
constant NOT_IN_LIST (line 78) | const NOT_IN_LIST = -2
constant TO_BE_CLEARED (line 90) | const TO_BE_CLEARED = -1
constant PENDING (line 99) | const PENDING = 0
constant ACTIVE (line 108) | const ACTIVE = 1
function onTick (line 115) | function onTick () {
function refreshTimeout (line 190) | function refreshTimeout () {
class FastTimer (line 213) | class FastTimer {
method constructor (line 269) | constructor (callback, delay, arg) {
method refresh (line 286) | refresh () {
method clear (line 311) | clear () {
method setTimeout (line 338) | setTimeout (callback, delay, arg) {
method clearTimeout (line 351) | clearTimeout (timeout) {
method setFastTimeout (line 375) | setFastTimeout (callback, delay, arg) {
method clearFastTimeout (line 384) | clearFastTimeout (timeout) {
method now (line 392) | now () {
method tick (line 402) | tick (delay = 0) {
method reset (line 413) | reset () {
FILE: lib/web/cache/cache.js
class Cache (line 29) | class Cache {
method constructor (line 36) | constructor () {
method match (line 45) | async match (request, options = {}) {
method matchAll (line 63) | async matchAll (request = undefined, options = {}) {
method add (line 73) | async add (request) {
method addAll (line 91) | async addAll (requests) {
method put (line 261) | async put (request, response) {
method delete (line 392) | async delete (request, options = {}) {
method keys (line 458) | async keys (request = undefined, options = {}) {
method #batchCacheOperations (line 539) | #batchCacheOperations (operations) {
method #queryCache (line 677) | #queryCache (requestQuery, options, targetStorage) {
method #requestMatchesCachedItem (line 701) | #requestMatchesCachedItem (requestQuery, request, response = null, opt...
method #internalMatchAll (line 748) | #internalMatchAll (request, options, maxResponses = Infinity) {
FILE: lib/web/cache/cachestorage.js
class CacheStorage (line 8) | class CacheStorage {
method constructor (line 15) | constructor () {
method match (line 23) | async match (request, options = {}) {
method has (line 60) | async has (cacheName) {
method open (line 78) | async open (cacheName) {
method delete (line 112) | async delete (cacheName) {
method keys (line 127) | async keys () {
FILE: lib/web/cache/util.js
function urlEquals (line 14) | function urlEquals (A, B, excludeFragment = false) {
function getFieldValues (line 26) | function getFieldValues (header) {
FILE: lib/web/cookies/index.js
function getCookies (line 28) | function getCookies (headers) {
function deleteCookie (line 57) | function deleteCookie (headers, name, attributes) {
function getSetCookies (line 80) | function getSetCookies (headers) {
function parseCookie (line 98) | function parseCookie (cookie) {
function setCookie (line 109) | function setCookie (headers, cookie) {
FILE: lib/web/cookies/parse.js
function parseSetCookie (line 15) | function parseSetCookie (header) {
function parseUnparsedAttributes (line 95) | function parseUnparsedAttributes (unparsedAttributes, cookieAttributeLis...
FILE: lib/web/cookies/util.js
function isCTLExcludingHtab (line 7) | function isCTLExcludingHtab (value) {
function validateCookieName (line 31) | function validateCookieName (name) {
function validateCookieValue (line 69) | function validateCookieValue (value) {
function validateCookiePath (line 102) | function validateCookiePath (path) {
function validateCookieDomain (line 121) | function validateCookieDomain (domain) {
function toIMFDate (line 184) | function toIMFDate (date) {
function validateCookieMaxAge (line 199) | function validateCookieMaxAge (maxAge) {
function stringify (line 209) | function stringify (cookie) {
FILE: lib/web/eventsource/eventsource-stream.js
constant BOM (line 8) | const BOM = [0xEF, 0xBB, 0xBF]
constant COLON (line 20) | const COLON = 0x3A
constant SPACE (line 24) | const SPACE = 0x20
class EventSourceStream (line 43) | class EventSourceStream extends Transform {
method constructor (line 85) | constructor (options = {}) {
method _transform (line 104) | _transform (chunk, _encoding, callback) {
method parseLine (line 286) | parseLine (line, event) {
method processEvent (line 365) | processEvent (event) {
method clearEvent (line 387) | clearEvent () {
FILE: lib/web/eventsource/eventsource.js
constant CONNECTING (line 41) | const CONNECTING = 0
constant OPEN (line 48) | const OPEN = 1
constant CLOSED (line 54) | const CLOSED = 2
constant ANONYMOUS (line 60) | const ANONYMOUS = 'anonymous'
constant USE_CREDENTIALS (line 66) | const USE_CREDENTIALS = 'use-credentials'
class EventSource (line 76) | class EventSource extends EventTarget {
method constructor (line 107) | constructor (url, eventSourceInitDict = {}) {
method readyState (line 200) | get readyState () {
method url (line 209) | get url () {
method withCredentials (line 217) | get withCredentials () {
method #connect (line 221) | #connect () {
method #reconnect (line 322) | #reconnect () {
method close (line 367) | close () {
method onopen (line 376) | get onopen () {
method onopen (line 380) | set onopen (fn) {
method onmessage (line 395) | get onmessage () {
method onmessage (line 399) | set onmessage (fn) {
method onerror (line 414) | get onerror () {
method onerror (line 418) | set onerror (fn) {
FILE: lib/web/eventsource/util.js
function isValidLastEventId (line 8) | function isValidLastEventId (value) {
function isASCIINumber (line 18) | function isASCIINumber (value) {
FILE: lib/web/fetch/body.js
function noop (line 27) | function noop () {}
function extractBody (line 45) | function extractBody (object, keepalive = false) {
function safelyExtractBody (line 267) | function safelyExtractBody (object, keepalive = false) {
function cloneBody (line 282) | function cloneBody (body) {
function bodyMixinMethods (line 301) | function bodyMixinMethods (instance, getInternalState) {
function mixinBody (line 407) | function mixinBody (prototype, getInternalState) {
function consumeBody (line 418) | function consumeBody (object, convertBytesToJSValue, instance, getIntern...
function bodyUnusable (line 470) | function bodyUnusable (object) {
function bodyMimeType (line 483) | function bodyMimeType (requestOrResponse) {
FILE: lib/web/fetch/data-url.js
constant HTTP_TOKEN_CODEPOINTS (line 11) | const HTTP_TOKEN_CODEPOINTS = /^[-!#$%&'*+.^_|~A-Za-z0-9]+$/u
constant HTTP_WHITESPACE_REGEX (line 12) | const HTTP_WHITESPACE_REGEX = /[\u000A\u000D\u0009\u0020]/u
constant HTTP_QUOTED_STRING_TOKENS (line 17) | const HTTP_QUOTED_STRING_TOKENS = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/u
function dataURLProcessor (line 21) | function dataURLProcessor (dataURL) {
function URLSerializer (line 123) | function URLSerializer (url, excludeFragment = false) {
function stringPercentDecode (line 142) | function stringPercentDecode (input) {
function isHexCharByte (line 153) | function isHexCharByte (byte) {
function hexByteToNumber (line 161) | function hexByteToNumber (byte) {
function percentDecode (line 174) | function percentDecode (input) {
function parseMIMEType (line 219) | function parseMIMEType (input) {
function collectAnHTTPQuotedString (line 397) | function collectAnHTTPQuotedString (input, position, extractValue = fals...
function serializeAMimeType (line 472) | function serializeAMimeType (mimeType) {
function isHTTPWhiteSpace (line 517) | function isHTTPWhiteSpace (char) {
function removeHTTPWhitespace (line 528) | function removeHTTPWhitespace (str, leading = true, trailing = true) {
function minimizeSupportedMimeType (line 536) | function minimizeSupportedMimeType (mimeType) {
FILE: lib/web/fetch/formdata-parser.js
function isAsciiString (line 17) | function isAsciiString (chars) {
function validateBoundary (line 30) | function validateBoundary (boundary) {
function multipartFormDataParser (line 64) | function multipartFormDataParser (input, mimeType) {
function parseContentDispositionAttribute (line 209) | function parseContentDispositionAttribute (input, position) {
function parseMultipartFormDataHeaders (line 315) | function parseMultipartFormDataHeaders (input, position) {
function collectASequenceOfBytes (line 464) | function collectASequenceOfBytes (condition, input, position) {
function removeChars (line 481) | function removeChars (buf, leading, trailing, predicate) {
function bufferStartsWith (line 502) | function bufferStartsWith (buffer, start, position) {
function parsingError (line 516) | function parsingError (cause) {
function isCTL (line 525) | function isCTL (char) {
function isTSpecial (line 537) | function isTSpecial (char) {
function isToken (line 562) | function isToken (char) {
FILE: lib/web/fetch/formdata.js
class FormData (line 9) | class FormData {
method constructor (line 12) | constructor (form = undefined) {
method append (line 24) | append (name, value, filename = undefined) {
method delete (line 52) | delete (name) {
method get (line 65) | get (name) {
method getAll (line 85) | getAll (name) {
method has (line 102) | has (name) {
method set (line 115) | set (name, value, filename = undefined) {
method getFormDataState (line 184) | static getFormDataState (formData) {
method setFormDataState (line 192) | static setFormDataState (formData, newState) {
method [nodeUtil.inspect.custom] (line 157) | [nodeUtil.inspect.custom] (depth, options) {
function makeEntry (line 223) | function makeEntry (name, value, filename) {
FILE: lib/web/fetch/global.js
function getGlobalOrigin (line 7) | function getGlobalOrigin () {
function setGlobalOrigin (line 11) | function setGlobalOrigin (newOrigin) {
FILE: lib/web/fetch/headers.js
function isHTTPWhiteSpaceCharCode (line 20) | function isHTTPWhiteSpaceCharCode (code) {
function headerValueNormalize (line 29) | function headerValueNormalize (potentialValue) {
function fill (line 45) | function fill (headers, object) {
function appendHeader (line 88) | function appendHeader (headers, name, value) {
function headersListSortAndCombine (line 132) | function headersListSortAndCombine (target) {
function compareHeaderName (line 189) | function compareHeaderName (a, b) {
class HeadersList (line 193) | class HeadersList {
method constructor (line 200) | constructor (init) {
method contains (line 216) | contains (name, isLowerCase) {
method clear (line 224) | clear () {
method append (line 236) | append (name, value, isLowerCase) {
method set (line 266) | set (name, value, isLowerCase) {
method delete (line 286) | delete (name, isLowerCase) {
method get (line 303) | get (name, isLowerCase) {
method entries (line 318) | get entries () {
method rawValues (line 330) | rawValues () {
method entriesList (line 334) | get entriesList () {
method toSortedArray (line 353) | toSortedArray () {
method [Symbol.iterator] (line 311) | * [Symbol.iterator] () {
class Headers (line 427) | class Headers {
method constructor (line 438) | constructor (init = undefined) {
method append (line 460) | append (name, value) {
method delete (line 473) | delete (name) {
method get (line 517) | get (name) {
method has (line 540) | has (name) {
method set (line 563) | set (name, value) {
method getSetCookie (line 611) | getSetCookie () {
method getHeadersGuard (line 633) | static getHeadersGuard (o) {
method setHeadersGuard (line 637) | static setHeadersGuard (o, guard) {
method getHeadersList (line 644) | static getHeadersList (o) {
method setHeadersList (line 652) | static setHeadersList (target, list) {
method [util.inspect.custom] (line 627) | [util.inspect.custom] (depth, options) {
FILE: lib/web/fetch/index.js
constant GET_OR_HEAD (line 74) | const GET_OR_HEAD = ['GET', 'HEAD']
class Fetch (line 83) | class Fetch extends EE {
method constructor (line 84) | constructor (dispatcher) {
method terminate (line 93) | terminate (reason) {
method abort (line 104) | abort (error) {
function handleFetchDone (line 130) | function handleFetchDone (response) {
function fetch (line 135) | function fetch (input, init = undefined) {
function finalizeAndReportTiming (line 265) | function finalizeAndReportTiming (response, initiatorType = 'other') {
function abortFetch (line 333) | function abortFetch (p, request, responseObject, error, controller /* un...
function fetching (line 368) | function fetching ({
function mainFetch (line 525) | async function mainFetch (fetchParams, recursive) {
function schemeFetch (line 775) | function schemeFetch (fetchParams) {
function finalizeResponse (line 972) | function finalizeResponse (fetchParams, response) {
function fetchFinale (line 985) | function fetchFinale (fetchParams, response) {
function httpFetch (line 1111) | async function httpFetch (fetchParams) {
function httpRedirectFetch (line 1214) | function httpRedirectFetch (fetchParams, response) {
function httpNetworkOrCacheFetch (line 1358) | async function httpNetworkOrCacheFetch (
function httpNetworkFetch (line 1757) | async function httpNetworkFetch (
FILE: lib/web/fetch/request.js
function buildAbort (line 47) | function buildAbort (acRef) {
class Request (line 88) | class Request {
method constructor (line 101) | constructor (input, init = undefined) {
method method (line 584) | get method () {
method url (line 592) | get url () {
method headers (line 602) | get headers () {
method destination (line 611) | get destination () {
method referrer (line 623) | get referrer () {
method referrerPolicy (line 645) | get referrerPolicy () {
method mode (line 655) | get mode () {
method credentials (line 665) | get credentials () {
method cache (line 675) | get cache () {
method redirect (line 686) | get redirect () {
method integrity (line 696) | get integrity () {
method keepalive (line 706) | get keepalive () {
method isReloadNavigation (line 715) | get isReloadNavigation () {
method isHistoryNavigation (line 725) | get isHistoryNavigation () {
method signal (line 736) | get signal () {
method body (line 743) | get body () {
method bodyUsed (line 749) | get bodyUsed () {
method duplex (line 755) | get duplex () {
method clone (line 762) | clone () {
method setRequestSignal (line 829) | static setRequestSignal (request, newSignal) {
method getRequestDispatcher (line 837) | static getRequestDispatcher (request) {
method setRequestDispatcher (line 845) | static setRequestDispatcher (request, newDispatcher) {
method setRequestHeaders (line 853) | static setRequestHeaders (request, newHeaders) {
method getRequestState (line 860) | static getRequestState (request) {
method setRequestState (line 868) | static setRequestState (request, newState) {
method [nodeUtil.inspect.custom] (line 797) | [nodeUtil.inspect.custom] (depth, options) {
function makeRequest (line 884) | function makeRequest (init) {
function cloneRequest (line 932) | function cloneRequest (request) {
function fromInnerRequest (line 956) | function fromInnerRequest (innerRequest, dispatcher, signal, guard) {
FILE: lib/web/fetch/response.js
class Response (line 28) | class Response {
method error (line 35) | static error () {
method json (line 45) | static json (data, init = undefined) {
method redirect (line 72) | static redirect (url, status = 302) {
method constructor (line 112) | constructor (body = null, init = undefined) {
method type (line 149) | get type () {
method url (line 157) | get url () {
method redirected (line 175) | get redirected () {
method status (line 184) | get status () {
method ok (line 192) | get ok () {
method statusText (line 201) | get statusText () {
method headers (line 210) | get headers () {
method body (line 217) | get body () {
method bodyUsed (line 223) | get bodyUsed () {
method clone (line 230) | clone () {
method getResponseHeaders (line 280) | static getResponseHeaders (response) {
method setResponseHeaders (line 288) | static setResponseHeaders (response, newHeaders) {
method getResponseState (line 295) | static getResponseState (response) {
method setResponseState (line 303) | static setResponseState (response, newState) {
method [nodeUtil.inspect.custom] (line 255) | [nodeUtil.inspect.custom] (depth, options) {
function cloneResponse (line 340) | function cloneResponse (response) {
function makeResponse (line 366) | function makeResponse (init) {
function makeNetworkError (line 385) | function makeNetworkError (reason) {
function isNetworkError (line 398) | function isNetworkError (response) {
function makeFilteredResponse (line 407) | function makeFilteredResponse (response, state) {
function filterResponse (line 426) | function filterResponse (response, type) {
function makeAppropriateNetworkError (line 480) | function makeAppropriateNetworkError (fetchParams, err = null) {
function initializeResponse (line 492) | function initializeResponse (response, init, body) {
function fromInnerResponse (line 551) | function fromInnerResponse (innerResponse, guard) {
FILE: lib/web/fetch/util.js
function responseURL (line 15) | function responseURL (response) {
function responseLocationURL (line 25) | function responseLocationURL (response, requestFragment) {
function isValidEncodedURL (line 62) | function isValidEncodedURL (url) {
function normalizeBinaryStringToUtf8 (line 82) | function normalizeBinaryStringToUtf8 (value) {
function requestCurrentURL (line 87) | function requestCurrentURL (request) {
function requestBadPort (line 91) | function requestBadPort (request) {
function isErrorLike (line 105) | function isErrorLike (object) {
function isValidReasonPhrase (line 118) | function isValidReasonPhrase (statusText) {
function isValidHeaderValue (line 146) | function isValidHeaderValue (potentialValue) {
function parseReferrerPolicy (line 164) | function parseReferrerPolicy (actualResponse) {
function setRequestReferrerPolicyOnRedirect (line 201) | function setRequestReferrerPolicyOnRedirect (request, actualResponse) {
function crossOriginResourcePolicyCheck (line 213) | function crossOriginResourcePolicyCheck () {
function corsCheck (line 219) | function corsCheck () {
function TAOCheck (line 225) | function TAOCheck () {
function appendFetchMetadata (line 230) | function appendFetchMetadata (httpRequest) {
function appendRequestOriginHeader (line 256) | function appendRequestOriginHeader (request) {
function coarsenTime (line 311) | function coarsenTime (timestamp, crossOriginIsolatedCapability) {
function clampAndCoarsenConnectionTimingInfo (line 317) | function clampAndCoarsenConnectionTimingInfo (connectionTimingInfo, defa...
function coarsenedSharedCurrentTime (line 340) | function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) {
function createOpaqueTimingInfo (line 345) | function createOpaqueTimingInfo (timingInfo) {
function makePolicyContainer (line 362) | function makePolicyContainer () {
function clonePolicyContainer (line 370) | function clonePolicyContainer (policyContainer) {
function determineRequestsReferrer (line 381) | function determineRequestsReferrer (request) {
function stripURLForReferrer (line 524) | function stripURLForReferrer (url, originOnly = false) {
function isOriginIPPotentiallyTrustworthy (line 570) | function isOriginIPPotentiallyTrustworthy (origin) {
function isOriginPotentiallyTrustworthy (line 595) | function isOriginPotentiallyTrustworthy (origin) {
function isURLPotentiallyTrustworthy (line 656) | function isURLPotentiallyTrustworthy (url) {
function tryUpgradeRequestToAPotentiallyTrustworthyURL (line 683) | function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
function sameOrigin (line 692) | function sameOrigin (A, B) {
function isAborted (line 708) | function isAborted (fetchParams) {
function isCancelled (line 712) | function isCancelled (fetchParams) {
function normalizeMethod (line 721) | function normalizeMethod (method) {
function createIterator (line 735) | function createIterator (name, kInternalIterator, keyIndex = 0, valueInd...
function iteratorMixin (line 871) | function iteratorMixin (name, object, kInternalIterator, keyIndex = 0, v...
function fullyReadBody (line 940) | function fullyReadBody (body, processBody, processBodyError) {
function readableStreamClose (line 968) | function readableStreamClose (controller) {
function readAllBytes (line 988) | async function readAllBytes (reader, successSteps, failureSteps) {
function urlIsLocal (line 1026) | function urlIsLocal (url) {
function urlHasHttpsScheme (line 1040) | function urlHasHttpsScheme (url) {
function urlIsHttpHttpsScheme (line 1059) | function urlIsHttpHttpsScheme (url) {
function simpleRangeHeaderValue (line 1079) | function simpleRangeHeaderValue (value, allowWhitespace) {
function buildContentRange (line 1212) | function buildContentRange (rangeStart, rangeEnd, fullLength) {
class InflateStream (line 1240) | class InflateStream extends Transform {
method constructor (line 1244) | constructor (zlibOptions) {
method _transform (line 1249) | _transform (chunk, encoding, callback) {
method _final (line 1267) | _final (callback) {
function createInflate (line 1280) | function createInflate (zlibOptions) {
function extractMimeType (line 1288) | function extractMimeType (headers) {
function gettingDecodingSplitting (line 1352) | function gettingDecodingSplitting (value) {
function getDecodeSplit (line 1419) | function getDecodeSplit (name, list) {
function hasAuthenticationEntry (line 1432) | function hasAuthenticationEntry (request) {
function includesCredentials (line 1440) | function includesCredentials (url) {
function isTraversableNavigable (line 1449) | function isTraversableNavigable (navigable) {
class EnvironmentSettingsObjectBase (line 1454) | class EnvironmentSettingsObjectBase {
method baseUrl (line 1455) | get baseUrl () {
method origin (line 1459) | get origin () {
class EnvironmentSettingsObject (line 1466) | class EnvironmentSettingsObject {
FILE: lib/web/infra/index.js
function collectASequenceOfCodePoints (line 14) | function collectASequenceOfCodePoints (condition, input, position) {
function collectASequenceOfCodePointsFast (line 41) | function collectASequenceOfCodePointsFast (char, input, position) {
constant ASCII_WHITESPACE_REPLACE_REGEX (line 54) | const ASCII_WHITESPACE_REPLACE_REGEX = /[\u0009\u000A\u000C\u000D\u0020]/g
function forgivingBase64 (line 62) | function forgivingBase64 (data) {
function isASCIIWhitespace (line 105) | function isASCIIWhitespace (char) {
function isomorphicDecode (line 121) | function isomorphicDecode (input) {
function isomorphicEncode (line 149) | function isomorphicEncode (input) {
function parseJSONFromBytes (line 163) | function parseJSONFromBytes (bytes) {
function removeASCIIWhitespace (line 175) | function removeASCIIWhitespace (str, leading = true, trailing = true) {
function removeChars (line 186) | function removeChars (str, leading, trailing, predicate) {
function serializeJavascriptValueToJSONString (line 202) | function serializeJavascriptValueToJSONString (value) {
FILE: lib/web/subresource-integrity/subresource-integrity.js
function getStrongestMetadata (line 132) | function getStrongestMetadata (metadataList) {
function parseMetadata (line 196) | function parseMetadata (metadata) {
function caseSensitiveMatch (line 264) | function caseSensitiveMatch (actualValue, expectedValue) {
FILE: lib/web/webidl/index.js
constant UNDEFINED (line 7) | const UNDEFINED = 1
constant BOOLEAN (line 8) | const BOOLEAN = 2
constant STRING (line 9) | const STRING = 3
constant SYMBOL (line 10) | const SYMBOL = 4
constant NUMBER (line 11) | const NUMBER = 5
constant BIGINT (line 12) | const BIGINT = 6
constant NULL (line 13) | const NULL = 7
constant OBJECT (line 14) | const OBJECT = 8 // function and object
FILE: lib/web/websocket/connection.js
function establishWebSocketConnection (line 26) | function establishWebSocketConnection (url, protocols, client, handler, ...
function closeWebSocketConnection (line 227) | function closeWebSocketConnection (object, code, reason, validate = fals...
function failWebsocketConnection (line 306) | function failWebsocketConnection (handler, code, reason, cause) {
FILE: lib/web/websocket/events.js
class MessageEvent (line 10) | class MessageEvent extends Event {
method constructor (line 13) | constructor (type, eventInitDict = {}) {
method data (line 32) | get data () {
method origin (line 38) | get origin () {
method lastEventId (line 44) | get lastEventId () {
method source (line 50) | get source () {
method ports (line 56) | get ports () {
method initMessageEvent (line 66) | initMessageEvent (
method createFastMessageEvent (line 85) | static createFastMessageEvent (type, init) {
class CloseEvent (line 103) | class CloseEvent extends Event {
method constructor (line 106) | constructor (type, eventInitDict = {}) {
method wasClean (line 119) | get wasClean () {
method code (line 125) | get code () {
method reason (line 131) | get reason () {
class ErrorEvent (line 139) | class ErrorEvent extends Event {
method constructor (line 142) | constructor (type, eventInitDict) {
method message (line 155) | get message () {
method filename (line 161) | get filename () {
method lineno (line 167) | get lineno () {
method colno (line 173) | get colno () {
method error (line 179) | get error () {
FILE: lib/web/websocket/frame.js
constant BUFFER_SIZE (line 6) | const BUFFER_SIZE = 8 * 1024
function generateMask (line 21) | function generateMask () {
class WebsocketFrameSend (line 29) | class WebsocketFrameSend {
method constructor (line 33) | constructor (data) {
method createFrame (line 37) | createFrame (opcode) {
method createFastTextFrame (line 90) | static createFastTextFrame (buffer) {
FILE: lib/web/websocket/permessage-deflate.js
class PerMessageDeflate (line 14) | class PerMessageDeflate {
method constructor (line 29) | constructor (extensions) {
method decompress (line 34) | decompress (chunk, fin, callback) {
FILE: lib/web/websocket/receiver.js
class ByteParser (line 25) | class ByteParser extends Writable {
method constructor (line 46) | constructor (handler, extensions) {
method _write (line 61) | _write (chunk, _, callback) {
method run (line 74) | run (callback) {
method consume (line 264) | consume (n) {
method writeFragments (line 307) | writeFragments (fragment) {
method consumeFragments (line 312) | consumeFragments () {
method parseCloseBody (line 337) | parseCloseBody (data) {
method parseControlFrame (line 377) | parseControlFrame (body) {
method closingInfo (line 443) | get closingInfo () {
FILE: lib/web/websocket/sender.js
class SendQueue (line 14) | class SendQueue {
method constructor (line 28) | constructor (socket) {
method add (line 32) | add (item, cb, hint) {
method #run (line 76) | async #run () {
function createFrame (line 94) | function createFrame (data, hint) {
function toBuffer (line 98) | function toBuffer (data, hint) {
FILE: lib/web/websocket/stream/websocketerror.js
function createInheritableDOMException (line 8) | function createInheritableDOMException () {
class WebSocketError (line 29) | class WebSocketError extends createInheritableDOMException() {
method constructor (line 33) | constructor (message = '', init = undefined) {
method closeCode (line 67) | get closeCode () {
method reason (line 71) | get reason () {
method createUnvalidatedWebSocketError (line 80) | static createUnvalidatedWebSocketError (message, code, reason) {
FILE: lib/web/websocket/stream/websocketstream.js
class WebSocketStream (line 18) | class WebSocketStream {
method constructor (line 79) | constructor (url, options = undefined) {
method url (line 170) | get url () {
method opened (line 175) | get opened () {
method closed (line 180) | get closed () {
method close (line 185) | close (closeInfo = undefined) {
method #write (line 200) | #write (chunk) {
method #onConnectionEstablished (line 258) | #onConnectionEstablished (response, parsedExtensions) {
method #onMessage (line 323) | #onMessage (type, data) {
method #onSocketClose (line 355) | #onSocketClose () {
method #closeUsingReason (line 424) | #closeUsingReason (reason) {
method #cancel (line 446) | #cancel (reason) {
FILE: lib/web/websocket/util.js
function isConnecting (line 12) | function isConnecting (readyState) {
function isEstablished (line 22) | function isEstablished (readyState) {
function isClosing (line 33) | function isClosing (readyState) {
function isClosed (line 44) | function isClosed (readyState) {
function fireEvent (line 56) | function fireEvent (e, target, eventFactory = (type, init) => new Event(...
function websocketMessageReceived (line 79) | function websocketMessageReceived (handler, type, data) {
function toArrayBuffer (line 87) | function toArrayBuffer (buffer) {
function isValidSubprotocol (line 101) | function isValidSubprotocol (protocol) {
function isValidStatusCode (line 148) | function isValidStatusCode (code) {
function isControlFrame (line 165) | function isControlFrame (opcode) {
function isContinuationFrame (line 177) | function isContinuationFrame (opcode) {
function isTextBinaryFrame (line 185) | function isTextBinaryFrame (opcode) {
function isValidOpcode (line 194) | function isValidOpcode (opcode) {
function parseExtensions (line 204) | function parseExtensions (extensions) {
function isValidClientWindowBits (line 229) | function isValidClientWindowBits (value) {
function getURLRecord (line 254) | function getURLRecord (url, baseURL) {
function validateCloseCodeAndReason (line 288) | function validateCloseCodeAndReason (code, reason) {
FILE: lib/web/websocket/websocket.js
class WebSocket (line 48) | class WebSocket extends EventTarget {
method constructor (line 117) | constructor (url, protocols = []) {
method close (line 190) | close (code = undefined, reason = undefined) {
method send (line 217) | send (data) {
method readyState (line 311) | get readyState () {
method bufferedAmount (line 318) | get bufferedAmount () {
method url (line 324) | get url () {
method extensions (line 331) | get extensions () {
method protocol (line 337) | get protocol () {
method onopen (line 343) | get onopen () {
method onopen (line 349) | set onopen (fn) {
method onerror (line 366) | get onerror () {
method onerror (line 372) | set onerror (fn) {
method onclose (line 389) | get onclose () {
method onclose (line 395) | set onclose (fn) {
method onmessage (line 412) | get onmessage () {
method onmessage (line 418) | set onmessage (fn) {
method binaryType (line 435) | get binaryType () {
method binaryType (line 441) | set binaryType (type) {
method #onConnectionEstablished (line 454) | #onConnectionEstablished (response, parsedExtensions) {
method #onMessage (line 507) | #onMessage (type, data) {
method #onParserDrain (line 548) | #onParserDrain () {
method #onSocketClose (line 556) | #onSocketClose () {
method ping (line 620) | static ping (ws, buffer) {
FILE: test/autobahn/client.js
function nextTest (line 12) | function nextTest () {
FILE: test/autobahn/report.js
function testCaseIdToWeight (line 19) | function testCaseIdToWeight (testCaseId) {
function isFailedTestCase (line 26) | function isFailedTestCase (testCase) {
FILE: test/busboy/formdata-test.js
function makeResponse (line 91) | function makeResponse (body, bnd) {
FILE: test/busboy/test-parser.js
function b64decode (line 28) | function b64decode (input) {
function makeResponse (line 32) | function makeResponse (body, bnd) {
FILE: test/cache-interceptor/cache-store-test-utils.js
function cacheStoreTests (line 16) | function cacheStoreTests (CacheStore, options) {
function writeBody (line 357) | function writeBody (stream, body) {
function readBody (line 370) | async function readBody ({ body }) {
function joinBufferArray (line 403) | function joinBufferArray (buffers) {
function compareGetResults (line 420) | async function compareGetResults (actual, expected, expectedBody) {
FILE: test/cache-interceptor/cache-tests-worker.mjs
function makeCacheStore (line 71) | async function makeCacheStore (type) {
function printResults (line 94) | function printResults (environment, results) {
function printStats (line 196) | function printStats (stats) {
FILE: test/cache-interceptor/cache-tests.mjs
constant CLI_OPTIONS (line 32) | const CLI_OPTIONS = parseArgs({
constant BASE_TEST_ENVIRONMENT (line 56) | const BASE_TEST_ENVIRONMENT = {
constant CACHE_TYPES (line 90) | const CACHE_TYPES = [
constant CACHE_STORES (line 106) | const CACHE_STORES = [
constant PROTOCOL (line 116) | const PROTOCOL = 'http'
constant PORT (line 117) | const PORT = 8000
function buildTestEnvironments (line 190) | function buildTestEnvironments (idx, testOptions) {
function joinEnvironments (line 227) | function joinEnvironments (base, sub) {
function filterEnvironments (line 247) | function filterEnvironments (environments) {
FILE: test/client-pipeline.js
method read (line 92) | read () {
method write (line 105) | write (chunk, encoding, callback) {
method final (line 109) | final (callback) {
method read (line 143) | read () {
method write (line 156) | write (chunk, encoding, callback) {
method final (line 160) | final (callback) {
method read (line 236) | read () {
method read (line 278) | read () {
method transform (line 863) | transform (chunk, encoding, callback) {
method transform (line 1051) | transform (chunk, encoding, callback) {
FILE: test/client-pipelining.js
function onWarning (line 29) | function onWarning (warning) {
function makeRequest (line 54) | function makeRequest (i) {
function makeRequestAndExpectUrl (line 68) | function makeRequestAndExpectUrl (client, i, t, cb) {
function makeRequest (line 125) | function makeRequest () {
method read (line 237) | read () {
method read (line 258) | read () {
function errordInflightPost (line 345) | function errordInflightPost (bodyType) {
function pipeliningNonIdempotentWithBody (line 455) | function pipeliningNonIdempotentWithBody (bodyType) {
function pipeliningHeadBusy (line 523) | function pipeliningHeadBusy (bodyType) {
function pipeliningIdempotentBusy (line 658) | function pipeliningIdempotentBusy (bodyType) {
FILE: test/client-request.js
method read (line 333) | read () { }
method read (line 885) | read () {
method read (line 919) | read () {
FILE: test/client-stream.js
method write (line 654) | write (chunk, encoding, callback) {
method write (line 694) | write (chunk, encoding, callback) {
method write (line 735) | write (chunk, encoding, callback) {
method read (line 760) | read () { }
method get (line 800) | get () {
method get (line 861) | get () {
FILE: test/client-timeout.js
method onConnect (line 29) | onConnect () {
method onHeaders (line 31) | onHeaders (statusCode, headers, resume) {
method onData (line 37) | onData () {
method onComplete (line 40) | onComplete () {
method onError (line 43) | onError (err) {
method read (line 75) | read () {}
method onConnect (line 81) | onConnect () {
method onHeaders (line 92) | onHeaders (statusCode, headers, resume) {
method onData (line 94) | onData () {
method onComplete (line 97) | onComplete () {
method onError (line 100) | onError (err) {
method onConnect (line 144) | onConnect () {
method onHeaders (line 152) | onHeaders (statusCode, headers, resume) {
method onData (line 154) | onData () {
method onComplete (line 157) | onComplete () {
method onError (line 160) | onError (err) {
method onConnect (line 193) | onConnect () {
method onHeaders (line 195) | onHeaders (statusCode, headers, resume) {
method onData (line 199) | onData () {
method onComplete (line 202) | onComplete () {
method onError (line 205) | onError (err) {
FILE: test/client-write-max-listeners.js
method read (line 22) | read () {
function onWarning (line 35) | function onWarning (warning) {
FILE: test/client.js
method connect (line 101) | connect (opts, cb) {
function postServer (line 592) | function postServer (t, expected) {
method read (line 997) | read () { }
method read (line 1036) | read () {
method destroy (line 1038) | destroy (err, callback) {
function makeRequest (line 1083) | function makeRequest (i) {
function makeRequest (line 1118) | function makeRequest (i) {
method read (line 1315) | read () {
method read (line 1368) | read () {
method read (line 1582) | read () {
method read (line 1709) | read () {
function buildParams (line 2055) | function buildParams (path) {
FILE: test/close-and-destroy.js
function onRequest (line 39) | function onRequest (err, { statusCode, headers, body }) {
function makeRequest (line 146) | function makeRequest () {
function makeRequest (line 180) | function makeRequest () {
function makeRequest (line 214) | function makeRequest () {
function makeRequest (line 292) | function makeRequest () {
function makeRequest (line 328) | function makeRequest () {
function makeRequest (line 359) | function makeRequest () {
FILE: test/connect-abort.js
method destroy (line 15) | destroy (err, cb) {
FILE: test/content-length.js
function invalidContentLength (line 102) | function invalidContentLength (bodyType) {
function zeroContentLength (line 164) | function zeroContentLength (bodyType) {
method read (line 336) | read () {
method read (line 427) | read () {
method read (line 443) | read () {
method read (line 459) | read () {
FILE: test/cookie/cookies.js
class Headers (line 604) | class Headers {
class Headers (line 645) | class Headers {
class Headers (line 668) | class Headers {
class Headers (line 691) | class Headers {
FILE: test/cookie/global-headers.js
class Headers (line 58) | class Headers { }
FILE: test/decorator-handler.js
method constructor (line 32) | constructor (handler) {
method onConnect (line 36) | onConnect (abort, context) {
method onHeaders (line 40) | onHeaders (statusCode, rawHeaders, resume, statusMessage) {
method onUpgrade (line 44) | onUpgrade (statusCode, rawHeaders, socket) {
method onData (line 48) | onData (data) {
method onComplete (line 52) | onComplete (trailers) {
method onError (line 56) | onError (err) {
method constructor (line 62) | constructor (controller) {
method abort (line 66) | abort (reason) {
method resume (line 70) | resume () {
method pause (line 74) | pause () {
method constructor (line 217) | constructor (handler) {
method onRequestStart (line 221) | onRequestStart (controller, context) {
method onRequestUpgrade (line 225) | onRequestUpgrade (controller, statusCode, headers, socket) {
method onResponseStart (line 229) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseData (line 233) | onResponseData (controller, data) {
method onResponseEnd (line 237) | onResponseEnd (controller, trailers) {
method onResponseError (line 241) | onResponseError (controller, err) {
method constructor (line 247) | constructor (controller) {
method abort (line 251) | abort (reason) {
method resume (line 255) | resume () {
method pause (line 259) | pause () {
FILE: test/dispatcher.js
class PoorImplementation (line 8) | class PoorImplementation extends Dispatcher {}
FILE: test/eventsource/eventsource-attributes.js
function fn (line 40) | function fn () {
function fn2 (line 47) | function fn2 () { }
FILE: test/eventsource/eventsource-custom-dispatcher.js
class CustomHeaderAgent (line 23) | class CustomHeaderAgent extends Agent {
method dispatch (line 24) | dispatch (opts) {
method dispatch (line 57) | dispatch (opts) {
class CustomHeaderAgent (line 56) | class CustomHeaderAgent extends Agent {
method dispatch (line 24) | dispatch (opts) {
method dispatch (line 57) | dispatch (opts) {
FILE: test/fetch/abort2.js
function makeRequest (line 27) | async function makeRequest () {
FILE: test/fetch/client-fetch.js
method cancel (line 120) | async cancel (reason) {
method start (line 142) | async start (c) {
method cancel (line 146) | async cancel (reason) {
FILE: test/fetch/fire-and-forget.js
method start (line 56) | start () {}
method pull (line 58) | pull (ctrl) {
method cancel (line 62) | cancel () {
FILE: test/fetch/formdata.js
class FormData (line 272) | class FormData {
method constructor (line 273) | constructor () {
method append (line 277) | append (key, value) {
method get (line 281) | get (key) {
method constructor (line 317) | constructor () {
method append (line 325) | append () {}
method delete (line 326) | delete () {}
method get (line 327) | get () {}
method getAll (line 328) | getAll () {}
method has (line 329) | has () {}
method set (line 330) | set () {}
method entries (line 331) | entries () {}
method keys (line 332) | keys () {}
method values (line 333) | values () {}
method forEach (line 334) | forEach () {}
function FormData (line 291) | function FormData () {
method constructor (line 273) | constructor () {
method append (line 277) | append (key, value) {
method get (line 281) | get (key) {
method constructor (line 317) | constructor () {
method append (line 325) | append () {}
method delete (line 326) | delete () {}
method get (line 327) | get () {}
method getAll (line 328) | getAll () {}
method has (line 329) | has () {}
method set (line 330) | set () {}
method entries (line 331) | entries () {}
method keys (line 332) | keys () {}
method values (line 333) | values () {}
method forEach (line 334) | forEach () {}
class FormData (line 316) | class FormData {
method constructor (line 273) | constructor () {
method append (line 277) | append (key, value) {
method get (line 281) | get (key) {
method constructor (line 317) | constructor () {
method append (line 325) | append () {}
method delete (line 326) | delete () {}
method get (line 327) | get () {}
method getAll (line 328) | getAll () {}
method has (line 329) | has () {}
method set (line 330) | set () {}
method entries (line 331) | entries () {}
method keys (line 332) | keys () {}
method values (line 333) | values () {}
method forEach (line 334) | forEach () {}
method [Symbol.toStringTag] (line 321) | get [Symbol.toStringTag] () {
FILE: test/fetch/headers.js
method get (line 746) | get () {
FILE: test/fetch/headerslist-sortedarray.js
function generateAsciiString (line 9) | function generateAsciiString (length) {
constant SORT_RUN (line 17) | const SORT_RUN = 4000
FILE: test/fetch/issue-1447.js
method body (line 25) | body (bodyString) {
FILE: test/fetch/issue-2828.js
class CustomAgent (line 11) | class CustomAgent extends Agent {
method dispatch (line 12) | dispatch (options, handler) {
FILE: test/fetch/issue-2898-comment.js
class CustomAgentA (line 11) | class CustomAgentA extends Agent {
method dispatch (line 12) | dispatch (options, handler) {
class CustomAgentB (line 18) | class CustomAgentB extends Agent {
method dispatch (line 19) | dispatch (options, handler) {
FILE: test/fetch/issue-4897.js
function createAssertingDispatcher (line 6) | function createAssertingDispatcher (t, expectedPath) {
function assertPath (line 16) | async function assertPath (t, url, expectedPath) {
FILE: test/fetch/issue-node-46525.js
function onWarning (line 10) | function onWarning () {
FILE: test/fetch/long-lived-abort-controller.js
function onWarning (line 20) | function onWarning (warning) {
FILE: test/fetch/pull-dont-push.js
method read (line 22) | read () {
FILE: test/fetch/readable-stream-from.js
method [Symbol.asyncIterator] (line 9) | async * [Symbol.asyncIterator] () {
method [Symbol.asyncIterator] (line 22) | async * [Symbol.asyncIterator] () {
FILE: test/fetch/request.js
method blob (line 174) | blob () {
FILE: test/fetch/response-json.js
constant APPLICATION_JSON (line 8) | const APPLICATION_JSON = 'application/json'
constant FOO_BAR (line 9) | const FOO_BAR = 'foo/bar'
constant INIT_TESTS (line 11) | const INIT_TESTS = [
class CustomError (line 69) | class CustomError extends Error {
method foo (line 74) | get foo () { throw new CustomError('bar') }
FILE: test/fetch/response.js
method blob (line 99) | blob () {
method [Symbol.asyncIterator] (line 128) | async * [Symbol.asyncIterator] () {
method start (line 170) | start (controller) {
method start (line 188) | start (controller) {
method start (line 202) | start (controller) {
method start (line 215) | start (controller) {
FILE: test/fixtures/socks5-test-server.js
class TestSocks5Server (line 10) | class TestSocks5Server {
method constructor (line 11) | constructor (options = {}) {
method listen (line 19) | async listen (port = 0) {
method handleConnection (line 40) | handleConnection (socket) {
method handleHandshake (line 78) | handleHandshake (socket, buffer, callback) {
method handleAuth (line 102) | handleAuth (socket, buffer, callback) {
method handleConnect (line 129) | handleConnect (socket, buffer, callback) {
method close (line 213) | async close () {
FILE: test/fuzzing/client/client-fuzz-body.js
function fuzz (line 9) | async function fuzz (address, results, buf) {
FILE: test/fuzzing/client/client-fuzz-headers.js
function fuzz (line 9) | async function fuzz (address, results, buf) {
FILE: test/fuzzing/client/client-fuzz-options.js
function fuzz (line 13) | async function fuzz (address, results, buf) {
FILE: test/fuzzing/server/server-fuzz-append-data.js
function appendData (line 3) | function appendData (socket, data) {
FILE: test/fuzzing/server/server-fuzz-split-data.js
function splitData (line 3) | function splitData (socket, data) {
FILE: test/get-head-body.js
method read (line 38) | read () {}
method read (line 53) | read () {
method read (line 66) | read () {
method read (line 89) | read () {
method read (line 102) | read () {
FILE: test/http-req-destroy.js
function doNotKillReqSocket (line 10) | function doNotKillReqSocket (bodyType) {
FILE: test/http2-body.js
method onConnect (line 114) | onConnect () {
method onError (line 117) | onError (err) {
method onHeaders (line 120) | onHeaders (statusCode, headers) {
method onData (line 130) | onData (chunk) {
method onBodySent (line 133) | onBodySent (body) {
method onComplete (line 136) | onComplete () {
FILE: test/http2-dispatcher.js
method write (line 54) | write (chunk, _encoding, cb) {
method read (line 103) | read () {
method write (line 118) | write (chunk, _, cb) {
method onConnect (line 514) | onConnect () {
method onHeaders (line 517) | onHeaders () {
method onData (line 520) | onData () {
method onComplete (line 523) | onComplete (trailers) {
method onError (line 526) | onError (err) {
method onConnect (line 591) | onConnect () {
method onHeaders (line 594) | onHeaders () {
method onData (line 597) | onData () {
method onComplete (line 600) | onComplete (trailers) {
method onError (line 603) | onError (err) {
method onConnect (line 669) | onConnect () {
method onHeaders (line 672) | onHeaders () {
method onData (line 675) | onData () {
method onComplete (line 678) | onComplete (trailers) {
method onError (line 681) | onError (err) {
FILE: test/http2-late-data.js
class FakeSocket (line 32) | class FakeSocket extends EventEmitter {
method constructor (line 33) | constructor () {
method destroy (line 38) | destroy () {
method ref (line 43) | ref () {}
method unref (line 44) | unref () {}
class FakeStream (line 47) | class FakeStream extends EventEmitter {
method setTimeout (line 48) | setTimeout () {}
method pause (line 49) | pause () {}
method resume (line 50) | resume () {}
method close (line 51) | close () {}
method write (line 52) | write () { return true }
method end (line 53) | end () {}
method cork (line 54) | cork () {}
method uncork (line 55) | uncork () {}
class FakeSession (line 58) | class FakeSession extends EventEmitter {
method constructor (line 59) | constructor (stream) {
method request (line 66) | request () {
method close (line 70) | close () {
method destroy (line 74) | destroy () {
method ref (line 78) | ref () {}
method unref (line 79) | unref () {}
method ping (line 80) | ping (_, cb) {
method [kOnError] (line 113) | [kOnError] (err) {
method [kResume] (line 116) | [kResume] () {
method emit (line 119) | emit () {}
method onConnect (line 130) | onConnect () {}
method onHeaders (line 131) | onHeaders () {
method onData (line 134) | onData () {
method onComplete (line 138) | onComplete (trailers) {
method onError (line 142) | onError (err) {
FILE: test/http2-trailers.js
method onConnect (line 52) | onConnect () {
method onHeaders (line 55) | onHeaders () {
method onData (line 58) | onData () {
method onComplete (line 61) | onComplete (trailers) {
method onError (line 64) | onError (err) {
FILE: test/http2-window-size.js
class FakeSession (line 27) | class FakeSession extends EventEmitter {
method unref (line 28) | unref () {}
method ref (line 29) | ref () {}
method close (line 30) | close () {}
method destroy (line 31) | destroy () {}
method request (line 32) | request () {
method setLocalWindowSize (line 36) | setLocalWindowSize (size) {
class FakeSocket (line 41) | class FakeSocket extends EventEmitter {
method constructor (line 42) | constructor () {
method unref (line 47) | unref () {}
method ref (line 48) | ref () {}
method destroy (line 49) | destroy () {
FILE: test/imports/undici-import.ts
function exampleCode (line 4) | async function exampleCode () {
FILE: test/install.js
method set (line 14) | set (target, prop, value) {
FILE: test/interceptors/cache-async-store.js
class AsyncCacheStore (line 18) | class AsyncCacheStore {
method constructor (line 21) | constructor () {
method get (line 25) | async get (key) {
method createWriteStream (line 41) | createWriteStream (key, value) {
method delete (line 45) | delete (key) {
FILE: test/interceptors/cache-revalidate-stale.js
function isStale (line 73) | function isStale (res) {
function revalidateTest (line 77) | async function revalidateTest (useEtag = false) {
FILE: test/interceptors/cache.js
method get (line 544) | get () {
method createWriteStream (line 547) | createWriteStream (key) {
method delete (line 550) | delete () { }
FILE: test/interceptors/decompress.js
method onRequestStart (line 779) | onRequestStart (ctrl) {
method onResponseStart (line 783) | onResponseStart (ctrl, statusCode, headers, statusMessage) {
method onResponseData (line 793) | onResponseData (ctrl, chunk) {
method onResponseEnd (line 797) | onResponseEnd (ctrl, trailers) {
method onResponseError (line 802) | onResponseError (ctrl, err) {
method onRequestStart (line 851) | onRequestStart (ctrl) {
method onResponseStart (line 855) | onResponseStart (ctrl, statusCode, headers, statusMessage) {
method onResponseData (line 867) | onResponseData (ctrl, chunk) {
method onResponseEnd (line 871) | onResponseEnd (ctrl, trailers) {
method onResponseError (line 876) | onResponseError (ctrl, err) {
constant MAX_CONTENT_ENCODINGS (line 948) | const MAX_CONTENT_ENCODINGS = 5
FILE: test/interceptors/deduplicate.js
method onConnect (line 1251) | onConnect () {}
method onHeaders (line 1252) | onHeaders () {}
method onData (line 1253) | onData () {
method onComplete (line 1257) | onComplete () {
method onError (line 1260) | onError (err) {
FILE: test/interceptors/dns.js
method lookup (line 968) | lookup (origin, opts, cb) {
method lookup (line 1052) | lookup (origin, opts, cb) {
method lookup (line 1149) | lookup (origin, opts, cb) {
method lookup (line 1240) | lookup (origin, opts, cb) {
method lookup (line 1337) | lookup (origin, opts, cb) {
method lookup (line 1439) | lookup (origin, opts, cb) {
method lookup (line 1519) | lookup (origin, opts, cb) {
method lookup (line 1587) | lookup (origin, opts, cb) {
method get (line 1762) | get (origin) {
method set (line 1765) | set (origin, records) {
method delete (line 1768) | delete (origin) {
method full (line 1772) | full () {
method lookup (line 1918) | lookup (origin, opts, cb) {
FILE: test/issue-1757.js
class MiniflareDispatcher (line 7) | class MiniflareDispatcher extends Dispatcher {
method constructor (line 8) | constructor (inner, options) {
method dispatch (line 13) | dispatch (options, handler) {
method close (line 17) | close (...args) {
method destroy (line 21) | destroy (...args) {
FILE: test/issue-2349.js
method write (line 35) | write (chunk, _encoding, callback) {
FILE: test/issue-3959.js
function runCacheTest (line 10) | async function runCacheTest (store) {
FILE: test/issue-4880.js
function startServer (line 62) | function startServer () {
function makeDispatcher (line 69) | function makeDispatcher (connections, maxConcurrentStreams) {
FILE: test/jest/issue-1757.test.js
class MiniflareDispatcher (line 7) | class MiniflareDispatcher extends Dispatcher {
method constructor (line 8) | constructor (inner, options) {
method dispatch (line 13) | dispatch (options, handler) {
method close (line 17) | close (...args) {
method destroy (line 21) | destroy (...args) {
FILE: test/jest/parser-timeout.test.js
class DummySocket (line 10) | class DummySocket extends EventEmitter {
method constructor (line 11) | constructor () {
method read (line 17) | read () {
FILE: test/mock-agent.js
method headers (line 2639) | headers (headers) {
function sleep (line 2697) | function sleep (delay) {
function intercept (line 2704) | function intercept () {
class MiniflareDispatcher (line 2827) | class MiniflareDispatcher extends Dispatcher {
method constructor (line 2828) | constructor (inner, options) {
method dispatch (line 2833) | dispatch (options, handler) {
method close (line 2837) | close (...args) {
method destroy (line 2841) | destroy (...args) {
method start (line 2882) | start (controller) {
method start (line 2956) | start (controller) {
FILE: test/mock-call-history-log.js
function assertConsistent (line 8) | function assertConsistent (t, mockCallHistoryLog) {
FILE: test/mock-delayed-abort.js
class TestDecoratorHandler (line 84) | class TestDecoratorHandler extends DecoratorHandler {
method onResponseStart (line 87) | onResponseStart (controller, statusCode, headers, statusMessage) {
method onResponseError (line 94) | onResponseError (controller, err) {
FILE: test/mock-interceptor-unused-assertions.js
function mockAgentWithOneInterceptor (line 35) | function mockAgentWithOneInterceptor () {
FILE: test/no-strict-content-length.js
function assertEmitWarningCalledAndReset (line 19) | function assertEmitWarningCalledAndReset () {
method read (line 120) | read () {
method read (line 136) | read () {
method read (line 179) | read () {
method read (line 225) | read () {
method read (line 271) | read () {
method read (line 317) | read () {
method read (line 363) | read () {
method read (line 408) | read () {
FILE: test/node-fetch/main.js
class CustomSearchParameters (line 1265) | class CustomSearchParameters extends URLSearchParams { }
FILE: test/node-fetch/mock.js
method headers (line 95) | headers (headers) {
FILE: test/node-fetch/utils/server.js
method constructor (line 9) | constructor () {
method start (line 22) | async start () {
method stop (line 27) | async stop () {
method port (line 32) | get port () {
method hostname (line 36) | get hostname () {
method mockState (line 40) | mockState (responseHandler) {
method router (line 45) | router (request, res) {
FILE: test/node-test/abort-controller.js
function waitingWithBody (line 161) | function waitingWithBody (body, type) {
function writeHeadersStartedWithBody (line 190) | function writeHeadersStartedWithBody (body, type) {
function writeBodyStartedWithBody (line 220) | function writeBodyStartedWithBody (body, type) {
FILE: test/node-test/abort-event-emitter.js
method read (line 43) | read () { }
method read (line 92) | read () { }
function waitingWithBody (line 182) | function waitingWithBody (body, type) {
function writeHeadersStartedWithBody (line 211) | function writeHeadersStartedWithBody (body, type) {
function writeBodyStartedWithBody (line 241) | function writeBodyStartedWithBody (body, type) {
FILE: test/node-test/agent.js
method onConnect (line 321) | onConnect () {}
method onHeaders (line 322) | onHeaders () {}
method onData (line 323) | onData () {}
method onComplete (line 324) | onComplete () {
method onError (line 327) | onError (err) {
method onConnect (line 359) | onConnect () {}
method onHeaders (line 360) | onHeaders () {}
method onData (line 361) | onData () {}
method onComplete (line 362) | onComplete () {
method onError (line 365) | onError (err) {
method onConnect (line 712) | onConnect () {}
method onHeaders (line 713) | onHeaders () {}
method onData (line 714) | onData () {}
method onComplete (line 715) | onComplete () {
method onError (line 718) | onError (err) {
class Handler (line 758) | class Handler {
method onConnect (line 759) | onConnect () {}
method onHeaders (line 760) | onHeaders () {}
method onData (line 761) | onData () {}
method onComplete (line 762) | onComplete () {}
method onError (line 763) | onError () {
FILE: test/node-test/async_hooks.js
function getCurrentTransaction (line 14) | function getCurrentTransaction () {
function setCurrentTransaction (line 19) | function setCurrentTransaction (trans) {
method init (line 25) | init (asyncId, type, triggerAsyncId, resource) {
method destroy (line 30) | destroy (asyncId) {
FILE: test/node-test/autoselectfamily.js
function _lookup (line 20) | function _lookup (resolver, hostname, options, cb) {
function createDnsServer (line 38) | function createDnsServer (ipv6Addr, ipv4Addr, cb) {
FILE: test/node-test/balanced-pool.js
class TestServer (line 301) | class TestServer {
method constructor (line 302) | constructor ({ config: { server, socketHangup, downOnRequests, socketH...
method _shouldHangupOnClient (line 317) | _shouldHangupOnClient () {
method _shouldStopServer (line 328) | _shouldStopServer () {
method prepareForIteration (line 335) | async prepareForIteration (iteration) {
method start (line 346) | start () {
method isRunning (line 370) | isRunning () {
method stop (line 374) | stop () {
FILE: test/node-test/ca-fingerprint.js
method connect (line 28) | connect (opts, cb) {
method connect (line 75) | connect (opts, cb) {
function getIssuerCertificate (line 106) | function getIssuerCertificate (socket) {
function getFingerprint (line 126) | function getFingerprint (content, inputEncoding = 'base64', outputEncodi...
FILE: test/node-test/client-abort.js
class OnAbortError (line 9) | class OnAbortError extends Error {}
method read (line 58) | read () {
method onConnect (line 88) | onConnect (abort) {
method onHeaders (line 91) | onHeaders () {
method onData (line 94) | onData () {
method onComplete (line 97) | onComplete () {
method onError (line 100) | onError (err) {
method onConnect (line 132) | onConnect (abort) {
method onHeaders (line 139) | onHeaders () {
method onData (line 142) | onData () {
method onComplete (line 145) | onComplete () {
method onError (line 148) | onError (err) {
method onConnect (line 158) | onConnect (abort) {
method onHeaders (line 161) | onHeaders () {
method onData (line 164) | onData () {
method onComplete (line 167) | onComplete () {
method onError (line 170) | onError (err) {
method onConnect (line 199) | onConnect (abort) {
method onHeaders (line 202) | onHeaders () {
method onData (line 205) | onData () {
method onComplete (line 208) | onComplete () {
method onError (line 211) | onError () {
FILE: test/node-test/client-dispatch.js
method onError (line 46) | onError (err) {
method onError (line 57) | onError (err) {
method onError (line 68) | onError (err) {
method onError (line 80) | onError (err) {
method onError (line 87) | onError (err) {
method onConnect (line 125) | onConnect () {
method onHeaders (line 127) | onHeaders (statusCode, headers) {
method onData (line 131) | onData (buf) {
method onComplete (line 134) | onComplete (trailers) {
method onError (line 138) | onError () {
method onConnect (line 179) | onConnect () {
method onHeaders (line 181) | onHeaders (statusCode, headers) {
method onData (line 189) | onData (buf) {
method onComplete (line 192) | onComplete (trailers) {
method onError (line 200) | onError () {
method onConnect (line 226) | onConnect () {
method onHeaders (line 228) | onHeaders (statusCode, headers) {
method onData (line 231) | onData (buf) {
method onComplete (line 234) | onComplete (trailers) {
method onError (line 237) | onError (err) {
method onConnect (line 263) | onConnect () {
method onHeaders (line 265) | onHeaders (statusCode, headers) {
method onData (line 268) | onData (buf) {
method onComplete (line 271) | onComplete (trailers) {
method onError (line 274) | onError (err) {
method onConnect (line 300) | onConnect () {
method onHeaders (line 302) | onHeaders (statusCode, headers) {
method onData (line 305) | onData (buf) {
method onComplete (line 308) | onComplete (trailers) {
method onError (line 311) | onError (err) {
method onConnect (line 337) | onConnect () {
method onHeaders (line 340) | onHeaders (statusCode, headers) {
method onData (line 343) | onData (buf) {
method onComplete (line 346) | onComplete (trailers) {
method onError (line 349) | onError (err) {
method onConnect (line 388) | onConnect () {
method onHeaders (line 390) | onHeaders (statusCode, headers) {
method onUpgrade (line 393) | onUpgrade (statusCode, headers, socket) {
method onData (line 407) | onData (buf) {
method onComplete (line 410) | onComplete (trailers) {
method onError (line 413) | onError () {
method onConnect (line 438) | onConnect () {
method onData (line 440) | onData (buf) {
method onComplete (line 443) | onComplete (trailers) {
method onError (line 446) | onError (err) {
method onConnect (line 471) | onConnect () {
method onHeaders (line 473) | onHeaders (statusCode, headers) {
method onComplete (line 476) | onComplete (trailers) {
method onError (line 479) | onError (err) {
method onConnect (line 504) | onConnect () {
method onHeaders (line 506) | onHeaders (statusCode, headers) {
method onData (line 509) | onData (buf) {
method onError (line 512) | onError (err) {
method onConnect (line 538) | onConnect () {
method onHeaders (line 540) | onHeaders (statusCode, headers) {
method onData (line 543) | onData (buf) {
method onComplete (line 546) | onComplete (trailers) {
method onConnect (line 575) | onConnect () {
method onHeaders (line 577) | onHeaders (statusCode, headers) {
method onError (line 579) | onError (err) {
method onConnect (line 606) | onConnect () {
method onHeaders (line 608) | onHeaders (statusCode, headers) {
method onError (line 610) | onError (err) {
method onConnect (line 664) | onConnect () {}
method onHeaders (line 665) | onHeaders () {}
method onData (line 666) | onData () {}
method onError (line 667) | onError (err) {
method onBodySent (line 694) | onBodySent (chunk) {
method onRequestSent (line 697) | onRequestSent () {
method onError (line 700) | onError (err) {
method onConnect (line 703) | onConnect () {}
method onHeaders (line 704) | onHeaders () {}
method onData (line 705) | onData () {}
method onComplete (line 706) | onComplete () {
method onBodySent (line 734) | onBodySent (chunk) {
method onRequestSent (line 738) | onRequestSent () {
method onError (line 741) | onError (err) {
method onConnect (line 744) | onConnect () {}
method onHeaders (line 745) | onHeaders () {}
method onData (line 746) | onData () {}
method onComplete (line 747) | onComplete () {
method onBodySent (line 775) | onBodySent (chunk) {
method onError (line 779) | onError (err) {
method onConnect (line 782) | onConnect () {}
method onHeaders (line 783) | onHeaders () {}
method onData (line 784) | onData () {}
method onComplete (line 785) | onComplete () {
method onBodySent (line 809) | onBodySent (chunk) {
method onError (line 812) | onError (err) {
method onConnect (line 817) | onConnect () {}
method onHeaders (line 818) | onHeaders () {}
method onData (line 819) | onData () {}
method onComplete (line 820) | onComplete () {}
method onConnect (line 845) | onConnect () {
method onBodySent (line 848) | onBodySent () {
method onResponseStarted (line 851) | onResponseStarted () {
method onHeaders (line 854) | onHeaders () {
method onData (line 857) | onData () {
method onComplete (line 860) | onComplete () {
method onError (line 864) | onError (err) {
method onConnect (line 893) | onConnect () {}
method onResponseStarted (line 894) | onResponseStarted () {
method onHeaders (line 897) | onHeaders () {}
method onData (line 898) | onData () {}
method onComplete (line 899) | onComplete () {
method onError (line 903) | onError (err) {
method onConnect (line 941) | onConnect () {
method onBodySent (line 944) | onBodySent () {
method onResponseStarted (line 947) | onResponseStarted () {
method onHeaders (line 950) | onHeaders () {
method onData (line 953) | onData () {
method onComplete (line 956) | onComplete () {
method onError (line 960) | onError (err) {
method onConnect (line 999) | onConnect () {
method onBodySent (line 1002) | onBodySent () {
method onResponseStarted (line 1005) | onResponseStarted () {
method onHeaders (line 1008) | onHeaders () {
method onData (line 1011) | onData () {
method onComplete (line 1014) | onComplete () {
method onError (line 1018) | onError (err) {
method onConnect (line 1029) | onConnect () {
method onBodySent (line 1032) | onBodySent () {
method onResponseStarted (line 1035) | onResponseStarted () {
method onHeaders (line 1038) | onHeaders () {
method onData (line 1041) | onData () {
method onComplete (line 1044) | onComplete () {
method onError (line 1048) | onError (err) {
method onConnect (line 1093) | onConnect () {
method onBodySent (line 1096) | onBodySent () {
method onResponseStarted (line 1099) | onResponseStarted () {
method onHeaders (line 1102) | onHeaders () {
method onData (line 1105) | onData () {
method onComplete (line 1108) | onComplete () {
method onError (line 1112) | onError (err) {
method onConnect (line 1123) | onConnect () {
method onBodySent (line 1126) | onBodySent () {
method onResponseStarted (line 1129) | onResponseStarted () {
method onHeaders (line 1132) | onHeaders () {
method onData (line 1135) | onData () {
method onComplete (line 1138) | onComplete () {
method onError (line 1142) | onError (err) {
FILE: test/node-test/client-errors.js
class IteratorError (line 18) | class IteratorError extends Error {}
function errorAndPipelining (line 125) | function errorAndPipelining (type) {
function errorAndChunkedEncodingPipelining (line 200) | function errorAndChunkedEncodingPipelining (type) {
function checkError (line 679) | function checkError (err) {
method read (line 690) | read () {}
method read (line 706) | read () {}
method read (line 774) | read () {}
function socketFailWrite (line 947) | function socketFailWrite (type) {
function socketFailEndWrite (line 987) | function socketFailEndWrite (type) {
method read (line 1137) | read () {
method read (line 1306) | read () {
FILE: test/node-test/debug.js
function extractLines (line 169) | function extractLines (chunks) {
FILE: test/node-test/tree.js
function generateAsciiString (line 52) | function generateAsciiString (length) {
FILE: test/pool.js
method connect (line 84) | connect (opts, cb) {
class FakeClient (line 379) | class FakeClient extends EventEmitter {
method constructor (line 380) | constructor () {
method dispatch (line 386) | dispatch (req, handler) {
method onError (line 393) | onError (err) {
method onConnect (line 672) | onConnect () {
method onHeaders (line 674) | onHeaders (statusCode, headers) {
method onData (line 677) | onData (chunk) {
method onComplete (line 680) | onComplete () {
method onError (line 683) | onError () {
method onConnect (line 819) | onConnect () {
method onHeaders (line 821) | onHeaders (statusCode, headers) {
method onData (line 824) | onData (chunk) {
method onComplete (line 826) | onComplete () {
method onError (line 829) | onError () {
method onConnect (line 840) | onConnect () {
method onHeaders (line 843) | onHeaders (statusCode, headers) {
method onData (line 846) | onData (chunk) {
method onError (line 849) | onError (err) {
method onConnect (line 877) | onConnect () {
method onHeaders (line 879) | onHeaders (statusCode, headers) {
method onData (line 882) | onData (chunk) {
method onComplete (line 884) | onComplete () {
method onError (line 887) | onError () {
method onConnect (line 924) | onConnect () {
method onHeaders (line 926) | onHeaders (statusCode, headers) {
method onData (line 929) | onData (chunk) {
method onComplete (line 931) | onComplete () {
method onError (line 934) | onError () {
method onConnect (line 971) | onConnect () {
method onHeaders (line 973) | onHeaders (statusCode, headers) {
method onData (line 976) | onData (chunk) {
method onComplete (line 978) | onComplete () {
method onError (line 981) | onError () {
method read (line 1016) | read () {
method read (line 1036) | read () {
method read (line 1072) | read () {
method read (line 1090) | read () {
FILE: test/promises.js
function postServer (line 50) | function postServer (t, expected) {
function onWarning (line 244) | function onWarning (warning) {
function makeRequest (line 270) | async function makeRequest (i) {
function makeRequestAndExpectUrl (line 282) | async function makeRequestAndExpectUrl (client, i, t) {
FILE: test/proxy-agent.js
function buildServer (line 1350) | function buildServer () {
function buildSSLServer (line 1357) | function buildSSLServer () {
function buildProxy (line 1372) | function buildProxy (listener) {
function buildSSLProxy (line 1381) | function buildSSLProxy () {
FILE: test/proxy.js
function buildServer (line 179) | function buildServer () {
function buildProxy (line 186) | function buildProxy () {
FILE: test/readable.js
function resume (line 11) | function resume () {
function abort (line 13) | function abort () {
function resume (line 32) | function resume () {
function abort (line 34) | function abort () {
function resume (line 46) | function resume () {
function abort (line 48) | function abort () {
function resume (line 66) | function resume () {
function abort (line 68) | function abort () {
function resume (line 89) | function resume () {
function abort (line 91) | function abort () {
function resume (line 110) | function resume () {
function abort (line 112) | function abort () {
function resume (line 130) | function resume () {
function abort (line 132) | function abort () {
function resume (line 150) | function resume () {
function abort (line 152) | function abort () {
function resume (line 171) | function resume () {
function abort (line 173) | function abort () {
FILE: test/request-timeout.js
method read (line 722) | read () {
method write (line 736) | write (chunk, encoding, callback) {
method final (line 739) | final (callback) {
method read (line 779) | read () {
method write (line 793) | write (chunk, encoding, callback) {
method final (line 796) | final (callback) {
FILE: test/request-timeout2.js
method read (line 35) | read () {
FILE: test/request.js
method [Symbol.iterator] (line 410) | * [Symbol.iterator] () {
method [Symbol.iterator] (line 488) | * [Symbol.iterator] () {
FILE: test/retry-handler.js
method onConnect (line 64) | onConnect () {
method onHeaders (line 67) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 71) | onData (chunk) {
method onComplete (line 75) | onComplete () {
method onError (line 79) | onError () {
method onConnect (line 159) | onConnect () {
method onHeaders (line 162) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 166) | onData (chunk) {
method onComplete (line 170) | onComplete () {
method onError (line 174) | onError () {
method onConnect (line 230) | onConnect () {
method onHeaders (line 233) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 236) | onData (chunk) {
method onComplete (line 239) | onComplete () {
method onError (line 242) | onError (err) {
method onConnect (line 307) | onConnect () {
method onHeaders (line 310) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 314) | onData (chunk) {
method onComplete (line 318) | onComplete () {
method onError (line 321) | onError (err) {
method onConnect (line 392) | onConnect () {
method onHeaders (line 395) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 399) | onData (chunk) {
method onComplete (line 403) | onComplete () {
method onError (line 406) | onError (err) {
method onConnect (line 474) | onConnect () {
method onHeaders (line 477) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 481) | onData (chunk) {
method onComplete (line 485) | onComplete () {
method onError (line 488) | onError (err) {
method onConnect (line 570) | onConnect () {
method onHeaders (line 573) | onHeaders (status, _rawHeaders, _resume, _statusMessage) {
method onData (line 577) | onData (chunk) {
method onComplete (line 581) | onComplete () {
method onError (line 585) | onError () {
method onConnect (line 655) | onConnect () {
method onHeaders (line 658) | onHeaders (_status, _rawHeaders, _resume, _statusMessage) {
method onData (line 661) | onData (chunk) {
method onComplete (line 665) | onComplete () {
method onError (line 668) | onError (err) {
method onConnect (line 943) | onConnect () {
method onHeaders (line 946) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 950) | onData (chunk) {
method onComplete (line 954) | onComplete () {
method onError (line 957) | onError (err) {
method onConnect (line 1111) | onConnect () {
method onHeaders (line 1114) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1118) | onData (chunk) {
method onComplete (line 1122) | onComplete () {
method onError (line 1126) | onError () {
method onConnect (line 1211) | onConnect () {
method onHeaders (line 1214) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1218) | onData (chunk) {
method onComplete (line 1222) | onComplete () {
method onError (line 1226) | onError () {
method onConnect (line 1311) | onConnect () {
method onHeaders (line 1314) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1318) | onData (chunk) {
method onComplete (line 1322) | onComplete () {
method onError (line 1326) | onError () {
method onConnect (line 1411) | onConnect () {
method onHeaders (line 1414) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1418) | onData (chunk) {
method onComplete (line 1422) | onComplete () {
method onError (line 1426) | onError () {
method onConnect (line 1506) | onConnect () {
method onHeaders (line 1509) | onHeaders (status, _rawHeaders, _resume, _statusMessage) {
method onData (line 1513) | onData (chunk) {
method onComplete (line 1517) | onComplete () {
method onError (line 1520) | onError (err) {
method onConnect (line 1599) | onConnect () {
method onHeaders (line 1602) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1606) | onData (chunk) {
method onComplete (line 1610) | onComplete () {
method onError (line 1613) | onError (err) {
FILE: test/retry-handler2.js
method onConnect (line 189) | onConnect () {
method onHeaders (line 192) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 196) | onData (chunk) {
method onComplete (line 200) | onComplete () {
method onError (line 204) | onError () {
method onConnect (line 285) | onConnect () {
method onHeaders (line 288) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 292) | onData (chunk) {
method onComplete (line 296) | onComplete () {
method onError (line 300) | onError () {
method onConnect (line 361) | onConnect () {
method onHeaders (line 364) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 367) | onData (chunk) {
method onComplete (line 371) | onComplete () {
method onError (line 375) | onError () {
method onConnect (line 441) | onConnect () {
method onHeaders (line 444) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 448) | onData (chunk) {
method onComplete (line 452) | onComplete () {
method onError (line 455) | onError () {
method onConnect (line 529) | onConnect () {
method onHeaders (line 532) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 536) | onData (chunk) {
method onComplete (line 540) | onComplete () {
method onError (line 543) | onError () {
method onConnect (line 614) | onConnect () {
method onHeaders (line 617) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 621) | onData (chunk) {
method onComplete (line 625) | onComplete () {
method onError (line 628) | onError () {
method onConnect (line 711) | onConnect () {
method onHeaders (line 714) | onHeaders (status, _rawHeaders, _resume, _statusMessage) {
method onData (line 718) | onData (chunk) {
method onComplete (line 722) | onComplete () {
method onError (line 726) | onError () {
method onConnect (line 799) | onConnect () {
method onHeaders (line 802) | onHeaders (_status, _rawHeaders, _resume, _statusMessage) {
method onData (line 805) | onData (chunk) {
method onComplete (line 809) | onComplete () {
method onError (line 812) | onError (err) {
method onConnect (line 1093) | onConnect () {
method onHeaders (line 1096) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1100) | onData (chunk) {
method onComplete (line 1104) | onComplete () {
method onError (line 1107) | onError (err) {
method onConnect (line 1263) | onConnect () {
method onHeaders (line 1266) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1270) | onData (chunk) {
method onComplete (line 1274) | onComplete () {
method onError (line 1278) | onError () {
method onConnect (line 1364) | onConnect () {
method onHeaders (line 1367) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1371) | onData (chunk) {
method onComplete (line 1375) | onComplete () {
method onError (line 1379) | onError () {
method onConnect (line 1465) | onConnect () {
method onHeaders (line 1468) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1472) | onData (chunk) {
method onComplete (line 1476) | onComplete () {
method onError (line 1480) | onError () {
method onConnect (line 1566) | onConnect () {
method onHeaders (line 1569) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1573) | onData (chunk) {
method onComplete (line 1577) | onComplete () {
method onError (line 1581) | onError () {
method onConnect (line 1662) | onConnect () {
method onHeaders (line 1665) | onHeaders (status, _rawHeaders, _resume, _statusMessage) {
method onData (line 1669) | onData (chunk) {
method onComplete (line 1673) | onComplete () {
method onError (line 1676) | onError (err) {
method onConnect (line 1752) | onConnect () {
method onHeaders (line 1755) | onHeaders (status, _rawHeaders, resume, _statusMessage) {
method onData (line 1759) | onData (chunk) {
method onComplete (line 1763) | onComplete () {
method onError (line 1766) | onError (err) {
FILE: test/round-robin-pool.js
method connect (line 53) | connect (opts, cb) {
FILE: test/snapshot-testing.js
constant TEST_CONSTANTS (line 13) | const TEST_CONSTANTS = {
function createSnapshotPath (line 33) | function createSnapshotPath (prefix = 'test-snapshots') {
function createTestServer (line 37) | function createTestServer (handler) {
function setupServer (line 41) | async function setupServer (server) {
function setupCleanup (line 48) | function setupCleanup (t, resources) {
function createJsonResponse (line 66) | function createJsonResponse (data) {
function createDefaultHandler (line 70) | function createDefaultHandler () {
function createEchoHandler (line 85) | function createEchoHandler () {
function createSequentialHandler (line 100) | function createSequentialHandler (responses) {
function createLargeSnapshotFile (line 108) | async function createLargeSnapshotFile (path, size = 1000) {
FILE: test/socket-back-pressure.js
method read (line 18) | read () {
FILE: test/stream-compat.js
method read (line 22) | read () {}
FILE: test/timers.js
constant ACCEPTABLE_DELTA (line 16) | const ACCEPTABLE_DELTA = 700
function tick (line 18) | function tick (duration) {
FILE: test/tls-cert-leak.js
function makeRequest (line 43) | async function makeRequest (i) {
function processBatch (line 74) | async function processBatch (start, batchSize) {
function runTest (line 119) | async function runTest () {
function checkMemoryTrend (line 146) | function checkMemoryTrend () {
function finalMemoryCheck (line 181) | function finalMemoryCheck () {
FILE: test/tls-session-reuse.js
function request (line 60) | function request () {
function request (line 149) | function request (pool, expectTLSSessionCache) {
function runRequests (line 161) | async function runRequests (pool, numIterations, expectTLSSessionCache) {
FILE: test/types/cache-interceptor.test-d.ts
method get (line 6) | get (_: CacheInterceptor.CacheKey): CacheInterceptor.GetResult | Promise...
method createWriteStream (line 10) | createWriteStream (_: CacheInterceptor.CacheKey, _2: CacheInterceptor.Ca...
method delete (line 14) | delete (_: CacheInterceptor.CacheKey): void | Promise<void> {
FILE: test/types/connector.test-d.ts
method connect (line 8) | connect (opts: buildConnector.Options, cb: buildConnector.Callback) {
FILE: test/types/dispatcher.events.test-d.ts
type EventHandler (line 6) | interface EventHandler {
FILE: test/types/dispatcher.test-d.ts
method [Symbol.iterator] (line 21) | * [Symbol.iterator] () {
FILE: test/types/dns-interceptor.test-d.ts
method size (line 6) | get size (): number {
method get (line 9) | get (origin: string): Interceptors.DNSInterceptorOriginRecords | null {
method set (line 12) | set (origin: string, records: Interceptors.DNSInterceptorOriginRecords |...
method delete (line 15) | delete (origin: string): void {
method full (line 18) | full (): boolean {
FILE: test/types/errors.test-d.ts
function f (line 120) | function f (): errors.HeadersTimeoutError | errors.ConnectTimeoutError { }
FILE: test/types/global-dispatcher.test-d.ts
class CustomDispatcher (line 6) | class CustomDispatcher extends Dispatcher {}
FILE: test/types/mock-agent.test-d.ts
type PendingInterceptor (line 70) | interface PendingInterceptor extends MockDispatch {
FILE: test/types/mock-errors.test-d.ts
function f (line 12) | function f (): mockErrors.MockNotMatchedError { }
FILE: test/types/mock-interceptor.test-d.ts
class CustomError (line 59) | class CustomError extends Error {
method hello (line 60) | hello (): void {}
FILE: test/utils/async-iterators.js
constant STREAM (line 12) | const STREAM = 'stream'
constant ASYNC_ITERATOR (line 13) | const ASYNC_ITERATOR = 'async-iterator'
function maybeWrapStream (line 14) | function maybeWrapStream (stream, type) {
FILE: test/utils/date.js
function asctime (line 279) | function asctime (date) {
function rfc850 (line 335) | function rfc850 (date) {
FILE: test/utils/event-loop-blocker.js
function eventLoopBlocker (line 3) | function eventLoopBlocker (ms) {
FILE: test/utils/formdata.js
function parseFormDataString (line 5) | function parseFormDataString (
FILE: test/utils/hello-world-server.js
function sendInDelayedChunks (line 14) | async function sendInDelayedChunks (res, payload, delay) {
FILE: test/utils/node-http.js
function closeServerAsPromise (line 5) | function closeServerAsPromise (server) {
function closeClientAndServerAsPromise (line 12) | function closeClientAndServerAsPromise (client, server) {
FILE: test/utils/redirecting-servers.js
function close (line 6) | function close (server) {
function startServer (line 15) | function startServer (handler) {
function startRedirectingServer (line 27) | async function startRedirectingServer () {
function startRedirectingWithBodyServer (line 90) | async function startRedirectingWithBodyServer () {
function startRedirectingWithoutLocationServer (line 107) | function startRedirectingWithoutLocationServer () {
function startRedirectingChainServers (line 125) | async function startRedirectingChainServers () {
function startRedirectingWithAuthorization (line 168) | async function startRedirectingWithAuthorization (authorization) {
function startRedirectingWithCookie (line 191) | async function startRedirectingWithCookie (cookie) {
function startRedirectingWithRelativePath (line 214) | async function startRedirectingWithRelativePath (t) {
function startRedirectingWithQueryParams (line 235) | async function startRedirectingWithQueryParams (t) {
FILE: test/utils/stream.js
function createReadable (line 5) | function createReadable (data) {
function createWritable (line 14) | function createWritable (target) {
class Source (line 26) | class Source {
method constructor (line 27) | constructor (data) {
method start (line 31) | async start (controller) {
method pull (line 35) | async pull (controller) {
function createReadableStream (line 41) | function createReadableStream (data) {
FILE: test/web-platform-tests/runner/test-runner.mjs
function setupGlobalTestharnessCallbacks (line 92) | function setupGlobalTestharnessCallbacks () {
function generateAndRunBundle (line 123) | async function generateAndRunBundle (url) {
FILE: test/web-platform-tests/runner/utils.mjs
function sanitizeUnpairedSurrogates (line 2) | function sanitizeUnpairedSurrogates (str) {
function codeUnitStr (line 15) | function codeUnitStr (char) {
FILE: test/web-platform-tests/wpt-runner.mjs
constant WPT_DIR (line 14) | const WPT_DIR = join(import.meta.dirname, 'wpt')
constant EXPECTATION_PATH (line 15) | const EXPECTATION_PATH = join(import.meta.dirname, 'expectation.json')
constant CA_CERT_PATH (line 16) | const CA_CERT_PATH = join(import.meta.dirname, 'runner/certs/cacert.pem')
function runWithTestUtil (line 20) | async function runWithTestUtil (testFunction) {
function runSingleTest (line 67) | function runSingleTest (url, options, expectation, timeout = 10000) {
function getExpectation (line 155) | function getExpectation () {
function updateExpectations (line 159) | function updateExpectations (results) {
function getManifest (line 203) | function getManifest () {
function discoverTestsToRun (line 211) | function discoverTestsToRun (filter, expectation) {
function generateWPTReport (line 267) | function generateWPTReport (results, startTime, endTime) {
function setup (line 318) | async function setup () {
function run (line 440) | async function run (filters = []) {
FILE: test/webidl/converters.js
method [Symbol.iterator] (line 38) | [Symbol.iterator] () {
function obj (line 115) | function obj () {}
method abc (line 140) | get abc () {
method zyx (line 143) | get zyx () {
FILE: test/webidl/helpers.js
class A (line 8) | class A {}
class B (line 9) | class B {}
class V (line 22) | class V {}
method value (line 51) | get value () {
FILE: test/websocket/custom-headers.js
class TestAgent (line 12) | class TestAgent extends Agent {
method dispatch (line 13) | dispatch (options) {
FILE: test/websocket/events.js
function listen (line 54) | function listen () {}
FILE: test/websocket/opening-handshake.js
function setupListener (line 159) | function setupListener () {
FILE: test/websocket/permessage-deflate-windowbits.js
function createMaliciousServer (line 15) | function createMaliciousServer (windowBitsValue) {
function makeWsFrame (line 68) | function makeWsFrame ({ opcode, rsv1, payload }) {
FILE: test/websocket/websocketinit.js
class WsDispatcher (line 8) | class WsDispatcher extends Dispatcher {
method constructor (line 9) | constructor () {
method dispatch (line 14) | dispatch () {
FILE: types/agent.d.ts
class Agent (line 9) | class Agent extends Dispatcher {
type Options (line 22) | interface Options extends Pool.Options {
type DispatchOptions (line 30) | interface DispatchOptions extends Dispatcher.DispatchOptions {
FILE: types/balanced-pool.d.ts
type BalancedPoolConnectOptions (line 7) | type BalancedPoolConnectOptions = Omit<Dispatcher.ConnectOptions, 'origin'>
class BalancedPool (line 9) | class BalancedPool extends Dispatcher {
FILE: types/cache-interceptor.d.ts
type CacheMethods (line 6) | type CacheMethods = 'GET' | 'HEAD' | 'OPTIONS' | 'TRACE'
type CacheHandlerOptions (line 8) | interface CacheHandlerOptions {
type CacheOptions (line 16) | interface CacheOptions {
type CacheControlDirectives (line 50) | interface CacheControlDirectives {
type CacheKey (line 69) | interface CacheKey {
type CacheValue (line 76) | interface CacheValue {
type DeleteByUri (line 88) | interface DeleteByUri {
type GetResult (line 94) | type GetResult = {
type CacheStore (line 110) | interface CacheStore {
type MemoryCacheStoreOpts (line 118) | interface MemoryCacheStoreOpts {
class MemoryCacheStore (line 137) | class MemoryCacheStore implements CacheStore {
type SqliteCacheStoreOpts (line 147) | interface SqliteCacheStoreOpts {
class SqliteCacheStore (line 165) | class SqliteCacheStore implements CacheStore {
FILE: types/cache.d.ts
type CacheStorage (line 3) | interface CacheStorage {
type Cache (line 16) | interface Cache {
type CacheQueryOptions (line 26) | interface CacheQueryOptions {
type MultiCacheQueryOptions (line 32) | interface MultiCacheQueryOptions extends CacheQueryOptions {
FILE: types/client-stats.d.ts
class ClientStats (line 5) | class ClientStats {
FILE: types/client.d.ts
type ClientConnectOptions (line 6) | type ClientConnectOptions = Omit<Dispatcher.ConnectOptions, 'origin'>
class Client (line 11) | class Client extends Dispatcher {
type OptionsInterceptors (line 33) | interface OptionsInterceptors {
type Options (line 36) | interface Options {
type SocketInfo (line 111) | interface SocketInfo {
FILE: types/connector.d.ts
type BuildOptions (line 8) | type BuildOptions = (ConnectionOptions | TcpNetConnectOpts | IpcNetConne...
type Options (line 19) | interface Options {
type Callback (line 30) | type Callback = (...args: CallbackArgs) => void
type CallbackArgs (line 31) | type CallbackArgs = [null, Socket | TLSSocket] | [Error, null]
type connector (line 33) | interface connector {
FILE: types/content-type.d.ts
type MIMEType (line 3) | interface MIMEType {
FILE: types/cookies.d.ts
type Cookie (line 5) | interface Cookie {
FILE: types/diagnostics-channel.d.ts
type Request (line 7) | interface Request {
type Response (line 14) | interface Response {
type ConnectParams (line 19) | interface ConnectParams {
type Connector (line 26) | type Connector = buildConnector.connector
type RequestCreateMessage (line 27) | interface RequestCreateMessage {
type RequestBodySentMessage (line 30) | interface RequestBodySentMessage {
type RequestBodyChunkSentMessage (line 34) | interface RequestBodyChunkSentMessage {
type RequestBodyChunkReceivedMessage (line 38) | interface RequestBodyChunkReceivedMessage {
type RequestHeadersMessage (line 42) | interface RequestHeadersMessage {
type RequestTrailersMessage (line 46) | interface RequestTrailersMessage {
type RequestErrorMessage (line 50) | interface RequestErrorMessage {
type ClientSendHeadersMessage (line 54) | interface ClientSendHeadersMessage {
type ClientBeforeConnectMessage (line 59) | interface ClientBeforeConnectMessage {
type ClientConnectedMessage (line 63) | interface ClientConnectedMessage {
type ClientConnectErrorMessage (line 68) | interface ClientConnectErrorMessage {
FILE: types/dispatcher.d.ts
type AbortSignal (line 11) | type AbortSignal = unknown
type UndiciHeaders (line 15) | type UndiciHeaders = Record<string, string | string[]> | IncomingHttpHea...
class Dispatcher (line 18) | class Dispatcher extends EventEmitter {
type ComposedDispatcher (line 99) | interface ComposedDispatcher extends Dispatcher { }
type Dispatch (line 100) | type Dispatch = Dispatcher['dispatch']
type DispatcherComposeInterceptor (line 101) | type DispatcherComposeInterceptor = (dispatch: Dispatch) => Dispatch
type DispatchOptions (line 102) | interface DispatchOptions {
type ConnectOptions (line 131) | interface ConnectOptions<TOpaque = null> {
type RequestOptions (line 145) | interface RequestOptions<TOpaque = null> extends DispatchOptions {
type PipelineOptions (line 159) | interface PipelineOptions<TOpaque = null> extends RequestOptions<TOpaque> {
type UpgradeOptions (line 163) | interface UpgradeOptions {
type ConnectData (line 178) | interface ConnectData<TOpaque = null> {
type ResponseData (line 184) | interface ResponseData<TOpaque = null> {
type PipelineHandlerData (line 193) | interface PipelineHandlerData<TOpaque = null> {
type StreamData (line 200) | interface StreamData<TOpaque = null> {
type UpgradeData (line 204) | interface UpgradeData<TOpaque = null> {
type StreamFactoryData (line 209) | interface StreamFactoryData<TOpaque = null> {
type StreamFactory (line 215) | type StreamFactory<TOpaque = null> = (data: StreamFactoryData<TOpaque>) ...
type DispatchController (line 217) | interface DispatchController {
type DispatchHandler (line 226) | interface DispatchHandler {
type PipelineHandler (line 259) | type PipelineHandler<TOpaque = null> = (data: PipelineHandlerData<TOpaqu...
type HttpMethod (line 260) | type HttpMethod = Autocomplete<'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE...
type BodyMixin (line 265) | interface BodyMixin {
type DispatchInterceptor (line 276) | interface DispatchInterceptor {
FILE: types/env-http-proxy-agent.d.ts
class EnvHttpProxyAgent (line 7) | class EnvHttpProxyAgent extends Dispatcher {
type Options (line 14) | interface Options extends Omit<ProxyAgent.Options, 'uri'> {
FILE: types/errors.d.ts
class UndiciError (line 7) | class UndiciError extends Error {
class ConnectTimeoutError (line 13) | class ConnectTimeoutError extends UndiciError {
class HeadersTimeoutError (line 19) | class HeadersTimeoutError extends UndiciError {
class HeadersOverflowError (line 25) | class HeadersOverflowError extends UndiciError {
class BodyTimeoutError (line 31) | class BodyTimeoutError extends UndiciError {
class ResponseError (line 36) | class ResponseError extends UndiciError {
class InvalidArgumentError (line 53) | class InvalidArgumentError extends UndiciError {
class InvalidReturnValueError (line 59) | class InvalidReturnValueError extends UndiciError {
class RequestAbortedError (line 65) | class RequestAbortedError extends UndiciError {
class InformationalError (line 71) | class InformationalError extends UndiciError {
class RequestContentLengthMismatchError (line 77) | class RequestContentLengthMismatchError extends UndiciError {
class ResponseContentLengthMismatchError (line 83) | class ResponseContentLengthMismatchError extends UndiciError {
class ClientDestroyedError (line 89) | class ClientDestroyedError extends UndiciError {
class ClientClosedError (line 95) | class ClientClosedError extends UndiciError {
class SocketError (line 101) | class SocketError extends UndiciError {
class NotSupportedError (line 108) | class NotSupportedError extends UndiciError {
class BalancedPoolMissingUpstreamError (line 114) | class BalancedPoolMissingUpstreamError extends UndiciError {
class HTTPParserError (line 119) | class HTTPParserError extends UndiciError {
class ResponseExceededMaxSizeError (line 125) | class ResponseExceededMaxSizeError extends UndiciError {
class RequestRetryError (line 130) | class RequestRetryError extends UndiciError {
class SecureProxyConnectionError (line 147) | class SecureProxyConnectionError extends UndiciError {
class MaxOriginsReachedError (line 157) | class MaxOriginsReachedError extends UndiciError {
class Socks5ProxyError (line 163) | class Socks5ProxyError extends UndiciError {
class MessageSizeExceededError (line 173) | class MessageSizeExceededError extends UndiciError {
FILE: types/eventsource.d.ts
type EventSourceEventMap (line 10) | interface EventSourceEventMap {
type EventSource (line 16) | interface EventSource extends EventTarget {
type EventSourceInit (line 58) | interface EventSourceInit {
FILE: types/fetch.d.ts
type RequestInfo (line 12) | type RequestInfo = string | URL | Request
type BodyInit (line 19) | type BodyInit =
class BodyMixin (line 30) | class BodyMixin {
type SpecIterator (line 59) | interface SpecIterator<T, TReturn = any, TNext = undefined> {
type SpecIterableIterator (line 63) | interface SpecIterableIterator<T> extends SpecIterator<T> {
type SpecIterable (line 67) | interface SpecIterable<T> {
type HeadersInit (line 71) | type HeadersInit = [string, string][] | HeaderRecord | Headers
class Headers (line 73) | class Headers implements SpecIterable<[string, string]> {
type RequestCache (line 92) | type RequestCache =
type RequestCredentials (line 100) | type RequestCredentials = 'omit' | 'include' | 'same-origin'
type RequestDestination (line 102) | type RequestDestination =
type RequestInit (line 122) | interface RequestInit {
type ReferrerPolicy (line 140) | type ReferrerPolicy =
type RequestMode (line 151) | type RequestMode = 'cors' | 'navigate' | 'no-cors' | 'same-origin'
type RequestRedirect (line 153) | type RequestRedirect = 'error' | 'follow' | 'manual'
type RequestDuplex (line 155) | type RequestDuplex = 'half'
class Request (line 157) | class Request extends BodyMixin {
type ResponseInit (line 179) | interface ResponseInit {
type ResponseType (line 185) | type ResponseType =
type ResponseRedirectStatus (line 193) | type ResponseRedirectStatus = 301 | 302 | 303 | 307 | 308
class Response (line 195) | class Response extends BodyMixin {
FILE: types/formdata.d.ts
type FormDataEntryValue (line 10) | type FormDataEntryValue = string | File
class FormData (line 15) | class FormData {
FILE: types/h2c-client.d.ts
type H2ClientOptions (line 5) | type H2ClientOptions = Omit<Dispatcher.ConnectOptions, 'origin'>
class H2CClient (line 10) | class H2CClient extends Dispatcher {
type Options (line 30) | interface Options {
FILE: types/handlers.d.ts
class RedirectHandler (line 3) | class RedirectHandler implements Dispatcher.DispatchHandler {
class DecoratorHandler (line 13) | class DecoratorHandler implements Dispatcher.DispatchHandler {
FILE: types/header.d.ts
type IncomingHttpHeaders (line 6) | type IncomingHttpHeaders = Record<string, string | string[] | undefined>
type HeaderNames (line 8) | type HeaderNames = Autocomplete<
type IANARegisteredMimeType (line 100) | type IANARegisteredMimeType = Autocomplete<
type KnownHeaderValues (line 152) | type KnownHeaderValues = {
type HeaderRecord (line 156) | type HeaderRecord = {
FILE: types/interceptors.d.ts
type DumpInterceptorOpts (line 9) | type DumpInterceptorOpts = { maxSize?: number }
type RetryInterceptorOpts (line 10) | type RetryInterceptorOpts = RetryHandler.RetryOptions
type RedirectInterceptorOpts (line 11) | type RedirectInterceptorOpts = { maxRedirections?: number }
type DecompressInterceptorOpts (line 12) | type DecompressInterceptorOpts = {
type ResponseErrorInterceptorOpts (line 17) | type ResponseErrorInterceptorOpts = { throwOnError: boolean }
type CacheInterceptorOpts (line 18) | type CacheInterceptorOpts = CacheHandler.CacheOptions
type DNSInterceptorRecord (line 21) | type DNSInterceptorRecord = { address: string, ttl: number, family: 4 | 6 }
type DNSInterceptorOriginRecords (line 22) | type DNSInterceptorOriginRecords = { records: { 4: { ips: DNSInterceptor...
type DNSStorage (line 23) | type DNSStorage = {
type DNSInterceptorOpts (line 30) | type DNSInterceptorOpts = {
type DeduplicateMethods (line 41) | type DeduplicateMethods = 'GET' | 'HEAD' | 'OPTIONS' | 'TRACE'
type DeduplicateInterceptorOpts (line 42) | type DeduplicateInterceptorOpts = {
FILE: types/mock-agent.d.ts
type PendingInterceptor (line 9) | interface PendingInterceptor extends MockDispatch {
class MockAgent (line 14) | class MockAgent<TMockAgentOptions extends MockAgent.Options = MockAgent....
type PendingInterceptorsFormatter (line 49) | interface PendingInterceptorsFormatter {
type Options (line 55) | interface Options extends Agent.Options {
FILE: types/mock-call-history.d.ts
type MockCallHistoryLogProperties (line 5) | type MockCallHistoryLogProperties = 'protocol' | 'host' | 'port' | 'orig...
class MockCallHistoryLog (line 9) | class MockCallHistoryLog {
type FilterCallsOperator (line 42) | type FilterCallsOperator = 'AND' | 'OR'
type FilterCallsOptions (line 45) | interface FilterCallsOptions {
type FilterCallsFunctionCriteria (line 50) | type FilterCallsFunctionCriteria = (log: MockCallHistoryLog) => boolean
type FilterCallsParameter (line 53) | type FilterCallsParameter = string | RegExp | undefined | null
type FilterCallsObjectCriteria (line 56) | interface FilterCallsObjectCriteria extends Record<string, FilterCallsPa...
class MockCallHistory (line 77) | class MockCallHistory {
FILE: types/mock-client.d.ts
class MockClient (line 9) | class MockClient extends Client implements Interceptable {
type Options (line 23) | interface Options extends Client.Options {
FILE: types/mock-errors.d.ts
class MockNotMatchedError (line 7) | class MockNotMatchedError extends Errors.UndiciError {
FILE: types/mock-interceptor.d.ts
class MockScope (line 6) | class MockScope<TData extends object = object> {
class MockInterceptor (line 17) | class MockInterceptor {
type Options (line 38) | interface Options {
type MockDispatch (line 50) | interface MockDispatch<TData extends object = object, TError extends Err...
type MockDispatchData (line 56) | interface MockDispatchData<TData extends object = object, TError extends...
type MockResponseOptions (line 61) | interface MockResponseOptions {
type MockResponseCallbackOptions (line 66) | interface MockResponseCallbackOptions {
type MockResponseDataHandler (line 74) | type MockResponseDataHandler<TData extends object = object> = (
type MockReplyOptionsCallback (line 78) | type MockReplyOptionsCallback<TData extends object = object> = (
type Interceptable (line 83) | interface Interceptable extends Dispatcher {
FILE: types/mock-pool.d.ts
class MockPool (line 9) | class MockPool extends Pool implements Interceptable {
type Options (line 23) | interface Options extends Pool.Options {
FILE: types/patch.d.ts
type EventInit (line 5) | interface EventInit {
type EventListenerOptions (line 11) | interface EventListenerOptions {
type AddEventListenerOptions (line 15) | interface AddEventListenerOptions extends EventListenerOptions {
type EventListenerOrEventListenerObject (line 21) | type EventListenerOrEventListenerObject = EventListener | EventListenerO...
type EventListenerObject (line 23) | interface EventListenerObject {
type EventListener (line 27) | interface EventListener {
FILE: types/pool-stats.d.ts
class PoolStats (line 5) | class PoolStats {
FILE: types/pool.d.ts
type PoolConnectOptions (line 8) | type PoolConnectOptions = Omit<Dispatcher.ConnectOptions, 'origin'>
class Pool (line 10) | class Pool extends Dispatcher {
type PoolStats (line 30) | type PoolStats = TPoolStats
type Options (line 31) | interface Options extends Client.Options {
FILE: types/proxy-agent.d.ts
class ProxyAgent (line 8) | class ProxyAgent extends Dispatcher {
type Options (line 16) | interface Options extends Agent.Options {
FILE: types/readable.d.ts
class BodyReadable (line 6) | class BodyReadable extends Readable {
FILE: types/retry-agent.d.ts
class RetryAgent (line 6) | class RetryAgent extends Dispatcher {
FILE: types/retry-handler.d.ts
class RetryHandler (line 5) | class RetryHandler implements Dispatcher.DispatchHandler {
type RetryState (line 15) | type RetryState = { counter: number; }
type RetryContext (line 17) | type RetryContext = {
type OnRetryCallback (line 24) | type OnRetryCallback = (result?: Error | null) => void
type RetryCallback (line 26) | type RetryCallback = (
type RetryOptions (line 37) | interface RetryOptions {
type RetryHandlers (line 121) | interface RetryHandlers {
FILE: types/round-robin-pool.d.ts
type RoundRobinPoolConnectOptions (line 8) | type RoundRobinPoolConnectOptions = Omit<Dispatcher.ConnectOptions, 'ori...
class RoundRobinPool (line 10) | class RoundRobinPool extends Dispatcher {
type RoundRobinPoolStats (line 30) | type RoundRobinPoolStats = TPoolStats
type Options (line 31) | interface Options extends Client.Options {
FILE: types/snapshot-agent.d.ts
class SnapshotRecorder (line 3) | class SnapshotRecorder {
type SnapshotRecorderMode (line 21) | type SnapshotRecorderMode = 'record' | 'playback' | 'update'
type Options (line 23) | interface Options {
type Snapshot (line 40) | interface Snapshot {
type SnapshotInfo (line 57) | interface SnapshotInfo {
type SnapshotData (line 70) | interface SnapshotData {
class SnapshotAgent (line 76) | class SnapshotAgent extends MockAgent {
type Options (line 91) | interface Options extends MockAgent.Options {
FILE: types/socks5-proxy-agent.d.ts
class Socks5ProxyAgent (line 8) | class Socks5ProxyAgent extends Dispatcher {
type Options (line 13) | interface Options extends Pool.Options {
FILE: types/utility.d.ts
type AutocompletePrimitiveBaseType (line 1) | type AutocompletePrimitiveBaseType<T> =
type Autocomplete (line 7) | type Autocomplete<T> = T | (AutocompletePrimitiveBaseType<T> & Record<ne...
FILE: types/webidl.d.ts
type Converter (line 8) | type Converter<T> = (object: unknown) => T
type SequenceConverter (line 10) | type SequenceConverter<T> = (object: unknown, iterable?: IterableIterato...
type RecordConverter (line 12) | type RecordConverter<K extends string, V> = (object: unknown) => Record<...
type WebidlErrors (line 14) | interface WebidlErrors {
type WebIDLTypes (line 37) | interface WebIDLTypes {
type WebidlUtil (line 48) | interface WebidlUtil {
type WebidlConverters (line 104) | interface WebidlConverters {
type WebidlIsFunction (line 247) | type WebidlIsFunction<T> = (arg: any) => arg is T
type WebidlIs (line 249) | interface WebidlIs {
type Webidl (line 268) | interface Webidl {
type WebIDLExtendedAttributes (line 336) | interface WebIDLExtendedAttributes {
FILE: types/websocket.d.ts
type BinaryType (line 15) | type BinaryType = 'blob' | 'arraybuffer'
type WebSocketEventMap (line 17) | interface WebSocketEventMap {
type WebSocket (line 24) | interface WebSocket extends EventTarget {
type CloseEventInit (line 78) | interface CloseEventInit extends EventInit {
type CloseEvent (line 84) | interface CloseEvent extends Event {
type MessageEventInit (line 95) | interface MessageEventInit<T = any> extends EventInit {
type MessageEvent (line 103) | interface MessageEvent<T = any> extends Event {
type ErrorEventInit (line 126) | interface ErrorEventInit extends EventInit {
type ErrorEvent (line 134) | interface ErrorEvent extends Event {
type WebSocketInit (line 147) | interface WebSocketInit {
type WebSocketStreamOptions (line 153) | interface WebSocketStreamOptions {
type WebSocketCloseInfo (line 158) | interface WebSocketCloseInfo {
type WebSocketStream (line 163) | interface WebSocketStream {
type WebSocketError (line 181) | interface WebSocketError extends Event, WebSocketCloseInfo {}
Condensed preview — 733 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,400K chars).
[
{
"path": ".c8rc.json",
"chars": 148,
"preview": "{\n \"all\": true,\n \"reporter\": [\n \"lcov\",\n \"text\",\n \"html\",\n \"text-summary\"\n ],\n \"include\": [\n \"lib/**/"
},
{
"path": ".dockerignore",
"chars": 174,
"preview": "# Ignore everything but the stuff following the `*` with the `!`\n# See https://docs.docker.com/engine/reference/builder/"
},
{
"path": ".editorconfig",
"chars": 143,
"preview": "# https://editorconfig.org/\n\nroot = true\n\n[*]\nindent_size = 2\nindent_style = space\ninsert_final_newline = true\ntrim_trai"
},
{
"path": ".github/ISSUE_TEMPLATE/bug-report.md",
"chars": 697,
"preview": "---\nname: Bug Report\nabout: Report an issue\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n## Bug Description\n\n<!-- A clear a"
},
{
"path": ".github/ISSUE_TEMPLATE/feature-request.md",
"chars": 655,
"preview": "---\nname: Feature Request\nabout: Make a suggestion on a feature or improvement for the project\ntitle: ''\nlabels: enhance"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 1428,
"preview": "<!--\nBefore submitting a Pull Request, please read our contribution guidelines, which\ncan be found at CONTRIBUTING.md in"
},
{
"path": ".github/dependabot.yml",
"chars": 614,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: \"monthly\"\n "
},
{
"path": ".github/workflows/autobahn.yml",
"chars": 1651,
"preview": "name: Autobahn\n\non:\n workflow_dispatch:\n workflow_call:\n inputs:\n node-version:\n default: '24'\n "
},
{
"path": ".github/workflows/backport.yml",
"chars": 649,
"preview": "name: Backport\non:\n pull_request_target:\n types:\n - closed\n - labeled\n\njobs:\n backport:\n name: Backpor"
},
{
"path": ".github/workflows/bench.yml",
"chars": 4494,
"preview": "name: Benchmarks\n\non:\n push:\n branches:\n - main\n - current\n - next\n - 'v*'\n pull_request:\n\npermissi"
},
{
"path": ".github/workflows/ci.yml",
"chars": 10706,
"preview": "name: CI\n\non:\n push:\n branches:\n - main\n - current\n - next\n - 'v*'\n pull_request:\n\npermissions:\n c"
},
{
"path": ".github/workflows/codeql.yml",
"chars": 2946,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/nodejs-nightly.yml",
"chars": 2222,
"preview": "name: Node.js Nightly\n\non:\n workflow_dispatch:\n schedule:\n - cron: \"0 10 * * *\"\n\npermissions:\n contents: read\n\njob"
},
{
"path": ".github/workflows/nodejs-shared.yml",
"chars": 4027,
"preview": "name: Node.js compiled --shared-builtin-undici/undici-path CI\n\non:\n workflow_call:\n inputs:\n node-version:\n "
},
{
"path": ".github/workflows/nodejs.yml",
"chars": 6815,
"preview": "name: Node.js\n\non:\n workflow_call:\n inputs:\n node-version:\n required: true\n type: string\n ru"
},
{
"path": ".github/workflows/release-create-pr.yml",
"chars": 2080,
"preview": "name: Create release PR\n\npermissions:\n contents: read\n\non:\n workflow_dispatch:\n inputs:\n version:\n desc"
},
{
"path": ".github/workflows/release.yml",
"chars": 3036,
"preview": "name: Release undici and undici-types on NPM and create GitHub Release\n\non:\n push:\n branches:\n - main\n paths:"
},
{
"path": ".github/workflows/scorecard.yml",
"chars": 2017,
"preview": "# This workflow uses actions that are not certified by GitHub. They are provided\n# by a third-party and are governed by "
},
{
"path": ".github/workflows/triggered-autobahn.yml",
"chars": 210,
"preview": "name: Autobahn\n\non:\n pull_request:\n types:\n - labeled\n \njobs:\n autobahn:\n if: ${{ github.event.label.name "
},
{
"path": ".github/workflows/update-submodules.yml",
"chars": 1876,
"preview": "name: Update Submodules\n\non:\n workflow_dispatch:\n schedule:\n - cron: '0 0 * * *'\n\njobs:\n update-wpt:\n name: Upd"
},
{
"path": ".gitignore",
"chars": 1344,
"preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directo"
},
{
"path": ".gitmodules",
"chars": 254,
"preview": "[submodule \"test/web-platform-tests/wpt\"]\n\tpath = test/web-platform-tests/wpt\n\turl = https://github.com/web-platform-tes"
},
{
"path": ".husky/pre-commit",
"chars": 13,
"preview": "npm run lint\n"
},
{
"path": ".npmignore",
"chars": 311,
"preview": "*\n!lib/**/*\n!index.js\n!index-fetch.js\n\n# The wasm files are stored as base64 strings in the corresponding .js files\nlib/"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 196,
"preview": "# Code of Conduct\n\nUndici is committed to upholding the Node.js Code of Conduct.\n\nThe Node.js Code of Conduct document c"
},
{
"path": "CONTRIBUTING.md",
"chars": 6040,
"preview": "# Contributing to Undici\n\n* [Guides](#guides)\n * [Update `llhttp`](#update-llhttp)\n * [Lint](#lint)\n * [Test](#test)\n"
},
{
"path": "GOVERNANCE.md",
"chars": 5544,
"preview": "### Undici Working Group\n\nThe Node.js Undici project is governed by a Working Group (WG)\nthat is responsible for high-le"
},
{
"path": "LICENSE",
"chars": 1090,
"preview": "MIT License\n\nCopyright (c) Matteo Collina and Undici contributors\n\nPermission is hereby granted, free of charge, to any "
},
{
"path": "MAINTAINERS.md",
"chars": 2370,
"preview": "# Maintainers\n\nThis document details any and all processes relevant to project maintainers. Maintainers should feel empo"
},
{
"path": "README.md",
"chars": 26244,
"preview": "# undici\n\n[](https://github.com/nodejs/un"
},
{
"path": "SECURITY.md",
"chars": 152,
"preview": "If you believe you have found a security issue in the software in this\nrepository, please consult https://github.com/nod"
},
{
"path": "benchmarks/_util/index.js",
"chars": 1963,
"preview": "'use strict'\n\nconst parallelRequests = parseInt(process.env.PARALLEL, 10) || 100\n\nfunction makeParallelRequests (cb) {\n "
},
{
"path": "benchmarks/_util/runner.js",
"chars": 3289,
"preview": "// @ts-check\n\n'use strict'\n\nclass Info {\n /** @type {string} */\n #name\n /** @type {bigint} */\n #current\n /** @type "
},
{
"path": "benchmarks/benchmark-http2.js",
"chars": 6790,
"preview": "'use strict'\n\nconst os = require('node:os')\nconst path = require('node:path')\nconst http2 = require('node:http2')\nconst "
},
{
"path": "benchmarks/benchmark-https.js",
"chars": 6676,
"preview": "'use strict'\n\nconst https = require('node:https')\nconst os = require('node:os')\nconst path = require('node:path')\nconst "
},
{
"path": "benchmarks/benchmark.js",
"chars": 7582,
"preview": "'use strict'\n\nconst http = require('node:http')\nconst os = require('node:os')\nconst path = require('node:path')\nconst { "
},
{
"path": "benchmarks/cache/date.mjs",
"chars": 1875,
"preview": "'use strict'\n\nimport { group, bench, run } from 'mitata'\nimport { parseHttpDate } from '../../lib/util/date.js'\n\nconst D"
},
{
"path": "benchmarks/cache/get-field-values.mjs",
"chars": 411,
"preview": "import { bench, group, run } from 'mitata'\nimport { getFieldValues } from '../../lib/web/cache/util.js'\n\nconst values = "
},
{
"path": "benchmarks/cookies/is-ctl-excluding-htab.mjs",
"chars": 441,
"preview": "import { bench, group, run } from 'mitata'\nimport { isCTLExcludingHtab } from '../../lib/web/cookies/util.js'\n\nconst val"
},
{
"path": "benchmarks/cookies/to-imf-date.mjs",
"chars": 240,
"preview": "import { bench, group, run } from 'mitata'\nimport { toIMFDate } from '../../lib/web/cookies/util.js'\n\nconst date = new D"
},
{
"path": "benchmarks/cookies/validate-cookie-name.mjs",
"chars": 261,
"preview": "import { bench, group, run } from 'mitata'\nimport { validateCookieName } from '../../lib/web/cookies/util.js'\n\nconst val"
},
{
"path": "benchmarks/cookies/validate-cookie-value.mjs",
"chars": 390,
"preview": "import { bench, group, run } from 'mitata'\nimport { validateCookieValue } from '../../lib/web/cookies/util.js'\n\nconst va"
},
{
"path": "benchmarks/core/is-blob-like.mjs",
"chars": 1266,
"preview": "import { bench, group, run } from 'mitata'\nimport { isBlobLike } from '../../lib/core/util.js'\n\nconst buffer = Buffer.al"
},
{
"path": "benchmarks/core/is-valid-header-char.mjs",
"chars": 1489,
"preview": "import { bench, group, run } from 'mitata'\nimport { isValidHeaderChar } from '../../lib/core/util.js'\n\nconst html = 'tex"
},
{
"path": "benchmarks/core/is-valid-port.mjs",
"chars": 309,
"preview": "import { bench, group, run } from 'mitata'\nimport { isValidPort } from '../../lib/core/util.js'\n\nconst string = '1234'\nc"
},
{
"path": "benchmarks/core/parse-headers.mjs",
"chars": 2819,
"preview": "import { bench, group, run } from 'mitata'\nimport { parseHeaders } from '../../lib/core/util.js'\n\nconst target = [\n {\n "
},
{
"path": "benchmarks/core/parse-raw-headers.mjs",
"chars": 843,
"preview": "import { bench, group, run } from 'mitata'\nimport { parseRawHeaders } from '../../lib/core/util.js'\n\nconst rawHeadersMix"
},
{
"path": "benchmarks/core/request-instantiation.mjs",
"chars": 338,
"preview": "import { bench, run } from 'mitata'\n\nimport Request from '../../lib/core/request.js'\nimport DecoratorHandler from '../.."
},
{
"path": "benchmarks/core/tree.mjs",
"chars": 566,
"preview": "import { bench, group, run } from 'mitata'\nimport { tree } from '../../lib/core/tree.js'\n\nconst contentLength = Buffer.f"
},
{
"path": "benchmarks/fetch/body-arraybuffer.mjs",
"chars": 608,
"preview": "import { group, bench, run } from 'mitata'\nimport { Response } from '../../lib/web/fetch/response.js'\n\nconst settings = "
},
{
"path": "benchmarks/fetch/bytes-match.mjs",
"chars": 954,
"preview": "import { createHash } from 'node:crypto'\nimport { bench, run } from 'mitata'\nimport { bytesMatch } from '../../lib/web/f"
},
{
"path": "benchmarks/fetch/headers-length32.mjs",
"chars": 1128,
"preview": "import { bench, run } from 'mitata'\nimport { Headers, getHeadersList } from '../../lib/web/fetch/headers.js'\n\nconst head"
},
{
"path": "benchmarks/fetch/headers.mjs",
"chars": 1435,
"preview": "import { bench, group, run } from 'mitata'\nimport { Headers, getHeadersList } from '../../lib/web/fetch/headers.js'\n\ncon"
},
{
"path": "benchmarks/fetch/is-valid-encoded-url.mjs",
"chars": 351,
"preview": "import { bench, run } from 'mitata'\nimport { isValidEncodedURL } from '../../lib/web/fetch/util.js'\n\nconst validUrl = 'h"
},
{
"path": "benchmarks/fetch/is-valid-header-value.mjs",
"chars": 1152,
"preview": "import { bench, run } from 'mitata'\nimport { isValidHeaderValue } from '../../lib/web/fetch/util.js'\n\nconst valid = 'val"
},
{
"path": "benchmarks/fetch/isomorphic-encode.mjs",
"chars": 1680,
"preview": "import { bench, group, run } from 'mitata'\nimport { isomorphicEncode } from '../../lib/web/fetch/util.js'\n\nconst charact"
},
{
"path": "benchmarks/fetch/request-creation.mjs",
"chars": 214,
"preview": "import { bench, run } from 'mitata'\nimport { Request } from '../../lib/web/fetch/request.js'\n\nconst input = 'https://exa"
},
{
"path": "benchmarks/fetch/url-has-https-scheme.mjs",
"chars": 625,
"preview": "import { bench, run } from 'mitata'\nimport { urlHasHttpsScheme } from '../../lib/web/fetch/util.js'\n\nconst httpString = "
},
{
"path": "benchmarks/package.json",
"chars": 1048,
"preview": "{\n \"name\": \"benchmarks\",\n \"scripts\": {\n \"bench\": \"PORT=3042 concurrently -k -s first npm:bench:server npm:bench:run"
},
{
"path": "benchmarks/post-benchmark.js",
"chars": 8535,
"preview": "'use strict'\n\nconst http = require('node:http')\nconst os = require('node:os')\nconst path = require('node:path')\nconst { "
},
{
"path": "benchmarks/server-http2.js",
"chars": 1330,
"preview": "'use strict'\n\nconst { unlinkSync, readFileSync } = require('node:fs')\nconst { createSecureServer } = require('node:http2"
},
{
"path": "benchmarks/server-https.js",
"chars": 1062,
"preview": "'use strict'\n\nconst { unlinkSync, readFileSync } = require('node:fs')\nconst { createServer } = require('node:https')\ncon"
},
{
"path": "benchmarks/server.js",
"chars": 1099,
"preview": "'use strict'\n\nconst { unlinkSync } = require('node:fs')\nconst { createServer } = require('node:http')\nconst os = require"
},
{
"path": "benchmarks/timers/compare-timer-getters.mjs",
"chars": 348,
"preview": "import { bench, group, run } from 'mitata'\n\ngroup('timers', () => {\n bench('Date.now()', () => {\n Date.now()\n })\n "
},
{
"path": "benchmarks/utils/date.mjs",
"chars": 774,
"preview": "import { Bench } from 'tinybench'\n\nimport { parseHttpDate } from '../../lib/util/date.js'\n\nconst asctime = 'Sun Nov 6 0"
},
{
"path": "benchmarks/wait.js",
"chars": 436,
"preview": "'use strict'\n\nconst os = require('node:os')\nconst path = require('node:path')\nconst waitOn = require('wait-on')\n\nconst s"
},
{
"path": "benchmarks/webidl/webidl-is.mjs",
"chars": 572,
"preview": "import { bench, run, barplot } from 'mitata'\nimport { Headers, FormData } from '../../index.js'\nimport { webidl } from '"
},
{
"path": "benchmarks/websocket/generate-mask.mjs",
"chars": 285,
"preview": "import { randomBytes } from 'node:crypto'\nimport { bench, summary, run } from 'mitata'\nimport { generateMask } from '../"
},
{
"path": "benchmarks/websocket/is-valid-subprotocol.mjs",
"chars": 376,
"preview": "import { bench, group, run } from 'mitata'\nimport { isValidSubprotocol } from '../../lib/web/websocket/util.js'\n\nconst v"
},
{
"path": "benchmarks/websocket/messageevent.mjs",
"chars": 716,
"preview": "import { bench, group, run } from 'mitata'\nimport { createFastMessageEvent, MessageEvent as UndiciMessageEvent } from '."
},
{
"path": "benchmarks/websocket-benchmark.mjs",
"chars": 4852,
"preview": "// @ts-check\n\nimport { bench } from './_util/runner.js'\nimport { formatBytes } from './_util/index.js'\nimport { WebSocke"
},
{
"path": "benchmarks/websocket-echo-server.mjs",
"chars": 1241,
"preview": "import { Worker, isMainThread, parentPort, threadId } from 'node:worker_threads'\nimport { cpus } from 'node:os'\nimport u"
},
{
"path": "build/wasm.js",
"chars": 4634,
"preview": "'use strict'\n\nconst WASM_BUILDER_CONTAINER = 'ghcr.io/nodejs/wasm-builder@sha256:975f391d907e42a75b8c72eb77c782181e94160"
},
{
"path": "deps/llhttp/include/llhttp.h",
"chars": 30650,
"preview": "\n#ifndef INCLUDE_LLHTTP_H_\n#define INCLUDE_LLHTTP_H_\n\n#define LLHTTP_VERSION_MAJOR 9\n#define LLHTTP_VERSION_MINOR 3\n#def"
},
{
"path": "deps/llhttp/src/api.c",
"chars": 13152,
"preview": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"llhttp.h\"\n\n#define CALLBACK_MAYBE(PARSER, NAME) "
},
{
"path": "deps/llhttp/src/http.c",
"chars": 5209,
"preview": "#include <stdio.h>\n#ifndef LLHTTP__TEST\n# include \"llhttp.h\"\n#else\n# define llhttp_t llparse_t\n#endif /* */\n\nint llhttp"
},
{
"path": "deps/llhttp/src/llhttp.c",
"chars": 315697,
"preview": "#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n\n#ifdef __SSE4_2__\n #ifdef _MSC_VER\n #include <nmmintrin.h>"
},
{
"path": "docs/.nojekyll",
"chars": 0,
"preview": ""
},
{
"path": "docs/CNAME",
"chars": 17,
"preview": "undici.nodejs.org"
},
{
"path": "docs/docs/api/Agent.md",
"chars": 2938,
"preview": "# Agent\n\nExtends: `undici.Dispatcher`\n\nAgent allows dispatching requests against multiple different origins.\n\nRequests a"
},
{
"path": "docs/docs/api/BalancedPool.md",
"chars": 3057,
"preview": "# Class: BalancedPool\n\nExtends: `undici.Dispatcher`\n\nA pool of [Pool](/docs/docs/api/Pool.md) instances connected to mul"
},
{
"path": "docs/docs/api/CacheStorage.md",
"chars": 1078,
"preview": "# CacheStorage\n\nUndici exposes a W3C spec-compliant implementation of [CacheStorage](https://developer.mozilla.org/en-US"
},
{
"path": "docs/docs/api/CacheStore.md",
"chars": 5472,
"preview": "# Cache Store\n\nA Cache Store is responsible for storing and retrieving cached responses.\nIt is also responsible for deci"
},
{
"path": "docs/docs/api/Client.md",
"chars": 13020,
"preview": "# Class: Client\n\nExtends: `undici.Dispatcher`\n\nA basic HTTP/1.1 client, mapped on top a single TCP/TLS connection. Pipel"
},
{
"path": "docs/docs/api/ClientStats.md",
"chars": 522,
"preview": "# Class: ClientStats\n\nStats for a [Client](/docs/docs/api/Client.md).\n\n## `new ClientStats(client)`\n\nArguments:\n\n* **cli"
},
{
"path": "docs/docs/api/Connector.md",
"chars": 3464,
"preview": "# Connector\n\nUndici creates the underlying socket via the connector builder.\nNormally, this happens automatically and yo"
},
{
"path": "docs/docs/api/ContentType.md",
"chars": 1130,
"preview": "# MIME Type Parsing\n\n## `MIMEType` interface\n\n* **type** `string`\n* **subtype** `string`\n* **parameters** `Map<string, s"
},
{
"path": "docs/docs/api/Cookies.md",
"chars": 2043,
"preview": "# Cookie Handling\n\n## `Cookie` interface\n\n* **name** `string`\n* **value** `string`\n* **expires** `Date|number` (optional"
},
{
"path": "docs/docs/api/Debug.md",
"chars": 2283,
"preview": "# Debug\n\nUndici (and subsenquently `fetch` and `websocket`) exposes a debug statement that can be enabled by setting `NO"
},
{
"path": "docs/docs/api/DiagnosticsChannel.md",
"chars": 10653,
"preview": "# Diagnostics Channel Support\n\nStability: Experimental.\n\nUndici supports the [`diagnostics_channel`](https://nodejs.org/"
},
{
"path": "docs/docs/api/Dispatcher.md",
"chars": 45551,
"preview": "# Dispatcher\n\nExtends: `events.EventEmitter`\n\nDispatcher is the core API used to dispatch requests.\n\nRequests are not gu"
},
{
"path": "docs/docs/api/EnvHttpProxyAgent.md",
"chars": 5825,
"preview": "# Class: EnvHttpProxyAgent\n\nExtends: `undici.Dispatcher`\n\nEnvHttpProxyAgent automatically reads the proxy configuration "
},
{
"path": "docs/docs/api/Errors.md",
"chars": 3991,
"preview": "# Errors\n\nUndici exposes a variety of error objects that you can use to enhance your error handling.\nYou can find all th"
},
{
"path": "docs/docs/api/EventSource.md",
"chars": 1232,
"preview": "# EventSource\n\n> ⚠️ Warning: the EventSource API is experimental.\n\nUndici exposes a WHATWG spec-compliant implementation"
},
{
"path": "docs/docs/api/Fetch.md",
"chars": 2124,
"preview": "# Fetch\n\nUndici exposes a fetch() method starts the process of fetching a resource from the network.\n\nDocumentation and "
},
{
"path": "docs/docs/api/GlobalInstallation.md",
"chars": 2779,
"preview": "# Global Installation\n\nUndici provides an `install()` function to add all WHATWG fetch classes to `globalThis`, making t"
},
{
"path": "docs/docs/api/H2CClient.md",
"chars": 10585,
"preview": "# Class: H2CClient\n\nExtends: `undici.Dispatcher`\n\nA basic H2C client.\n\n**Example**\n\n```js\nconst { createServer } = requi"
},
{
"path": "docs/docs/api/MockAgent.md",
"chars": 17223,
"preview": "# Class: MockAgent\n\nExtends: `undici.Dispatcher`\n\nA mocked Agent class that implements the Agent API. It allows one to i"
},
{
"path": "docs/docs/api/MockCallHistory.md",
"chars": 5632,
"preview": "# Class: MockCallHistory\n\nAccess to an instance with :\n\n```js\nconst mockAgent = new MockAgent({ enableCallHistory: true "
},
{
"path": "docs/docs/api/MockCallHistoryLog.md",
"chars": 1775,
"preview": "# Class: MockCallHistoryLog\n\nAccess to an instance with :\n\n```js\nconst mockAgent = new MockAgent({ enableCallHistory: tr"
},
{
"path": "docs/docs/api/MockClient.md",
"chars": 2213,
"preview": "# Class: MockClient\n\nExtends: `undici.Client`\n\nA mock client class that implements the same api as [MockPool](/docs/docs"
},
{
"path": "docs/docs/api/MockErrors.md",
"chars": 595,
"preview": "# MockErrors\n\nUndici exposes a variety of mock error objects that you can use to enhance your mock error handling.\nYou c"
},
{
"path": "docs/docs/api/MockPool.md",
"chars": 16582,
"preview": "# Class: MockPool\n\nExtends: `undici.Pool`\n\nA mock Pool class that implements the Pool API and is used by MockAgent to in"
},
{
"path": "docs/docs/api/Pool.md",
"chars": 2941,
"preview": "# Class: Pool\n\nExtends: `undici.Dispatcher`\n\nA pool of [Client](/docs/docs/api/Client.md) instances connected to the sam"
},
{
"path": "docs/docs/api/PoolStats.md",
"chars": 805,
"preview": "# Class: PoolStats\n\nAggregate stats for a [Pool](/docs/docs/api/Pool.md) or [BalancedPool](/docs/docs/api/BalancedPool.m"
},
{
"path": "docs/docs/api/ProxyAgent.md",
"chars": 8090,
"preview": "# Class: ProxyAgent\n\nExtends: `undici.Dispatcher`\n\nA Proxy Agent class that implements the Agent API. It allows the conn"
},
{
"path": "docs/docs/api/RedirectHandler.md",
"chars": 3205,
"preview": "# Class: RedirectHandler\n\nA class that handles redirection logic for HTTP requests.\n\n## `new RedirectHandler(dispatch, m"
},
{
"path": "docs/docs/api/RetryAgent.md",
"chars": 2262,
"preview": "# Class: RetryAgent\n\nExtends: `undici.Dispatcher`\n\nA `undici.Dispatcher` that allows to automatically retry a request.\nW"
},
{
"path": "docs/docs/api/RetryHandler.md",
"chars": 4587,
"preview": "# Class: RetryHandler\n\nExtends: `undici.DispatcherHandlers`\n\nA handler class that implements the retry logic for a reque"
},
{
"path": "docs/docs/api/RoundRobinPool.md",
"chars": 6093,
"preview": "# Class: RoundRobinPool\n\nExtends: `undici.Dispatcher`\n\nA pool of [Client](/docs/docs/api/Client.md) instances connected "
},
{
"path": "docs/docs/api/SnapshotAgent.md",
"chars": 16047,
"preview": "# SnapshotAgent\n\nThe `SnapshotAgent` provides a powerful way to record and replay HTTP requests for testing purposes. It"
},
{
"path": "docs/docs/api/Socks5ProxyAgent.md",
"chars": 8534,
"preview": "# Class: Socks5ProxyAgent\n\nExtends: `undici.Dispatcher`\n\nA SOCKS5 proxy wrapper class that implements the Dispatcher API"
},
{
"path": "docs/docs/api/Util.md",
"chars": 732,
"preview": "# Util\n\nUtility API for third-party implementations of the dispatcher API.\n\n## `parseHeaders(headers, [obj])`\n\nReceives "
},
{
"path": "docs/docs/api/WebSocket.md",
"chars": 4335,
"preview": "# Class: WebSocket\n\nExtends: [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget)\n\nThe WebSocke"
},
{
"path": "docs/docs/api/api-lifecycle.md",
"chars": 8283,
"preview": "# Client Lifecycle\n\nAn Undici [Client](/docs/docs/api/Client.md) can be best described as a state machine. The following"
},
{
"path": "docs/docs/best-practices/client-certificate.md",
"chars": 2053,
"preview": "# Client certificate\n\nClient certificate authentication can be configured with the `Client`, the required options are pa"
},
{
"path": "docs/docs/best-practices/crawling.md",
"chars": 3142,
"preview": "# Crawling\n\n[RFC 9309](https://datatracker.ietf.org/doc/html/rfc9309) defines crawlers as automated clients.\n\nSome web s"
},
{
"path": "docs/docs/best-practices/mocking-request.md",
"chars": 5557,
"preview": "# Mocking Request\n\nUndici has its own mocking [utility](/docs/docs/api/MockAgent.md). It allow us to intercept undici HT"
},
{
"path": "docs/docs/best-practices/proxy.md",
"chars": 3336,
"preview": "# Connecting through a proxy\n\nConnecting through a proxy is possible by:\n\n- Using [ProxyAgent](/docs/docs/api/ProxyAgent"
},
{
"path": "docs/docs/best-practices/undici-vs-builtin-fetch.md",
"chars": 4871,
"preview": "# Undici Module vs. Node.js Built-in Fetch\n\nNode.js has shipped a built-in `fetch()` implementation powered by undici si"
},
{
"path": "docs/docs/best-practices/writing-tests.md",
"chars": 2218,
"preview": "# Writing tests\n\nUndici is tuned for a production use case and its default will keep\na socket open for a few seconds aft"
},
{
"path": "docs/docsify/sidebar.md",
"chars": 3174,
"preview": "<!-- Sidebar for Docsify -->\n\n* [**Home**](/ \"Node.js Undici\")\n* API\n * [Dispatcher](/docs/api/Dispatcher.md \"Undici AP"
},
{
"path": "docs/examples/README.md",
"chars": 5954,
"preview": "\n## undici.request() examples\n\n### A simple GET request, read the response body as text:\n```js\nconst { request } = requi"
},
{
"path": "docs/examples/ca-fingerprint/index.js",
"chars": 2187,
"preview": "'use strict'\n\nconst crypto = require('node:crypto')\nconst https = require('node:https')\nconst { Client, buildConnector }"
},
{
"path": "docs/examples/eventsource.js",
"chars": 555,
"preview": "'use strict'\n\nconst { randomBytes } = require('node:crypto')\nconst { EventSource } = require('../../')\n\nasync function m"
},
{
"path": "docs/examples/fetch.js",
"chars": 283,
"preview": "'use strict'\n\nconst { fetch } = require('../../')\n\nasync function main () {\n const res = await fetch('http://localhost:"
},
{
"path": "docs/examples/proxy/fetch.mjs",
"chars": 1049,
"preview": "import * as http from 'node:http'\nimport { once } from 'node:events'\nimport { createProxy } from 'proxy'\nimport { fetch,"
},
{
"path": "docs/examples/proxy/index.js",
"chars": 1116,
"preview": "'use strict'\n\nconst { Pool, Client } = require('../../../')\nconst http = require('node:http')\nconst proxy = require('./p"
},
{
"path": "docs/examples/proxy/proxy.js",
"chars": 6684,
"preview": "'use strict'\n\nconst net = require('node:net')\nconst { pipeline } = require('node:stream')\nconst { STATUS_CODES } = requi"
},
{
"path": "docs/examples/proxy/websocket.js",
"chars": 2167,
"preview": "'use strict'\n\nconst { Pool, Client } = require('../../../')\nconst http = require('node:http')\nconst proxy = require('./p"
},
{
"path": "docs/examples/proxy-agent.js",
"chars": 551,
"preview": "'use strict'\n\nconst { request, setGlobalDispatcher, ProxyAgent } = require('../..')\n\nsetGlobalDispatcher(new ProxyAgent("
},
{
"path": "docs/examples/request.js",
"chars": 2300,
"preview": "'use strict'\n\nconst { request } = require('../../')\n\nasync function getRequest (port = 3001) {\n // A simple GET request"
},
{
"path": "docs/examples/snapshot-testing.js",
"chars": 3228,
"preview": "const { SnapshotAgent, setGlobalDispatcher, getGlobalDispatcher, request } = require('../../index.js')\nconst { createSer"
},
{
"path": "docs/examples/socks5-proxy.js",
"chars": 5817,
"preview": "'use strict'\n\nconst { Socks5Agent, request, fetch } = require('undici')\n\n// Basic example demonstrating SOCKS5 proxy usa"
},
{
"path": "docs/index.html",
"chars": 4285,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"UTF-8\">\n <title>Node.js Undici</title>\n <meta http-equiv=\"X-"
},
{
"path": "docs/package.json",
"chars": 226,
"preview": "{\n \"private\": true,\n \"name\": \"@undici/documentation\",\n \"description\": \"Documentation site for the `undici` package.\","
},
{
"path": "eslint.config.js",
"chars": 868,
"preview": "'use strict'\n\nconst neo = require('neostandard')\nconst { installedExports } = require('./lib/global')\n\nmodule.exports = "
},
{
"path": "index-fetch.js",
"chars": 2480,
"preview": "'use strict'\n\nconst { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global')\nconst EnvHttpProxyAgent = req"
},
{
"path": "index.d.ts",
"chars": 87,
"preview": "import Undici from './types/index'\nexport default Undici\nexport * from './types/index'\n"
},
{
"path": "index.js",
"chars": 8447,
"preview": "'use strict'\n\nconst Client = require('./lib/dispatcher/client')\nconst Dispatcher = require('./lib/dispatcher/dispatcher'"
},
{
"path": "lib/api/abort-signal.js",
"chars": 1071,
"preview": "'use strict'\n\nconst { addAbortListener } = require('../core/util')\nconst { RequestAbortedError } = require('../core/erro"
},
{
"path": "lib/api/api-connect.js",
"chars": 2608,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst { AsyncResource } = require('node:async_hooks')\nconst { Invali"
},
{
"path": "lib/api/api-pipeline.js",
"chars": 5426,
"preview": "'use strict'\n\nconst {\n Readable,\n Duplex,\n PassThrough\n} = require('node:stream')\nconst assert = require('node:assert"
},
{
"path": "lib/api/api-request.js",
"chars": 5606,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst { AsyncResource } = require('node:async_hooks')\nconst { Readab"
},
{
"path": "lib/api/api-stream.js",
"chars": 4729,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst { finished } = require('node:stream')\nconst { AsyncResource } "
},
{
"path": "lib/api/api-upgrade.js",
"chars": 2718,
"preview": "'use strict'\n\nconst { InvalidArgumentError, SocketError } = require('../core/errors')\nconst { AsyncResource } = require("
},
{
"path": "lib/api/index.js",
"chars": 264,
"preview": "'use strict'\n\nmodule.exports.request = require('./api-request')\nmodule.exports.stream = require('./api-stream')\nmodule.e"
},
{
"path": "lib/api/readable.js",
"chars": 13662,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst { Readable } = require('node:stream')\nconst { RequestAbortedEr"
},
{
"path": "lib/cache/memory-cache-store.js",
"chars": 6745,
"preview": "'use strict'\n\nconst { Writable } = require('node:stream')\nconst { EventEmitter } = require('node:events')\nconst { assert"
},
{
"path": "lib/cache/sqlite-cache-store.js",
"chars": 11428,
"preview": "'use strict'\n\nconst { Writable } = require('node:stream')\nconst { assertCacheKey, assertCacheValue } = require('../util/"
},
{
"path": "lib/core/connect.js",
"chars": 4206,
"preview": "'use strict'\n\nconst net = require('node:net')\nconst assert = require('node:assert')\nconst util = require('./util')\nconst"
},
{
"path": "lib/core/constants.js",
"chars": 3260,
"preview": "'use strict'\n\n/**\n * @see https://developer.mozilla.org/docs/Web/HTTP/Headers\n */\nconst wellknownHeaderNames = /** @type"
},
{
"path": "lib/core/diagnostics.js",
"chars": 6496,
"preview": "'use strict'\n\nconst diagnosticsChannel = require('node:diagnostics_channel')\nconst util = require('node:util')\n\nconst un"
},
{
"path": "lib/core/errors.js",
"chars": 12802,
"preview": "'use strict'\n\nconst kUndiciError = Symbol.for('undici.error.UND_ERR')\nclass UndiciError extends Error {\n constructor (m"
},
{
"path": "lib/core/request.js",
"chars": 11721,
"preview": "'use strict'\n\nconst {\n InvalidArgumentError,\n NotSupportedError\n} = require('./errors')\nconst assert = require('node:a"
},
{
"path": "lib/core/socks5-client.js",
"chars": 11316,
"preview": "'use strict'\n\nconst { EventEmitter } = require('node:events')\nconst { Buffer } = require('node:buffer')\nconst { InvalidA"
},
{
"path": "lib/core/socks5-utils.js",
"chars": 5556,
"preview": "'use strict'\n\nconst { Buffer } = require('node:buffer')\nconst net = require('node:net')\nconst { InvalidArgumentError } ="
},
{
"path": "lib/core/symbols.js",
"chars": 2918,
"preview": "'use strict'\n\nmodule.exports = {\n kClose: Symbol('close'),\n kDestroy: Symbol('destroy'),\n kDispatch: Symbol('dispatch"
},
{
"path": "lib/core/tree.js",
"chars": 3582,
"preview": "'use strict'\n\nconst {\n wellknownHeaderNames,\n headerNameLowerCasedRecord\n} = require('./constants')\n\nclass TstNode {\n "
},
{
"path": "lib/core/util.js",
"chars": 25431,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst { kDestroyed, kBodyUsed, kListeners, kBody } = require('./symb"
},
{
"path": "lib/dispatcher/agent.js",
"chars": 4728,
"preview": "'use strict'\n\nconst { InvalidArgumentError, MaxOriginsReachedError } = require('../core/errors')\nconst { kClients, kRunn"
},
{
"path": "lib/dispatcher/balanced-pool.js",
"chars": 5715,
"preview": "'use strict'\n\nconst {\n BalancedPoolMissingUpstreamError,\n InvalidArgumentError\n} = require('../core/errors')\nconst {\n "
},
{
"path": "lib/dispatcher/client-h1.js",
"chars": 41468,
"preview": "'use strict'\n\n/* global WebAssembly */\n\nconst assert = require('node:assert')\nconst util = require('../core/util.js')\nco"
},
{
"path": "lib/dispatcher/client-h2.js",
"chars": 27712,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst { pipeline } = require('node:stream')\nconst util = require('.."
},
{
"path": "lib/dispatcher/client.js",
"chars": 18693,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst net = require('node:net')\nconst http = require('node:http')\nco"
},
{
"path": "lib/dispatcher/dispatcher-base.js",
"chars": 3696,
"preview": "'use strict'\n\nconst Dispatcher = require('./dispatcher')\nconst UnwrapHandler = require('../handler/unwrap-handler')\ncons"
},
{
"path": "lib/dispatcher/dispatcher.js",
"chars": 1288,
"preview": "'use strict'\nconst EventEmitter = require('node:events')\nconst WrapHandler = require('../handler/wrap-handler')\n\nconst w"
},
{
"path": "lib/dispatcher/env-http-proxy-agent.js",
"chars": 4343,
"preview": "'use strict'\n\nconst DispatcherBase = require('./dispatcher-base')\nconst { kClose, kDestroy, kClosed, kDestroyed, kDispat"
},
{
"path": "lib/dispatcher/fixed-queue.js",
"chars": 4615,
"preview": "'use strict'\n\n// Extracted from node/lib/internal/fixed_queue.js\n\n// Currently optimal queue size, tested on V8 6.0 - 6."
},
{
"path": "lib/dispatcher/h2c-client.js",
"chars": 1304,
"preview": "'use strict'\n\nconst { InvalidArgumentError } = require('../core/errors')\nconst Client = require('./client')\n\nclass H2CCl"
},
{
"path": "lib/dispatcher/pool-base.js",
"chars": 5013,
"preview": "'use strict'\n\nconst { PoolStats } = require('../util/stats.js')\nconst DispatcherBase = require('./dispatcher-base')\ncons"
},
{
"path": "lib/dispatcher/pool.js",
"chars": 3429,
"preview": "'use strict'\n\nconst {\n PoolBase,\n kClients,\n kNeedDrain,\n kAddClient,\n kGetDispatcher,\n kRemoveClient\n} = require("
},
{
"path": "lib/dispatcher/proxy-agent.js",
"chars": 9523,
"preview": "'use strict'\n\nconst { kProxy, kClose, kDestroy, kDispatch } = require('../core/symbols')\nconst Agent = require('./agent'"
},
{
"path": "lib/dispatcher/retry-agent.js",
"chars": 684,
"preview": "'use strict'\n\nconst Dispatcher = require('./dispatcher')\nconst RetryHandler = require('../handler/retry-handler')\n\nclass"
},
{
"path": "lib/dispatcher/round-robin-pool.js",
"chars": 3738,
"preview": "'use strict'\n\nconst {\n PoolBase,\n kClients,\n kNeedDrain,\n kAddClient,\n kGetDispatcher,\n kRemoveClient\n} = require("
},
{
"path": "lib/dispatcher/socks5-proxy-agent.js",
"chars": 7253,
"preview": "'use strict'\n\nconst net = require('node:net')\nconst { URL } = require('node:url')\n\nlet tls // include tls conditionally "
},
{
"path": "lib/encoding/index.js",
"chars": 791,
"preview": "'use strict'\n\nconst textDecoder = new TextDecoder()\n\n/**\n * @see https://encoding.spec.whatwg.org/#utf-8-decode\n * @para"
},
{
"path": "lib/global.js",
"chars": 1249,
"preview": "'use strict'\n\n// We include a version number for the Dispatcher API. In case of breaking changes,\n// this version number"
},
{
"path": "lib/handler/cache-handler.js",
"chars": 17705,
"preview": "'use strict'\n\nconst util = require('../core/util')\nconst {\n parseCacheControlHeader,\n parseVaryHeader,\n isEtagUsable\n"
},
{
"path": "lib/handler/cache-revalidation-handler.js",
"chars": 3165,
"preview": "'use strict'\n\nconst assert = require('node:assert')\n\n/**\n * This takes care of revalidation requests we send to the orig"
},
{
"path": "lib/handler/decorator-handler.js",
"chars": 1444,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst WrapHandler = require('./wrap-handler')\n\n/**\n * @deprecated\n *"
},
{
"path": "lib/handler/deduplication-handler.js",
"chars": 11502,
"preview": "'use strict'\n\nconst { RequestAbortedError } = require('../core/errors')\n\n/**\n * @typedef {import('../../types/dispatcher"
},
{
"path": "lib/handler/redirect-handler.js",
"chars": 8969,
"preview": "'use strict'\n\nconst util = require('../core/util')\nconst { kBodyUsed } = require('../core/symbols')\nconst assert = requi"
},
{
"path": "lib/handler/retry-handler.js",
"chars": 10897,
"preview": "'use strict'\nconst assert = require('node:assert')\n\nconst { kRetryHandlerDefaultRetry } = require('../core/symbols')\ncon"
},
{
"path": "lib/handler/unwrap-handler.js",
"chars": 2062,
"preview": "'use strict'\n\nconst { parseHeaders } = require('../core/util')\nconst { InvalidArgumentError } = require('../core/errors'"
},
{
"path": "lib/handler/wrap-handler.js",
"chars": 2576,
"preview": "'use strict'\n\nconst { InvalidArgumentError } = require('../core/errors')\n\nmodule.exports = class WrapHandler {\n #handle"
},
{
"path": "lib/interceptor/cache.js",
"chars": 14957,
"preview": "'use strict'\n\nconst assert = require('node:assert')\nconst { Readable } = require('node:stream')\nconst util = require('.."
},
{
"path": "lib/interceptor/decompress.js",
"chars": 8194,
"preview": "'use strict'\n\nconst { createInflate, createGunzip, createBrotliDecompress, createZstdDecompress } = require('node:zlib')"
},
{
"path": "lib/interceptor/deduplicate.js",
"chars": 4086,
"preview": "'use strict'\n\nconst diagnosticsChannel = require('node:diagnostics_channel')\nconst util = require('../core/util')\nconst "
},
{
"path": "lib/interceptor/dns.js",
"chars": 14181,
"preview": "'use strict'\nconst { isIP } = require('node:net')\nconst { lookup } = require('node:dns')\nconst DecoratorHandler = requir"
},
{
"path": "lib/interceptor/dump.js",
"chars": 2609,
"preview": "'use strict'\n\nconst { InvalidArgumentError, RequestAbortedError } = require('../core/errors')\nconst DecoratorHandler = r"
},
{
"path": "lib/interceptor/redirect.js",
"chars": 717,
"preview": "'use strict'\n\nconst RedirectHandler = require('../handler/redirect-handler')\n\nfunction createRedirectInterceptor ({ maxR"
},
{
"path": "lib/interceptor/response-error.js",
"chars": 2403,
"preview": "'use strict'\n\n// const { parseHeaders } = require('../core/util')\nconst DecoratorHandler = require('../handler/decorator"
},
{
"path": "lib/interceptor/retry.js",
"chars": 419,
"preview": "'use strict'\nconst RetryHandler = require('../handler/retry-handler')\n\nmodule.exports = globalOpts => {\n return dispatc"
},
{
"path": "lib/llhttp/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "lib/llhttp/constants.d.ts",
"chars": 4307,
"preview": "export type IntDict = Record<string, number>;\nexport declare const ERROR: IntDict;\nexport declare const TYPE: IntDict;\ne"
},
{
"path": "lib/llhttp/constants.js",
"chars": 17069,
"preview": "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SPECIAL_HEADERS = exports.MINOR = e"
},
{
"path": "lib/llhttp/llhttp-wasm.js",
"chars": 72279,
"preview": "'use strict'\n\nconst { Buffer } = require('node:buffer')\n\nconst wasmBase64 = 'AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAn9/AGABfwB"
},
{
"path": "lib/llhttp/llhttp_simd-wasm.js",
"chars": 72531,
"preview": "'use strict'\n\nconst { Buffer } = require('node:buffer')\n\nconst wasmBase64 = 'AGFzbQEAAAABJwdgAX8Bf2ADf39/AX9gAn9/AGABfwB"
},
{
"path": "lib/llhttp/utils.d.ts",
"chars": 162,
"preview": "import type { IntDict } from './constants';\nexport declare function enumToMap(obj: IntDict, filter?: readonly number[], "
}
]
// ... and 533 more files (download for full content)
About this extraction
This page contains the full source code of the nodejs/undici GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 733 files (5.8 MB), approximately 1.5M tokens, and a symbol index with 2729 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.