diff --git a/package.json b/package.json index 3d15182a..ae6fa9cb 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "pump": "^3.0.0", "qs": "^6.11.2", "type-fest": "^4.3.1", - "undici": "^5.22.1", + "undici": "^5.28.2", "ylru": "^1.3.2" }, "devDependencies": { diff --git a/src/diagnosticsChannel.ts b/src/diagnosticsChannel.ts index e9731d19..51fe618f 100644 --- a/src/diagnosticsChannel.ts +++ b/src/diagnosticsChannel.ts @@ -54,6 +54,21 @@ Socket.prototype.destroy = function(err?: any) { return this[kDestroy](err); }; +function getRequestOpaque(request: DiagnosticsChannel.Request, kHandler?: symbol) { + if (!kHandler) return; + const handler = request[kHandler]; + // maxRedirects = 0 will get [Symbol(handler)]: RequestHandler { + // responseHeaders: null, + // opaque: { + // [Symbol(request id)]: 1, + // [Symbol(request start time)]: 465.0712921619415, + // [Symbol(enable request timing or not)]: true, + // [Symbol(request timing)]: [Object], + // [Symbol(request original opaque)]: undefined + // } + return handler?.opts?.opaque ?? handler?.opaque; +} + export function initDiagnosticsChannel() { // makre sure init global DiagnosticsChannel once if (initedDiagnosticsChannel) return; @@ -73,7 +88,7 @@ export function initDiagnosticsChannel() { } } } - const opaque = request[kHandler]?.opts?.opaque; + const opaque = getRequestOpaque(request, kHandler); // ignore non HttpClient Request if (!opaque || !opaque[symbols.kRequestId]) return; debug('[%s] Request#%d %s %s, path: %s, headers: %o', @@ -131,8 +146,7 @@ export function initDiagnosticsChannel() { // This message is published right before the first byte of the request is written to the socket. subscribe('undici:client:sendHeaders', (message, name) => { const { request, socket } = message as DiagnosticsChannel.ClientSendHeadersMessage; - if (!kHandler) return; - const opaque = request[kHandler]?.opts?.opaque; + const opaque = getRequestOpaque(request, kHandler); if (!opaque || !opaque[symbols.kRequestId]) return; socket[symbols.kHandledRequests]++; @@ -154,8 +168,7 @@ export function initDiagnosticsChannel() { subscribe('undici:request:bodySent', (message, name) => { const { request } = message as DiagnosticsChannel.RequestBodySentMessage; - if (!kHandler) return; - const opaque = request[kHandler]?.opts?.opaque; + const opaque = getRequestOpaque(request, kHandler); if (!opaque || !opaque[symbols.kRequestId]) return; debug('[%s] Request#%d send body', name, opaque[symbols.kRequestId]); @@ -166,8 +179,7 @@ export function initDiagnosticsChannel() { // This message is published after the response headers have been received, i.e. the response has been completed. subscribe('undici:request:headers', (message, name) => { const { request, response } = message as DiagnosticsChannel.RequestHeadersMessage; - if (!kHandler) return; - const opaque = request[kHandler]?.opts?.opaque; + const opaque = getRequestOpaque(request, kHandler); if (!opaque || !opaque[symbols.kRequestId]) return; // get socket from opaque @@ -184,8 +196,7 @@ export function initDiagnosticsChannel() { // This message is published after the response body and trailers have been received, i.e. the response has been completed. subscribe('undici:request:trailers', (message, name) => { const { request } = message as DiagnosticsChannel.RequestTrailersMessage; - if (!kHandler) return; - const opaque = request[kHandler]?.opts?.opaque; + const opaque = getRequestOpaque(request, kHandler); if (!opaque || !opaque[symbols.kRequestId]) return; debug('[%s] Request#%d get response body and trailers', name, opaque[symbols.kRequestId]); diff --git a/test/options.followRedirect.test.ts b/test/options.followRedirect.test.ts index 4841f1b6..f001101b 100644 --- a/test/options.followRedirect.test.ts +++ b/test/options.followRedirect.test.ts @@ -104,6 +104,9 @@ describe('options.followRedirect.test.js', () => { assert(!redirected); assert.equal(url, requestURL); assert.equal(res.headers.location, `${_url}redirect-full-301-to-url`); + assert(res.socket.remoteAddress === '127.0.0.1' || res.socket.remoteAddress === '::1'); + assert(res.socket.id > 0); + assert(res.timing.contentDownload > 0); }); // it('should redirect `location: http://other-domain` with headers.Host', function(done) {