@nxtedition/nxt-undici 6.0.5 → 6.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,14 +5,17 @@ const DEFAULT_STORE = new undici.cacheStores.SqliteCacheStore({ location: ':memo
5
5
  const MAX_ENTRY_SIZE = 128 * 1024
6
6
 
7
7
  class CacheHandler extends DecoratorHandler {
8
+ #key
8
9
  #value
9
- #opts
10
10
  #store
11
11
 
12
- constructor(opts, { store, handler }) {
12
+ constructor(key, { store, handler }) {
13
+ undici.util.cache.assertCacheKey(key)
14
+
13
15
  super(handler)
14
16
 
15
- this.#opts = opts
17
+ this.#key = key
18
+ this.#value = null
16
19
  this.#store = store
17
20
  }
18
21
 
@@ -39,20 +42,26 @@ class CacheHandler extends DecoratorHandler {
39
42
  return super.onHeaders(statusCode, headers, resume)
40
43
  }
41
44
 
42
- const cacheControl = parseCacheControl(headers['cache-control'])
45
+ const cacheControlDirectives = parseCacheControl(headers['cache-control']) ?? {}
46
+
47
+ if (this.#key.headers.authorization && !cacheControlDirectives.public) {
48
+ return super.onHeaders(statusCode, headers, resume)
49
+ }
50
+
51
+ if (cacheControlDirectives.private || cacheControlDirectives['no-store']) {
52
+ return super.onHeaders(statusCode, headers, resume)
53
+ }
54
+
43
55
  if (
44
- !cacheControl ||
45
- !cacheControl.public ||
46
- cacheControl.private ||
47
- cacheControl['no-store'] ||
48
- // TODO (fix): Support all cache control directives...
49
- // cacheControl['no-transform'] ||
50
- cacheControl['no-cache'] ||
51
- cacheControl['must-understand'] ||
52
- cacheControl['must-revalidate'] ||
53
- cacheControl['proxy-revalidate']
56
+ cacheControlDirectives['no-transform'] ||
57
+ cacheControlDirectives['must-revalidate'] ||
58
+ cacheControlDirectives['proxy-revalidate'] ||
59
+ cacheControlDirectives['must-understand'] ||
60
+ cacheControlDirectives['stale-while-revalidate'] ||
61
+ cacheControlDirectives['stale-if-error'] ||
62
+ cacheControlDirectives['no-cache']
54
63
  ) {
55
- // Not cacheble...
64
+ // TODO (fix): Support all cache control directives...
56
65
  return super.onHeaders(statusCode, headers, resume)
57
66
  }
58
67
 
@@ -61,7 +70,7 @@ class CacheHandler extends DecoratorHandler {
61
70
  for (const key of [headers.vary]
62
71
  .flat()
63
72
  .flatMap((vary) => vary.split(',').map((key) => key.trim().toLowerCase()))) {
64
- const val = this.#opts.headers?.[key]
73
+ const val = this.#key.headers[key]
65
74
  if (!val) {
66
75
  // Expect vary headers to be present...
67
76
  return super.onHeaders(statusCode, headers, resume)
@@ -73,9 +82,9 @@ class CacheHandler extends DecoratorHandler {
73
82
  return super.onHeaders(statusCode, headers, resume)
74
83
  }
75
84
 
76
- const ttl = cacheControl.immutable
85
+ const ttl = cacheControlDirectives.immutable
77
86
  ? 31556952
78
- : Number(cacheControl['s-max-age'] ?? cacheControl['max-age'])
87
+ : Number(cacheControlDirectives['s-max-age'] ?? cacheControlDirectives['max-age'])
79
88
  if (!ttl || !Number.isFinite(ttl) || ttl <= 0) {
80
89
  return super.onHeaders(statusCode, headers, resume)
81
90
  }
@@ -89,8 +98,8 @@ class CacheHandler extends DecoratorHandler {
89
98
  statusCode,
90
99
  statusMessage: '',
91
100
  headers,
92
- cacheControlDirectives: '',
93
- etag: '',
101
+ cacheControlDirectives,
102
+ etag: headers.etag,
94
103
  vary,
95
104
  cachedAt,
96
105
  staleAt: 0,
@@ -115,7 +124,7 @@ class CacheHandler extends DecoratorHandler {
115
124
 
116
125
  onComplete(trailers) {
117
126
  if (this.#value && (!trailers || Object.keys(trailers).length === 0)) {
118
- this.#store.set(this.#opts, this.#value)
127
+ this.#store.set(this.#key, this.#value)
119
128
  }
120
129
 
121
130
  super.onComplete(trailers)
@@ -131,16 +140,17 @@ export default () => (dispatch) => (opts, handler) => {
131
140
  return dispatch(opts, handler)
132
141
  }
133
142
 
134
- if (opts.headers?.['cache-control'] || opts.headers?.authorization) {
143
+ const cacheControlDirectives = parseCacheControl(opts?.headers['cache-control']) ?? {}
144
+
145
+ if (
146
+ cacheControlDirectives['max-age'] ||
147
+ cacheControlDirectives['max-stale'] ||
148
+ cacheControlDirectives['min-fresh'] ||
149
+ cacheControlDirectives['no-cache'] ||
150
+ cacheControlDirectives['no-transform'] ||
151
+ cacheControlDirectives['stale-if-error']
152
+ ) {
135
153
  // TODO (fix): Support all cache control directives...
136
- // const cacheControl = cacheControlParser.parse(opts.headers['cache-control'])
137
- // cacheControl['no-cache']
138
- // cacheControl['no-store']
139
- // cacheControl['max-age']
140
- // cacheControl['max-stale']
141
- // cacheControl['min-fresh']
142
- // cacheControl['no-transform']
143
- // cacheControl['only-if-cached']
144
154
  return dispatch(opts, handler)
145
155
  }
146
156
 
@@ -149,8 +159,13 @@ export default () => (dispatch) => (opts, handler) => {
149
159
 
150
160
  const store = opts.cache.store ?? DEFAULT_STORE
151
161
  const entry = store.get(opts)
152
- if (!entry) {
153
- return dispatch(opts, new CacheHandler(opts.headers, { store, handler }))
162
+ if (!entry && !cacheControlDirectives['only-if-cached']) {
163
+ return dispatch(
164
+ opts,
165
+ cacheControlDirectives['no-store']
166
+ ? handler
167
+ : new CacheHandler(undici.util.cache.makeCacheKey(opts), { store, handler }),
168
+ )
154
169
  }
155
170
 
156
171
  let aborted = false
@@ -168,7 +183,7 @@ export default () => (dispatch) => (opts, handler) => {
168
183
  }
169
184
  }
170
185
 
171
- const { statusCode, headers } = entry
186
+ const { statusCode, headers } = entry ?? { statusCode: 504, headers: {} }
172
187
  try {
173
188
  handler.onConnect(abort)
174
189
  if (aborted) {
@@ -60,7 +60,7 @@ class Handler extends DecoratorHandler {
60
60
  this.#logger.debug('upstream request socket closed')
61
61
  })
62
62
 
63
- super.onUpgrade(statusCode, null, socket, headers)
63
+ super.onUpgrade(statusCode, headers, socket)
64
64
  }
65
65
 
66
66
  onHeaders(statusCode, headers, resume) {
@@ -41,8 +41,8 @@ class Handler extends DecoratorHandler {
41
41
  }
42
42
  }
43
43
 
44
- onUpgrade(statusCode, rawHeaders, socket, headers) {
45
- super.onUpgrade(statusCode, rawHeaders, socket, headers)
44
+ onUpgrade(statusCode, headers, socket) {
45
+ super.onUpgrade(statusCode, headers, socket)
46
46
  }
47
47
 
48
48
  onHeaders(statusCode, headers, resume) {
package/lib/utils.js CHANGED
@@ -265,10 +265,6 @@ export class DecoratorHandler {
265
265
  return this.#handler.onConnect?.(...args)
266
266
  }
267
267
 
268
- onError(...args) {
269
- return this.#handler.onError?.(...args)
270
- }
271
-
272
268
  onUpgrade(...args) {
273
269
  return this.#handler.onUpgrade?.(...args)
274
270
  }
@@ -284,6 +280,10 @@ export class DecoratorHandler {
284
280
  onComplete(...args) {
285
281
  return this.#handler.onComplete?.(...args)
286
282
  }
283
+
284
+ onError(...args) {
285
+ return this.#handler.onError?.(...args)
286
+ }
287
287
  }
288
288
 
289
289
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/nxt-undici",
3
- "version": "6.0.5",
3
+ "version": "6.0.7",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "main": "lib/index.js",