From 0aad863e0eb8a206555194614f2432daaf5dbbba Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Tue, 4 Nov 2025 10:58:51 +0000 Subject: [PATCH] inspector: inspect HTTP response body --- lib/internal/inspector/network_http.js | 12 ++++++ test/parallel/test-inspector-network-http.js | 45 +++++++++++++++----- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/internal/inspector/network_http.js b/lib/internal/inspector/network_http.js index fcfac2e6394e37..8d324c8c544eea 100644 --- a/lib/internal/inspector/network_http.js +++ b/lib/internal/inspector/network_http.js @@ -17,6 +17,7 @@ const { sniffMimeType, } = require('internal/inspector/network'); const { Network } = require('inspector'); +const EventEmitter = require('events'); const kRequestUrl = Symbol('kRequestUrl'); @@ -120,6 +121,17 @@ function onClientResponseFinish({ request, response }) { }, }); + // Unlike response.on('data', ...), this does not put the stream into flowing mode. + EventEmitter.prototype.on.call(response, 'data', (chunk) => { + Network.dataReceived({ + requestId: request[kInspectorRequestId], + timestamp: getMonotonicTime(), + dataLength: chunk.byteLength, + encodedDataLength: chunk.byteLength, + data: chunk, + }); + }); + // Wait until the response body is consumed by user code. response.once('end', () => { Network.loadingFinished({ diff --git a/test/parallel/test-inspector-network-http.js b/test/parallel/test-inspector-network-http.js index 1dd4a65fc0dd72..74c6488ef399a5 100644 --- a/test/parallel/test-inspector-network-http.js +++ b/test/parallel/test-inspector-network-http.js @@ -130,6 +130,27 @@ function verifyLoadingFailed({ method, params }) { assert.strictEqual(typeof params.errorText, 'string'); } +function verifyHttpResponse(response) { + assert.strictEqual(response.statusCode, 200); + const chunks = []; + + // Verifies that the inspector does not put the response into flowing mode. + assert.strictEqual(response.readableFlowing, null); + // Verifies that the data listener may be added at a later time, and it can + // still observe the data in full. + queueMicrotask(() => { + response.on('data', (chunk) => { + chunks.push(chunk); + }); + assert.strictEqual(response.readableFlowing, true); + }); + + response.on('end', common.mustCall(() => { + const body = Buffer.concat(chunks).toString(); + assert.strictEqual(body, '\nhello world\n'); + })); +} + async function testHttpGet() { const url = `http://127.0.0.1:${httpServer.address().port}/hello-world`; const requestWillBeSentFuture = once(session, 'Network.requestWillBeSent') @@ -146,11 +167,7 @@ async function testHttpGet() { port: httpServer.address().port, path: '/hello-world', headers: requestHeaders - }, common.mustCall((res) => { - // Dump the response. - res.on('data', () => {}); - res.on('end', () => {}); - })); + }, common.mustCall(verifyHttpResponse)); await requestWillBeSentFuture; const responseReceived = await responseReceivedFuture; @@ -158,6 +175,12 @@ async function testHttpGet() { const delta = (loadingFinished.timestamp - responseReceived.timestamp) * 1000; assert.ok(delta > kDelta); + + const responseBody = await session.post('Network.getResponseBody', { + requestId: responseReceived.requestId, + }); + assert.strictEqual(responseBody.base64Encoded, false); + assert.strictEqual(responseBody.body, '\nhello world\n'); } async function testHttpsGet() { @@ -177,11 +200,7 @@ async function testHttpsGet() { path: '/hello-world', rejectUnauthorized: false, headers: requestHeaders, - }, common.mustCall((res) => { - // Dump the response. - res.on('data', () => {}); - res.on('end', () => {}); - })); + }, common.mustCall(verifyHttpResponse)); await requestWillBeSentFuture; const responseReceived = await responseReceivedFuture; @@ -189,6 +208,12 @@ async function testHttpsGet() { const delta = (loadingFinished.timestamp - responseReceived.timestamp) * 1000; assert.ok(delta > kDelta); + + const responseBody = await session.post('Network.getResponseBody', { + requestId: responseReceived.requestId, + }); + assert.strictEqual(responseBody.base64Encoded, false); + assert.strictEqual(responseBody.body, '\nhello world\n'); } async function testHttpError() {