@nxtedition/nxt-undici 7.3.12 → 7.3.14

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.
@@ -113,7 +113,7 @@ class CacheHandler extends DecoratorHandler {
113
113
 
114
114
  const ttl = cacheControlDirectives.immutable
115
115
  ? 31556952
116
- : Number(cacheControlDirectives['s-max-age'] ?? cacheControlDirectives['max-age'])
116
+ : Number(cacheControlDirectives['s-maxage'] ?? cacheControlDirectives['max-age'])
117
117
  if (!ttl || !Number.isFinite(ttl) || ttl <= 0) {
118
118
  return super.onHeaders(statusCode, headers, resume)
119
119
  }
@@ -186,7 +186,11 @@ export default () => (dispatch) => (opts, handler) => {
186
186
  return dispatch(opts, handler)
187
187
  }
188
188
 
189
- const cacheControlDirectives = parseCacheControl(opts?.headers['cache-control']) ?? {}
189
+ const rawCacheControl = opts?.headers?.['cache-control']
190
+ const cacheControlDirectives = parseCacheControl(rawCacheControl) ?? {}
191
+ // cache-control-parser does not recognise 'only-if-cached', so check the raw string.
192
+ const onlyIfCached =
193
+ typeof rawCacheControl === 'string' && rawCacheControl.includes('only-if-cached')
190
194
 
191
195
  if (cacheControlDirectives['no-transform']) {
192
196
  // Do nothing. We don't transform requests...
@@ -213,19 +217,20 @@ export default () => (dispatch) => (opts, handler) => {
213
217
  } catch (err) {
214
218
  if (err.message === 'database is locked') {
215
219
  // Database is busy. We don't bother trying again...
216
- opts.logger?.debug({ err }, 'failed to set cache entry')
220
+ opts.logger?.debug({ err }, 'failed to get cache entry')
217
221
  } else {
218
- opts.logger?.error({ err }, 'failed to set cache entry')
222
+ opts.logger?.error({ err }, 'failed to get cache entry')
219
223
  }
220
224
  }
221
225
 
222
- if (!entry && !cacheControlDirectives['only-if-cached']) {
226
+ if (!entry && !onlyIfCached) {
223
227
  return dispatch(
224
228
  opts,
225
229
  cacheControlDirectives['no-store']
226
230
  ? handler
227
231
  : new CacheHandler(undici.util.cache.makeCacheKey(opts), {
228
232
  maxEntrySize: opts.cache.maxEntrySize,
233
+ maxEntryTTL: opts.cache.maxEntryTTL,
229
234
  store,
230
235
  logger: opts.logger,
231
236
  handler,
@@ -119,7 +119,7 @@ export default () => (dispatch) => {
119
119
  )
120
120
 
121
121
  for (let i = 0; i < records.length; i++) {
122
- if (records[i].expires >= now) {
122
+ if (records[i].expires >= now && records[i].timeout < now) {
123
123
  record = records[i]
124
124
  break
125
125
  }
@@ -66,6 +66,7 @@ class Handler extends DecoratorHandler {
66
66
 
67
67
  socket.on('close', () => {
68
68
  this.#logger.debug('upstream request socket closed')
69
+ this.onDone()
69
70
  })
70
71
 
71
72
  super.onUpgrade(statusCode, headers, socket)
@@ -89,7 +90,7 @@ class Handler extends DecoratorHandler {
89
90
  return super.onData(chunk)
90
91
  }
91
92
 
92
- onComplete() {
93
+ onComplete(trailers) {
93
94
  this.#timing.end = performance.now() - this.#created
94
95
 
95
96
  const data = {
@@ -117,7 +118,7 @@ class Handler extends DecoratorHandler {
117
118
 
118
119
  this.onDone()
119
120
 
120
- super.onComplete()
121
+ super.onComplete(trailers)
121
122
  }
122
123
 
123
124
  onError(err) {
@@ -5,23 +5,27 @@ export default () => (dispatch) => async (opts, handler) => {
5
5
  return dispatch(opts, handler)
6
6
  }
7
7
 
8
- const origin = await new Promise((resolve, reject) => {
9
- const thenable = lookup(opts.origin, { signal: opts.signal ?? undefined }, (err, val) => {
10
- if (err) {
11
- reject(err)
12
- } else {
13
- resolve(val)
8
+ try {
9
+ const origin = await new Promise((resolve, reject) => {
10
+ const thenable = lookup(opts.origin, { signal: opts.signal ?? undefined }, (err, val) => {
11
+ if (err) {
12
+ reject(err)
13
+ } else {
14
+ resolve(val)
15
+ }
16
+ })
17
+
18
+ if (thenable != null) {
19
+ Promise.resolve(thenable).then(resolve, reject)
14
20
  }
15
21
  })
16
22
 
17
- if (thenable != null) {
18
- Promise.resolve(thenable).then(resolve, reject)
23
+ if (!origin) {
24
+ throw new Error('invalid origin: ' + origin)
19
25
  }
20
- })
21
26
 
22
- if (!origin) {
23
- throw new Error('invalid origin: ' + origin)
27
+ return dispatch({ ...opts, origin }, handler)
28
+ } catch (err) {
29
+ handler.onError(err)
24
30
  }
25
-
26
- return dispatch({ ...opts, origin }, handler)
27
31
  }
@@ -105,7 +105,9 @@ function reduceHeaders({ headers, proxyName, httpVersion, socket }, fn, acc) {
105
105
  socket.remoteAddress && `for=${printIp(socket.remoteAddress, socket.remotePort)}`,
106
106
  `proto=${socket.encrypted ? 'https' : 'http'}`,
107
107
  forwardedHost && `host="${forwardedHost}"`,
108
- ].join(';'),
108
+ ]
109
+ .filter(Boolean)
110
+ .join(';'),
109
111
  )
110
112
  } else if (forwarded) {
111
113
  // The forwarded header should not be included in response.
@@ -69,6 +69,7 @@ class Handler extends DecoratorHandler {
69
69
  if (!this.#opts.follow(this.#location, this.#count, this.#opts)) {
70
70
  assert(!this.#headersSent)
71
71
  this.#headersSent = true
72
+ this.#location = null
72
73
  return super.onHeaders(statusCode, headers, resume)
73
74
  }
74
75
  } else {
@@ -144,7 +145,10 @@ class Handler extends DecoratorHandler {
144
145
  this.#location = null
145
146
 
146
147
  try {
147
- this.#dispatch(this.#opts, this)?.catch((err) => this.onError(err))
148
+ const result = this.#dispatch(this.#opts, this)
149
+ if (result != null && typeof result.catch === 'function') {
150
+ result.catch((err) => this.onError(err))
151
+ }
148
152
  } catch (err) {
149
153
  this.onError(err)
150
154
  }
@@ -176,7 +176,6 @@ class Handler extends DecoratorHandler {
176
176
  }
177
177
 
178
178
  if (this.#statusCode < 400) {
179
- this.#retryCount = 0
180
179
  return super.onData(chunk)
181
180
  }
182
181
 
@@ -194,7 +193,6 @@ class Handler extends DecoratorHandler {
194
193
  this.#trailers = trailers
195
194
 
196
195
  if (this.#statusCode < 400) {
197
- this.#retryCount = 0
198
196
  return super.onComplete(trailers)
199
197
  }
200
198
 
@@ -41,7 +41,7 @@ class Handler extends DecoratorHandler {
41
41
  return super.onData(chunk)
42
42
  }
43
43
 
44
- onComplete() {
44
+ onComplete(trailers) {
45
45
  const contentMD5 = this.#hasher?.digest('base64')
46
46
 
47
47
  if (this.#contentLength != null && this.#pos !== Number(this.#contentLength)) {
@@ -59,7 +59,7 @@ class Handler extends DecoratorHandler {
59
59
  }),
60
60
  )
61
61
  } else {
62
- super.onComplete()
62
+ super.onComplete(trailers)
63
63
  }
64
64
  }
65
65
  }
package/lib/utils.js CHANGED
@@ -59,8 +59,8 @@ export function parseContentRange(range) {
59
59
  return m
60
60
  ? {
61
61
  start: parseInt(m[1], 10),
62
- end: m[2] ? parseInt(m[2]) + 1 : null,
63
- size: m[3] === '*' ? null : parseInt(m[3]),
62
+ end: m[2] ? parseInt(m[2], 10) + 1 : null,
63
+ size: m[3] === '*' ? null : parseInt(m[3], 10),
64
64
  }
65
65
  : null
66
66
  }
@@ -83,8 +83,8 @@ export function parseRangeHeader(range) {
83
83
  const m = range.match(/^bytes=(\d+)-(\d+)?$/)
84
84
  return m
85
85
  ? {
86
- start: parseInt(m[1]),
87
- end: m[2] ? parseInt(m[2]) + 1 : null,
86
+ start: parseInt(m[1], 10),
87
+ end: m[2] ? parseInt(m[2], 10) + 1 : null,
88
88
  size: null,
89
89
  }
90
90
  : null
@@ -267,7 +267,6 @@ export class DecoratorHandler {
267
267
  onError(err) {
268
268
  if (!this.#errored && !this.#completed) {
269
269
  this.#errored = true
270
- assert(!this.#completed)
271
270
  return this.#handler.onError?.(err)
272
271
  }
273
272
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/nxt-undici",
3
- "version": "7.3.12",
3
+ "version": "7.3.14",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "main": "lib/index.js",