summaryrefslogtreecommitdiff
path: root/ext/fetch/20_headers.js
AgeCommit message (Collapse)Author
2024-09-04refactor(ext/fetch): align error messages (#25374)Ian Bull
Aligns the error messages in the ext/fetch folder to be in-line with the Deno style guide. https://github.com/denoland/deno/issues/25269
2024-05-23fix(runtime): use more null proto objects (#23921)Luca Casonato
This is a primordialization effort to improve resistance against users tampering with the global `Object` prototype. --------- Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
2024-01-10refactor: use `core.ensureFastOps()` (#21888)Kenta Moriuchi
2024-01-01chore: update copyright to 2024 (#21753)David Sherret
2023-12-07refactor: pull 'core', 'internals', 'primordials' from ES module (#21462)Bartek Iwańczuk
This commit refactors how we access "core", "internals" and "primordials" objects coming from `deno_core`, in our internal JavaScript code. Instead of capturing them from "globalThis.__bootstrap" namespace, we import them from recently added "ext:core/mod.js" file.
2023-11-19fix(ext,runtime): add missing custom inspections (#21219)Kenta Moriuchi
2023-10-10fix(ext/web): writability of `ReadableStream.from` (#20836)Luca Casonato
Fixes a WPT in `URL` and `ReadableStream`. Some unrelated WPT expectation changes due to WPT update.
2023-09-21perf(ext/fetch): use new instead of createBranded (#20624)Marcos Casagrande
This PR optimizes `fromInner*` methods of `Request` / `Header` / `Response` used by `Deno.serve` and `fetch` by using `new` instead of `ObjectCreate` from `createBranded`. The "brand" is created by passing `webidl.brand` to the constructor instead. https://github.com/denoland/deno/blob/142449ecab20006c5cfd15462814650596bc034d/ext/webidl/00_webidl.js#L1001-L1005 ### Benchmark ```js const createBranded = Symbol("create branded"); const brand = Symbol("brand"); class B { constructor(init) { if (init === createBranded) { this[brand] = brand; } } } Deno.bench("Object.create(protoype)", () => { Object.create(B.prototype); }); Deno.bench("new Class", () => { new B(createBranded); }); ``` ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.37.0 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ----------------------------------------------------------------------------- ----------------------------- Object.create(protoype) 8.74 ns/iter 114,363,610.3 (7.32 ns … 26.02 ns) 8.65 ns 13.39 ns 14.47 ns new Class 3.05 ns/iter 328,271,012.2 (2.78 ns … 9.1 ns) 3.06 ns 3.46 ns 3.5 ns ```
2023-08-15perf(ext/node): optimize http headers (#20163)Marcos Casagrande
This PR optimizes Node's `IncomingMessageForServer.headers` by replacing `Object.fromEntries()` with a loop and `headers.entries` with `headersEntries` which returns the internal array directly instead of an iterator ## Benchmarks Using `wrk` with 5 headers ``` wrk -d 10s --latency -H "X-Deno: true" -H "Accept: application/json" -H "X-Foo: bar" -H "User-Agent: wrk" -H "Accept-Encoding: gzip, br" http://127.0.0.1:3000 ``` **this PR** ``` Running 10s test @ http://127.0.0.1:3000 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 167.53us 136.89us 2.75ms 97.33% Req/Sec 31.98k 1.38k 36.39k 70.30% Latency Distribution 50% 134.00us 75% 191.00us 90% 234.00us 99% 544.00us 642548 requests in 10.10s, 45.96MB read Requests/sec: 63620.36 Transfer/sec: 4.55MB ``` **main** ``` Running 10s test @ http://127.0.0.1:3000 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 181.31us 132.54us 3.79ms 97.13% Req/Sec 29.21k 1.45k 32.93k 79.21% Latency Distribution 50% 148.00us 75% 198.00us 90% 261.00us 99% 545.00us 586939 requests in 10.10s, 41.98MB read Requests/sec: 58114.01 Transfer/sec: 4.16MB ``` ```js import express from "npm:express"; const app = express(); app.get("/", function (req, res) { req.headers; res.end(); }); app.listen(3000); ```
2023-08-14perf(ext/headers): optimize headers iterable (#20155)Marcos Casagrande
This PR makes more optimizations to headers iterable by removing `ObjectEntries` which was consistently prominent in the flame graph when benchmarking an express server. **this PR** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------ ----------------------------- headers iter 9.6 µs/iter 104,134.1 (8.74 µs … 131.31 µs) 9.47 µs 12.61 µs 17.81 µs ``` **main** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ------------------------------------------------------------------ ----------------------------- headers iter 12.87 µs/iter 77,675.9 (11.97 µs … 132.34 µs) 12.76 µs 16.49 µs 26.4 µs ``` ```js const headers = new Headers({ "Content-Type": "application/json", "X-Content-Type": "application/json", "Date": "Thu, 14 Aug 2023 17:45:10 GMT", "X-Deno": "Deno", "Powered-By": "Deno", "Content-Encoding": "gzip", "Set-Cookie": "__Secure-ID=123; Secure; Domain=example.com", "Content-Length": "150", "Vary": "Accept-Encoding, Accept, X-Requested-With", }); Deno.bench('headers iter', () => { [...headers] }) ```
2023-08-12perf(ext/headers): use regex.test instead of .exec (#20125)Marcos Casagrande
This PR improves the performance of `Headers.get` by using `Regex.test` instead of `.exec`. Also replaced the `Map` used for caching with an object which is a bit faster **This patch** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ----------------------------------------------------------------------- ----------------------------- Headers.get 124.71 ns/iter 8,018,687.3 (115.11 ns … 265.66 ns) 126.05 ns 136.12 ns 142.37 ns ``` **1.36.1** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.0 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ----------------------------------------------------------------------- ----------------------------- Headers.get 218.91 ns/iter 4,568,172.3 (165.37 ns … 264.44 ns) 241.62 ns 260.94 ns 262.67 ns ``` ```js const headers = new Headers({ "Content-Type": "application/json", "Date": "Thu, 10 Aug 2023 07:45:10 GMT", "X-Deno": "Deno", "Powered-By": "Deno", "Content-Encoding": "gzip", "Set-Cookie": "__Secure-ID=123; Secure; Domain=example.com", "Content-Length": "150", "Vary": "Accept-Encoding, Accept, X-Requested-With", }); Deno.bench("Headers.get", () => { headers.get("x-deno"); }); ```
2023-08-12perf(ext/headers): cache iterableHeaders for immutable Headers (#20132)Marcos Casagrande
This PR caches `_iterableHeaders` for immutable `Headers` increasing the performance of `fetch` & server if headers are iterated. Should close #19466 I only cached immutable headers to address this comment https://github.com/denoland/deno/issues/19466#issuecomment-1589892373 since I didn't find any occurrence of header mutation on immutable headers. We can discuss caching for non-immutable, but I think this is a great first step. ## BENCHMARK ### Server ```js const addr = Deno.args[0] ?? "127.0.0.1:4500"; const [hostname, port] = addr.split(":"); const { serve } = Deno; serve({ hostname, port: Number(port), reusePort: true }, (req) => { const headers = [...req.headers]; // req.headers are immutable, cannot set/append/delete return new Response("ok"); }); ``` Used `wrk` with 5 headers ``` wrk -d 10s --latency -H "X-Deno: true" -H "Accept: application/json" -H "X-Foo: bar" -H "User-Agent: wrk" -H "Accept-Encoding: gzip, br" http://127.0.0.1:4500 ``` **This patch** ``` Running 10s test @ http://127.0.0.1:4500 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 70.18us 22.89us 679.00us 81.37% Req/Sec 71.55k 9.69k 82.18k 89.60% Latency Distribution 50% 59.00us 75% 89.00us 90% 98.00us 99% 159.00us 1437891 requests in 10.10s, 193.35MB read Requests/sec: 142369.83 Transfer/sec: 19.14MB ``` **main** ``` Running 10s test @ http://127.0.0.1:4500 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 112.78us 36.47us 2.09ms 77.99% Req/Sec 44.30k 1.65k 49.14k 74.26% Latency Distribution 50% 99.00us 75% 136.00us 90% 162.00us 99% 213.00us 890588 requests in 10.10s, 118.91MB read Requests/sec: 88176.37 Transfer/sec: 11.77MB ``` ### fetch ```js const res = await fetch('http://127.0.0.1:4500'); Deno.bench("Headers iterator", () => { const i = [...res.headers]; // res.headers are immutable, cannot set/append/delete }); ``` **this patch** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ---------------------------------------------------------------------- ----------------------------- Headers iterator 329.5 ns/iter 3,034,909.0 (318.55 ns … 364.34 ns) 331.1 ns 355.72 ns 364.34 ns ``` **main** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.1 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ---------------------------------------------------------------------- ----------------------------- Headers iterator 2.59 µs/iter 386,372.1 (2.56 µs … 2.68 µs) 2.59 µs 2.68 µs 2.68 µs ```
2023-08-10perf(ext/headers): optimize getHeader using for loop (#20115)Marcos Casagrande
This PR optimizes the `getHeader` function by replacing `.filter` and `.map` with a `for` loop **this patch** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.0 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ----------------------------------------------------------------- ----------------------------- Headers.get 132.2 ns/iter 7,564,093.4 (125.81 ns … 147.66 ns) 133.79 ns 144.92 ns 145.36 ns ``` **main** ``` cpu: 13th Gen Intel(R) Core(TM) i9-13900H runtime: deno 1.36.0 (x86_64-unknown-linux-gnu) benchmark time (avg) iter/s (min … max) p75 p99 p995 ----------------------------------------------------------------- ----------------------------- Headers.get 191.48 ns/iter 5,222,523.6 (182.75 ns … 212.22 ns) 193.5 ns 205.96 ns 211.51 ns ``` ```js const headers = new Headers({ "Content-Type": "application/json", "Date": "Thu, 10 Aug 2023 07:45:10 GMT", "X-Deno": "Deno", "Powered-By": "Deno", "Content-Encoding": "gzip", "Set-Cookie": "__Secure-ID=123; Secure; Domain=example.com", "Content-Length": "150", "Vary": "Accept-Encoding, Accept, X-Requested-With", }); Deno.bench("Headers.get", () => { const i = headers.get("x-deno"); }); ```
2023-08-09perf(ext/headers): use .push loop instead of spread operator (#20108)Marcos Casagrande
2023-07-02feat(ext/fetch): add Headers#getSetCookie (#13542)Luca Casonato
Spec change: https://github.com/whatwg/fetch/pull/1346 Tests: https://github.com/web-platform-tests/wpt/pull/31442 (ran against this PR and they all pass) --------- Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
2023-06-15refactor(ext/fetch): const for max header cache size (#19496)markthree
2023-06-13perf(http): cache verified headers (#19465)Bartek Iwańczuk
Use `Map` to cache validated HTTP headers. Cache has a capacity of 4096 elements and it's cleared once that capacity is reached. In `preactssr` benchmark it lowers the time spent when adding headers from 180ms to 2.5ms.
2023-06-05perf: optimize RegExp usage in JS (#19364)Bartek Iwańczuk
Towards https://github.com/denoland/deno/issues/19330 Shows about 1% improvement in the HTTP benchmark.
2023-05-02refactor(core): Use `ObjectHasOwn` instead of ↵Kenta Moriuchi
`ObjectPrototypeHasOwnProperty` (#18952) ES2022 `Object.hasOwn` can be used in snapshot, so I migrate to use it.
2023-05-01refactor(webidl): move prefix & context out of converters options bag (#18931)Leo Kettmeir
2023-04-20refactor(ext/webidl): remove option bags from "makeException" (#18679)Bartek Iwańczuk
Creating these options bags is more costly than passing arguments one-by-one. Especially since `prefix` and `context` are passed to all functions.
2023-04-12refactor(ext/webidl): remove object from 'requiredArguments' (#18674)Bartek Iwańczuk
This should produce a little less garbage and using an object here wasn't really required. --------- Co-authored-by: Aapo Alasuutari <aapo.alasuutari@gmail.com> Co-authored-by: Leo Kettmeir <crowlkats@toaxl.com>
2023-03-08refactor: rename InternalModuleLoader to ExtModuleLoader, use ext: scheme ↵Bartek Iwańczuk
for snapshotted modules (#18041) This commit renames "deno_core::InternalModuleLoader" to "ExtModuleLoader" and changes the specifiers used by the modules loaded from this loader to "ext:". "internal:" scheme was really ambiguous and it's more characters than "ext:", which should result in slightly smaller snapshot size. Closes https://github.com/denoland/deno/issues/18020
2023-03-01fix(core): introduce `SafeRegExp` to primordials (#17592)Kenta Moriuchi
2023-02-07 refactor: remove prefix from include_js_files & use extension name (#17683)Leo Kettmeir
2023-02-07refactor: Use ES modules for internal runtime code (#17648)Leo Kettmeir
This PR refactors all internal js files (except core) to be written as ES modules. `__bootstrap`has been mostly replaced with static imports in form in `internal:[path to file from repo root]`. To specify if files are ESM, an `esm` method has been added to `Extension`, similar to the `js` method. A new ModuleLoader called `InternalModuleLoader` has been added to enable the loading of internal specifiers, which is used in all situations except when a snapshot is only loaded, and not a new one is created from it. --------- Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
2023-01-06perf(ext,runtime): remove using `SafeArrayIterator` from `for-of` (#17255)Kenta Moriuchi
2023-01-02chore: update copyright year to 2023 (#17247)David Sherret
Yearly tradition of creating extra noise in git.
2022-12-20chore: Update dlint (#17031)Kenta Moriuchi
Introduces `SafeSetIterator` and `SafeMapIterator` to primordials
2022-10-10fix(ext/fetch): fix illegal header regex (#16236)Marcos Casagrande
This PR fixes invalid header parsing which is flaky because `g` flag is being used in the regex, which keeps track of `lastIndex` ```javascript try { new Headers([["x", "\u0000x"]]); // error } catch(e) {} new Headers([["x", "\u0000x"]]); // no error ``` This issue affects `Response` & `Request` constructors as well
2022-09-28feat: implement Web Cache API (#15829)Satya Rohith
2022-03-25chore(ext): fix typo in ext/webgpu, ext/fetch (#14106)apeltop
2022-02-07refactor: update runtime code for primordial check for iterators (#13510)Bartek Iwańczuk
2022-02-01refactor: primordials for instanceof (#13527)Bartek Iwańczuk
2022-01-27Revert "refactor: update runtime code for primordial checks for "instanceof" ↵Bartek Iwańczuk
(#13497)" (#13511) This reverts commit 884143218fad0e18f7553aaf079d52de703f7601.
2022-01-27refactor: update runtime code for primordial checks for "instanceof" (#13497)Bartek Iwańczuk
2022-01-07chore: update copyright to 2022 (#13306)Ryan Dahl
Co-authored-by: Erfan Safari <erfanshield@outlook.com>
2021-11-23revert: store header keys lower case internally (#12837)Luca Casonato
This reverts commit 49ec3d10ad90851f4d28274a3f0fe96c642204ac.
2021-10-01perf(fetch): optimize fillHeaders() key iteration (#12287)Aaron O'Mullan
Reduces self-time by ~70x (~70ms => ~1ms on 1M iters) for...in filtered by hasOwnProperty yields the same set of keys as Object.keys()
2021-09-30perf(web): ~400x faster http header trimming (#12277)Aaron O'Mullan
Use a regex substring match with a first/last char fastpath instead of 2 regex replaces. Roughly ~400x faster (423ms vs 0.7ms in profiled runs)
2021-09-26perf(fetch/headers): optimize appendHeader (#12234)Aaron O'Mullan
Use a single regex to check for `\0`, `\n`, `\r` instead of 3 `String.includes(...)` calls
2021-09-25fix(ext/webidl): correctly apply [SymbolToStringTag] to interfaces (#11851)李瑞丰
Co-authored-by: Luca Casonato <hello@lcas.dev> Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
2021-08-21fiz(ext/fetch): Headers constructor error message (#11778)Feng Yu
2021-08-11Rename extensions/ directory to ext/ (#11643)Ryan Dahl