inspector: fix absolute URLs in network http · nodejs/node@1718bc3
@@ -32,9 +32,28 @@ const setResponseHeaders = (res) => {
32323333const kTimeout = 1000;
3434const kDelta = 200;
35+const kDefaultResponseHeaders = {
36+'server': 'node',
37+'etag': '12345',
38+'set-cookie': 'key1=value1\nkey2=value2',
39+'x-header2': 'value1, value2',
40+};
41+42+function getDefaultResponseExpect(url) {
43+return {
44+ url,
45+mimeType: 'text/plain',
46+charset: 'utf-8',
47+responseHeaders: kDefaultResponseHeaders,
48+};
49+}
50+51+function getPathName(req) {
52+return new URL(req.url, `http://${req.headers.host}`).pathname;
53+}
35543655const handleRequest = (req, res) => {
37-const path = req.url;
56+const path = getPathName(req);
3857switch (path) {
3958case '/hello-world':
4059setResponseHeaders(res);
@@ -46,6 +65,22 @@ const handleRequest = (req, res) => {
4665res.end('hello world\n');
4766}, kTimeout);
4867break;
68+case '/echo-post': {
69+const chunks = [];
70+req.on('data', (chunk) => {
71+chunks.push(chunk);
72+});
73+req.on('end', () => {
74+const body = Buffer.concat(chunks).toString();
75+res.setHeader('Content-Type', 'application/json; charset=utf-8');
76+res.writeHead(200);
77+res.end(JSON.stringify({
78+method: req.method,
79+ body,
80+}));
81+});
82+break;
83+}
4984default:
5085assert.fail(`Unexpected path: ${path}`);
5186}
@@ -77,7 +112,7 @@ function verifyRequestWillBeSent({ method, params }, expect) {
7711278113assert.ok(params.requestId.startsWith('node-network-event-'));
79114assert.strictEqual(params.request.url, expect.url);
80-assert.strictEqual(params.request.method, 'GET');
115+assert.strictEqual(params.request.method, expect.method ?? 'GET');
81116assert.strictEqual(typeof params.request.headers, 'object');
82117assert.strictEqual(params.request.headers['accept-language'], 'en-US');
83118assert.strictEqual(params.request.headers.cookie, 'k1=v1; k2=v2');
@@ -103,12 +138,20 @@ function verifyResponseReceived({ method, params }, expect) {
103138assert.strictEqual(params.response.statusText, 'OK');
104139assert.strictEqual(params.response.url, expect.url);
105140assert.strictEqual(typeof params.response.headers, 'object');
106-assert.strictEqual(params.response.headers.server, 'node');
107-assert.strictEqual(params.response.headers.etag, '12345');
108-assert.strictEqual(params.response.headers['set-cookie'], 'key1=value1\nkey2=value2');
109-assert.strictEqual(params.response.headers['x-header2'], 'value1, value2');
110-assert.strictEqual(params.response.mimeType, 'text/plain');
111-assert.strictEqual(params.response.charset, 'utf-8');
141+if (expect.responseHeaders?.server) {
142+assert.strictEqual(params.response.headers.server, expect.responseHeaders.server);
143+}
144+if (expect.responseHeaders?.etag) {
145+assert.strictEqual(params.response.headers.etag, expect.responseHeaders.etag);
146+}
147+if (expect.responseHeaders?.['set-cookie']) {
148+assert.strictEqual(params.response.headers['set-cookie'], expect.responseHeaders['set-cookie']);
149+}
150+if (expect.responseHeaders?.['x-header2']) {
151+assert.strictEqual(params.response.headers['x-header2'], expect.responseHeaders['x-header2']);
152+}
153+assert.strictEqual(params.response.mimeType, expect.mimeType);
154+assert.strictEqual(params.response.charset, expect.charset);
112155113156return params;
114157}
@@ -151,17 +194,46 @@ function verifyHttpResponse(response) {
151194}));
152195}
153196154-async function testHttpGet() {
155-const url = `http://127.0.0.1:${httpServer.address().port}/hello-world`;
197+function drainHttpResponse(response) {
198+response.resume();
199+}
200+201+function createRequestTracker(url, responseExpect, requestExpect = {}) {
156202const requestWillBeSentFuture = once(session, 'Network.requestWillBeSent')
157-.then(([event]) => verifyRequestWillBeSent(event, { url }));
203+.then(([event]) => verifyRequestWillBeSent(event, {
204+ url,
205+method: requestExpect.method,
206+}));
158207159208const responseReceivedFuture = once(session, 'Network.responseReceived')
160-.then(([event]) => verifyResponseReceived(event, { url }));
209+.then(([event]) => verifyResponseReceived(event, responseExpect));
161210162211const loadingFinishedFuture = once(session, 'Network.loadingFinished')
163212.then(([event]) => verifyLoadingFinished(event));
164213214+return {
215+ requestWillBeSentFuture,
216+ responseReceivedFuture,
217+ loadingFinishedFuture,
218+};
219+}
220+221+async function assertResponseBody(responseReceived, expectedBody, expectedBase64Encoded = false) {
222+const responseBody = await session.post('Network.getResponseBody', {
223+requestId: responseReceived.requestId,
224+});
225+assert.strictEqual(responseBody.base64Encoded, expectedBase64Encoded);
226+assert.strictEqual(responseBody.body, expectedBody);
227+}
228+229+async function testHttpGet() {
230+const url = `http://127.0.0.1:${httpServer.address().port}/hello-world`;
231+const {
232+ requestWillBeSentFuture,
233+ responseReceivedFuture,
234+ loadingFinishedFuture,
235+} = createRequestTracker(url, getDefaultResponseExpect(url));
236+165237http.get({
166238host: '127.0.0.1',
167239port: httpServer.address().port,
@@ -175,24 +247,83 @@ async function testHttpGet() {
175247176248const delta = (loadingFinished.timestamp - responseReceived.timestamp) * 1000;
177249assert.ok(delta > kDelta);
250+await assertResponseBody(responseReceived, '\nhello world\n');
251+}
178252179-const responseBody = await session.post('Network.getResponseBody', {
180-requestId: responseReceived.requestId,
253+async function testHttpGetWithAbsoluteUrlPath() {
254+const url = `http://127.0.0.1:${httpServer.address().port}/hello-world`;
255+const {
256+ requestWillBeSentFuture,
257+ responseReceivedFuture,
258+ loadingFinishedFuture,
259+} = createRequestTracker(url, getDefaultResponseExpect(url));
260+261+http.get({
262+host: '127.0.0.1',
263+port: httpServer.address().port,
264+path: url,
265+headers: requestHeaders,
266+}, common.mustCall(verifyHttpResponse));
267+268+await requestWillBeSentFuture;
269+const responseReceived = await responseReceivedFuture;
270+const loadingFinished = await loadingFinishedFuture;
271+272+const delta = (loadingFinished.timestamp - responseReceived.timestamp) * 1000;
273+assert.ok(delta > kDelta);
274+await assertResponseBody(responseReceived, '\nhello world\n');
275+}
276+277+async function testHttpPostWithAbsoluteUrlPath() {
278+const requestBody = JSON.stringify({ title: 'foo', type: 'post' });
279+const url = `http://127.0.0.1:${httpServer.address().port}/echo-post`;
280+const {
281+ requestWillBeSentFuture,
282+ responseReceivedFuture,
283+ loadingFinishedFuture,
284+} = createRequestTracker(url, {
285+ url,
286+mimeType: 'application/json',
287+charset: 'utf-8',
288+}, {
289+method: 'POST',
181290});
182-assert.strictEqual(responseBody.base64Encoded, false);
183-assert.strictEqual(responseBody.body, '\nhello world\n');
291+292+const responsePromise = new Promise((resolve, reject) => {
293+const req = http.request({
294+host: '127.0.0.1',
295+port: httpServer.address().port,
296+path: url,
297+method: 'POST',
298+headers: {
299+ ...requestHeaders,
300+'Content-Type': 'application/json',
301+'Content-Length': Buffer.byteLength(requestBody),
302+},
303+}, resolve);
304+req.on('error', reject);
305+req.end(requestBody);
306+});
307+308+const response = await responsePromise;
309+drainHttpResponse(response);
310+311+await requestWillBeSentFuture;
312+const responseReceived = await responseReceivedFuture;
313+await loadingFinishedFuture;
314+await assertResponseBody(responseReceived, JSON.stringify({
315+method: 'POST',
316+body: requestBody,
317+}));
184318}
185319186320async function testHttpsGet() {
187321const url = `https://127.0.0.1:${httpsServer.address().port}/hello-world`;
188-const requestWillBeSentFuture = once(session, 'Network.requestWillBeSent')
189-.then(([event]) => verifyRequestWillBeSent(event, { url }));
190-191-const responseReceivedFuture = once(session, 'Network.responseReceived')
192-.then(([event]) => verifyResponseReceived(event, { url }));
193-194-const loadingFinishedFuture = once(session, 'Network.loadingFinished')
195-.then(([event]) => verifyLoadingFinished(event));
322+const {
323+ requestWillBeSentFuture,
324+ responseReceivedFuture,
325+ loadingFinishedFuture,
326+} = createRequestTracker(url, getDefaultResponseExpect(url));
196327197328https.get({
198329host: '127.0.0.1',
@@ -208,12 +339,7 @@ async function testHttpsGet() {
208339209340const delta = (loadingFinished.timestamp - responseReceived.timestamp) * 1000;
210341assert.ok(delta > kDelta);
211-212-const responseBody = await session.post('Network.getResponseBody', {
213-requestId: responseReceived.requestId,
214-});
215-assert.strictEqual(responseBody.base64Encoded, false);
216-assert.strictEqual(responseBody.body, '\nhello world\n');
342+await assertResponseBody(responseReceived, '\nhello world\n');
217343}
218344219345async function testHttpError() {
@@ -257,6 +383,10 @@ async function testHttpsError() {
257383const testNetworkInspection = async () => {
258384await testHttpGet();
259385session.removeAllListeners();
386+await testHttpGetWithAbsoluteUrlPath();
387+session.removeAllListeners();
388+await testHttpPostWithAbsoluteUrlPath();
389+session.removeAllListeners();
260390await testHttpsGet();
261391session.removeAllListeners();
262392await testHttpError();