◐ Shell
clean mode source ↗

inspector: support inspecting HTTP/2 request and response bodies · nodejs/node@d2087ba

@@ -14,12 +14,15 @@ const inspector = require('node:inspector/promises');

1414

const session = new inspector.Session();

1515

session.connect();

161617+

const requestBody = { 'hello': 'world' };

18+1719

const requestHeaders = {

1820

'x-header1': ['value1', 'value2'],

1921

[http2.constants.HTTP2_HEADER_ACCEPT_LANGUAGE]: 'en-US',

2022

[http2.constants.HTTP2_HEADER_AGE]: 1000,

23+

[http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'application/json; charset=utf-8',

2124

[http2.constants.HTTP2_HEADER_COOKIE]: ['k1=v1', 'k2=v2'],

22-

[http2.constants.HTTP2_HEADER_METHOD]: 'GET',

25+

[http2.constants.HTTP2_HEADER_METHOD]: 'POST',

2326

[http2.constants.HTTP2_HEADER_PATH]: '/hello-world',

2427

};

2528

@@ -54,23 +57,35 @@ const pushResponseHeaders = {

5457

[http2.constants.HTTP2_HEADER_STATUS]: 200,

5558

};

565960+

const styleCss = 'body { color: red; }\n';

61+

const serverResponse = 'hello world\n';

62+5763

const kTimeout = 1000;

5864

const kDelta = 200;

59656066

const handleStream = (stream, headers) => {

6167

const path = headers[http2.constants.HTTP2_HEADER_PATH];

68+

let body = '';

6269

switch (path) {

6370

case '/hello-world':

64-

stream.pushStream(pushRequestHeaders, common.mustSucceed((pushStream) => {

65-

pushStream.respond(pushResponseHeaders);

66-

pushStream.end('body { color: red; }\n');

67-

}));

71+

stream.on('data', (chunk) => {

72+

body += chunk;

73+

});

687469-

stream.respond(responseHeaders);

75+

stream.on('end', () => {

76+

assert.strictEqual(body, JSON.stringify(requestBody));

707771-

setTimeout(() => {

72-

stream.end('hello world\n');

73-

}, kTimeout);

78+

stream.pushStream(pushRequestHeaders, common.mustSucceed((pushStream) => {

79+

pushStream.respond(pushResponseHeaders);

80+

pushStream.end(styleCss);

81+

}));

82+83+

stream.respond(responseHeaders);

84+85+

setTimeout(() => {

86+

stream.end(serverResponse);

87+

}, kTimeout);

88+

});

7489

break;

7590

case '/trigger-error':

7691

stream.close(http2.constants.NGHTTP2_STREAM_CLOSED);

@@ -114,7 +129,6 @@ function verifyRequestWillBeSent({ method, params }, expectedUrl) {

114129115130

assert.ok(params.requestId.startsWith('node-network-event-'));

116131

assert.strictEqual(params.request.url, expectedUrl);

117-

assert.strictEqual(params.request.method, 'GET');

118132

assert.strictEqual(typeof params.request.headers, 'object');

119133120134

if (expectedUrl.endsWith('/hello-world')) {

@@ -123,10 +137,17 @@ function verifyRequestWillBeSent({ method, params }, expectedUrl) {

123137

assert.strictEqual(params.request.headers.age, '1000');

124138

assert.strictEqual(params.request.headers['x-header1'], 'value1, value2');

125139

assert.ok(findFrameInInitiator(__filename, params.initiator));

140+

assert.strictEqual(params.request.hasPostData, true);

141+

assert.strictEqual(params.request.method, 'POST');

126142

} else if (expectedUrl.endsWith('/style.css')) {

127143

assert.strictEqual(params.request.headers['x-header3'], 'value1, value2');

128144

assert.strictEqual(params.request.headers['x-push'], 'true');

129145

assert.ok(!findFrameInInitiator(__filename, params.initiator));

146+

assert.strictEqual(params.request.hasPostData, true);

147+

assert.strictEqual(params.request.method, 'GET');

148+

} else {

149+

assert.strictEqual(params.request.hasPostData, false);

150+

assert.strictEqual(params.request.method, 'GET');

130151

}

131152132153

assert.strictEqual(typeof params.timestamp, 'number');

@@ -198,6 +219,8 @@ async function testHttp2(secure = false) {

198219

rejectUnauthorized: false,

199220

});

200221

const request = client.request(requestHeaders);

222+

request.write(JSON.stringify(requestBody));

223+

request.end();

201224202225

// Dump the responses.

203226

request.on('data', () => {});

@@ -216,6 +239,11 @@ async function testHttp2(secure = false) {

216239

verifyRequestWillBeSent(mainRequest, url);

217240

verifyRequestWillBeSent(pushRequest, pushedUrl);

218241242+

const { postData } = await session.post('Network.getRequestPostData', {

243+

requestId: mainRequest.params.requestId

244+

});

245+

assert.strictEqual(postData, JSON.stringify(requestBody));

246+219247

const [

220248

{ value: [ mainResponse ] },

221249

{ value: [ pushResponse ] },

@@ -230,6 +258,18 @@ async function testHttp2(secure = false) {

230258

verifyLoadingFinished(event1);

231259

verifyLoadingFinished(event2);

232260261+

const responseBody = await session.post('Network.getResponseBody', {

262+

requestId: mainRequest.params.requestId,

263+

});

264+

assert.strictEqual(responseBody.base64Encoded, false);

265+

assert.strictEqual(responseBody.body, serverResponse);

266+267+

const pushResponseBody = await session.post('Network.getResponseBody', {

268+

requestId: pushRequest.params.requestId,

269+

});

270+

assert.strictEqual(pushResponseBody.base64Encoded, true);

271+

assert.strictEqual(Buffer.from(pushResponseBody.body, 'base64').toString(), styleCss);

272+233273

const mainFinished = [event1, event2]

234274

.find((event) => event.params.requestId === mainResponse.params.requestId);

235275

const pushFinished = [event1, event2]