feat(util): expose request header normalization - #5780
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5780 +/- ##
==========================================
- Coverage 93.51% 93.51% -0.01%
==========================================
Files 110 110
Lines 39359 39552 +193
==========================================
+ Hits 36808 36986 +178
- Misses 2551 2566 +15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I'm not convinced by this change, as it's significantly perf cost. Wdyt @ronag? |
|
Yea. This is probably not a good idea... |
|
That makes sense. The current implementation wraps every interceptor boundary, so it does more work than necessary for each request. I’m thinking of changing it to normalize once at the composed dispatcher entry, skip plain objects that are already normalized, and keep the resulting object through interceptor redispatches. Would that address the performance concern, or would you prefer a different approach? |
Composed interceptors received headers in several different formats depending on how a request was made. Normalize them at each interceptor boundary while retaining repeated values. Signed-off-by: GiHoon1123 <rlaejrqo465@naver.com>
770da53 to
88e5463
Compare
|
I reworked this to avoid wrapping each interceptor boundary. Headers are now normalized once when the composed dispatcher is entered, and already-normalized plain objects are passed through without a copy. The existing DNS redispatch cases still pass with the normalized object. The updated commit is |
|
|
||
| if (Array.isArray(headers)) { | ||
| if (headers.length > 0 && Array.isArray(headers[0])) { | ||
| if (headers.some(header => !Array.isArray(header) || header.length !== 2)) { |
There was a problem hiding this comment.
let's try to prefer for-loops over array methods; this will sit in a hot-path if interceptors are used
There was a problem hiding this comment.
Updated this to use a loop.
| } | ||
| } | ||
|
|
||
| function normalizeHeaders (headers) { |
There was a problem hiding this comment.
I'm a bit worried of all the branching, but unsure if it can be simplified
There was a problem hiding this comment.
I took another look at the request path. Normalizing in compose() means walking the headers to build an object, then Request walks them again to build its internal array. It also adds that work for interceptors that never read request headers.
Would it be better to expose a shared normalization helper for interceptors that need it? If normalization should happen automatically, it seems like we’d need a shared internal representation that Request can reuse. What do you think?
There was a problem hiding this comment.
That's a good idea, go for it
There was a problem hiding this comment.
Implemented in 058d912. normalizeHeaders() is now exposed through util, and cache and deduplicate use the same helper. I removed eager normalization from compose(), so interceptors that do not inspect headers no longer pay the extra cost. Types, docs, and the relevant tests have been updated.
Signed-off-by: Gihoon1123 <rlaejrqo465@naver.com>
Let interceptors normalize supported header inputs only when they need to inspect them. Reuse the same helper in cache and deduplicate without adding work to every composed request. Signed-off-by: GiHoon1123 <rlaejrqo465@naver.com>
Refs #4336.
Request headers can reach composed interceptors as an object, flat array,
Headersinstance, or another iterable. This addsutil.normalizeHeaders()so interceptors that inspect headers can convert those inputs to a lower-case object while preserving repeated values.The cache and deduplicate interceptors now use the same helper.
compose()no longer normalizes every request, avoiding extra header work for interceptors that do not inspect them.Tests:
npm run lintnpm run test:typescriptborp --timeout 180000 test/interceptors/interceptors-on-client.js test/interceptors/cache-query-params.js test/interceptors/redirect.js test/cache-interceptor/cache-utils.js test/node-test/util.jsnode --test --test-name-pattern '#5522' test/interceptors/dns.js