@nxtedition/lib 26.0.1 → 26.0.3
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.
- package/http.js +58 -46
- package/package.json +1 -1
package/http.js
CHANGED
|
@@ -154,10 +154,12 @@ export async function upgradeMiddleware(ctx, next) {
|
|
|
154
154
|
}
|
|
155
155
|
})
|
|
156
156
|
|
|
157
|
+
let logger = ctx.logger
|
|
157
158
|
try {
|
|
158
159
|
const isHealthcheck = req.url === '/healthcheck' || req.url === '/_up'
|
|
159
160
|
if (!isHealthcheck) {
|
|
160
|
-
|
|
161
|
+
logger = logger?.child({ req })
|
|
162
|
+
logger?.debug('request started')
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
const thenable = next()
|
|
@@ -173,15 +175,15 @@ export async function upgradeMiddleware(ctx, next) {
|
|
|
173
175
|
if (isHealthcheck) {
|
|
174
176
|
// Do nothing...
|
|
175
177
|
} else if (socket.errored) {
|
|
176
|
-
|
|
178
|
+
logger?.error({ err: socket.errored, req, socket, elapsedTime }, 'stream error')
|
|
177
179
|
} else if (!socket.writableEnded) {
|
|
178
|
-
|
|
180
|
+
logger?.debug({ req, socket, elapsedTime }, 'stream aborted')
|
|
179
181
|
} else if (socket.statusCode >= 500) {
|
|
180
|
-
|
|
182
|
+
logger?.error({ req, socket, elapsedTime }, 'stream error')
|
|
181
183
|
} else if (socket.statusCode >= 400) {
|
|
182
|
-
|
|
184
|
+
logger?.warn({ req, socket, elapsedTime }, 'stream failed')
|
|
183
185
|
} else {
|
|
184
|
-
|
|
186
|
+
logger?.debug({ req, socket, elapsedTime }, 'stream completed')
|
|
185
187
|
}
|
|
186
188
|
} catch (err) {
|
|
187
189
|
ctx[kAbortController]?.abort(err)
|
|
@@ -190,17 +192,17 @@ export async function upgradeMiddleware(ctx, next) {
|
|
|
190
192
|
const elapsedTime = performance.now() - startTime
|
|
191
193
|
|
|
192
194
|
if (req.aborted || aborted || (!socket.errored && socket.closed) || err.name === 'AbortError') {
|
|
193
|
-
|
|
195
|
+
logger?.debug({ err, req, socket, elapsedTime }, 'stream aborted')
|
|
194
196
|
} else if (statusCode < 500) {
|
|
195
|
-
|
|
197
|
+
logger?.warn({ err, req, socket, elapsedTime }, 'stream failed')
|
|
196
198
|
} else {
|
|
197
|
-
|
|
199
|
+
logger?.error({ err, req, socket, elapsedTime }, 'stream error')
|
|
198
200
|
}
|
|
199
201
|
socket.destroy(err)
|
|
200
202
|
} finally {
|
|
201
203
|
if (!socket.writableEnded && !socket.destroyed) {
|
|
202
204
|
socket.destroy()
|
|
203
|
-
|
|
205
|
+
logger?.warn('socket destroyed')
|
|
204
206
|
}
|
|
205
207
|
}
|
|
206
208
|
}
|
|
@@ -209,20 +211,41 @@ export async function requestMiddleware(ctx, next) {
|
|
|
209
211
|
const { req, res } = ctx
|
|
210
212
|
const startTime = performance.now()
|
|
211
213
|
|
|
214
|
+
let logger = ctx.logger
|
|
212
215
|
try {
|
|
213
216
|
const isHealthcheck = req.url === '/healthcheck' || req.url === '/_up'
|
|
214
217
|
if (!isHealthcheck) {
|
|
215
|
-
|
|
218
|
+
logger = logger?.child({ req })
|
|
219
|
+
logger?.debug('request started')
|
|
216
220
|
}
|
|
217
221
|
|
|
218
222
|
if (ctx.id) {
|
|
219
223
|
res.setHeader('request-id', ctx.id)
|
|
220
224
|
}
|
|
221
225
|
|
|
226
|
+
if (req.httpVersionMajor === 1 && (req.method === 'HEAD' || req.method === 'GET')) {
|
|
227
|
+
// Fast dump where request "has" already emitted all lifecycle events.
|
|
228
|
+
// This avoid a lot of unnecessary overhead otherwise introduced by
|
|
229
|
+
// stream.Readable life cycle rules. The downside is that this will
|
|
230
|
+
// break some servers that read GET bodies.
|
|
231
|
+
|
|
232
|
+
req._dumped = true
|
|
233
|
+
req._readableState.ended = true
|
|
234
|
+
req._readableState.endEmitted = true
|
|
235
|
+
req._readableState.destroyed = true
|
|
236
|
+
req._readableState.closed = true
|
|
237
|
+
req._readableState.closeEmitted = true
|
|
238
|
+
|
|
239
|
+
req._read()
|
|
240
|
+
}
|
|
241
|
+
|
|
222
242
|
const thenable = next()
|
|
223
243
|
|
|
224
|
-
if (
|
|
244
|
+
if (!req.destroyed || req.errored) {
|
|
225
245
|
req.on('error', noop)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!res.destroyed || res.errored) {
|
|
226
249
|
res.on('error', noop)
|
|
227
250
|
}
|
|
228
251
|
|
|
@@ -230,22 +253,24 @@ export async function requestMiddleware(ctx, next) {
|
|
|
230
253
|
await thenable
|
|
231
254
|
}
|
|
232
255
|
|
|
233
|
-
|
|
256
|
+
if (!res.destroyed || !res.writableEnded) {
|
|
257
|
+
throw new Error('Response not completed')
|
|
258
|
+
}
|
|
234
259
|
|
|
235
260
|
const elapsedTime = performance.now() - startTime
|
|
236
261
|
|
|
237
262
|
if (isHealthcheck) {
|
|
238
263
|
// Do nothing...
|
|
239
264
|
} else if (res.errored) {
|
|
240
|
-
|
|
265
|
+
logger?.error({ err: res.errored, req, res, elapsedTime }, 'request error')
|
|
241
266
|
} else if (!res.writableEnded) {
|
|
242
|
-
|
|
267
|
+
logger?.debug({ req, res, elapsedTime }, 'request aborted')
|
|
243
268
|
} else if (res.statusCode >= 500) {
|
|
244
|
-
|
|
269
|
+
logger?.error({ req, res, elapsedTime }, 'request error')
|
|
245
270
|
} else if (res.statusCode >= 400) {
|
|
246
|
-
|
|
271
|
+
logger?.warn({ req, res, elapsedTime }, 'request failed')
|
|
247
272
|
} else {
|
|
248
|
-
|
|
273
|
+
logger?.debug({ req, res, elapsedTime }, 'request completed')
|
|
249
274
|
}
|
|
250
275
|
} catch (err) {
|
|
251
276
|
ctx[kAbortController]?.abort(err)
|
|
@@ -285,7 +310,7 @@ export async function requestMiddleware(ctx, next) {
|
|
|
285
310
|
}
|
|
286
311
|
}
|
|
287
312
|
} else if (err.headers != null) {
|
|
288
|
-
|
|
313
|
+
logger?.warn({ req, err }, 'invalid headers')
|
|
289
314
|
}
|
|
290
315
|
|
|
291
316
|
if (fp.isPlainObject(err.body)) {
|
|
@@ -300,17 +325,17 @@ export async function requestMiddleware(ctx, next) {
|
|
|
300
325
|
}
|
|
301
326
|
|
|
302
327
|
if (statusCode < 500) {
|
|
303
|
-
|
|
328
|
+
logger?.warn({ res, err, elapsedTime }, 'request failed')
|
|
304
329
|
} else {
|
|
305
|
-
|
|
330
|
+
logger?.error({ res, err, elapsedTime }, 'request error')
|
|
306
331
|
}
|
|
307
332
|
} else {
|
|
308
333
|
if (req.aborted || (!res.errored && res.closed) || err.name === 'AbortError') {
|
|
309
|
-
|
|
334
|
+
logger?.debug({ res, err, elapsedTime }, 'request aborted')
|
|
310
335
|
} else if (statusCode < 500) {
|
|
311
|
-
|
|
336
|
+
logger?.warn({ res, err, elapsedTime }, 'request failed')
|
|
312
337
|
} else {
|
|
313
|
-
|
|
338
|
+
logger?.error({ res, err, elapsedTime }, 'request error')
|
|
314
339
|
}
|
|
315
340
|
res.destroy(err)
|
|
316
341
|
}
|
|
@@ -319,7 +344,7 @@ export async function requestMiddleware(ctx, next) {
|
|
|
319
344
|
// Do nothing..
|
|
320
345
|
} else {
|
|
321
346
|
res.destroy()
|
|
322
|
-
|
|
347
|
+
logger?.warn('request destroyed')
|
|
323
348
|
}
|
|
324
349
|
}
|
|
325
350
|
}
|
|
@@ -334,13 +359,8 @@ export class IncomingMessage extends http.IncomingMessage {
|
|
|
334
359
|
#search
|
|
335
360
|
#query
|
|
336
361
|
|
|
337
|
-
constructor(...args) {
|
|
338
|
-
super(...args)
|
|
339
|
-
this.#id = this.headers['request-id'] || this.headers['Request-Id'] || genReqId()
|
|
340
|
-
}
|
|
341
|
-
|
|
342
362
|
get id() {
|
|
343
|
-
return this.#id
|
|
363
|
+
return (this.#id ??= this.headers['request-id'] || this.headers['Request-Id'] || genReqId())
|
|
344
364
|
}
|
|
345
365
|
|
|
346
366
|
get target() {
|
|
@@ -485,6 +505,12 @@ export class ServerResponse extends http.ServerResponse {
|
|
|
485
505
|
headers = headers ? Object.assign(this.#headersObj, headers) : this.#headersObj
|
|
486
506
|
}
|
|
487
507
|
|
|
508
|
+
if (!this.destroyed) {
|
|
509
|
+
if (this.#headers === -1) {
|
|
510
|
+
this.#headers = performance.now() - this.#created
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
488
514
|
this.#headersObj = null
|
|
489
515
|
|
|
490
516
|
return super.writeHead(statusCode, headers)
|
|
@@ -503,15 +529,6 @@ export class ServerResponse extends http.ServerResponse {
|
|
|
503
529
|
return super.assignSocket(socket)
|
|
504
530
|
}
|
|
505
531
|
|
|
506
|
-
flushHeaders() {
|
|
507
|
-
if (!this.destroyed) {
|
|
508
|
-
if (this.#headers === -1) {
|
|
509
|
-
this.#headers = performance.now() - this.#created
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
return super.flushHeaders()
|
|
513
|
-
}
|
|
514
|
-
|
|
515
532
|
write(chunk, encoding, callback) {
|
|
516
533
|
if (!this.destroyed) {
|
|
517
534
|
if (this.#data === -1) {
|
|
@@ -584,13 +601,8 @@ export class Http2ServerRequest extends http2.Http2ServerRequest {
|
|
|
584
601
|
#search
|
|
585
602
|
#query
|
|
586
603
|
|
|
587
|
-
constructor(...args) {
|
|
588
|
-
super(...args)
|
|
589
|
-
this.#id = this.headers['request-id'] || this.headers['Request-Id'] || genReqId()
|
|
590
|
-
}
|
|
591
|
-
|
|
592
604
|
get id() {
|
|
593
|
-
return this.#id
|
|
605
|
+
return (this.#id ??= this.headers['request-id'] || this.headers['Request-Id'] || genReqId())
|
|
594
606
|
}
|
|
595
607
|
|
|
596
608
|
get target() {
|