From 4052deaae0fc9645ad8876b81e08f027799bab2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Rzepecki?= Date: Tue, 28 Nov 2023 20:22:09 +0100 Subject: [PATCH 1/2] fix: Correct capitalisation of HTTP headers Node lower-cases HTTP headers, but in AppMaps they should have the canonical capitalisation (X-Like-This). --- src/hooks/http.ts | 13 ++++-- test/__snapshots__/express.test.ts.snap | 54 +++++++++++----------- test/__snapshots__/httpClient.test.ts.snap | 20 ++++---- test/helpers.ts | 16 +++---- 4 files changed, 55 insertions(+), 48 deletions(-) diff --git a/src/hooks/http.ts b/src/hooks/http.ts index 18c5e060..2131795a 100644 --- a/src/hooks/http.ts +++ b/src/hooks/http.ts @@ -156,10 +156,13 @@ function normalizeHeaders( ): Record | undefined { const result: Record = {}; - for (const [k, v] of Object.entries(headers)) + for (const [k, v] of Object.entries(headers)) { if (v === undefined) continue; - else if (v instanceof Array) result[k] = v.join("\n"); - else result[k] = String(v); + + const key = k.split("-").map(capitalize).join("-"); + if (v instanceof Array) result[key] = v.join("\n"); + else result[key] = String(v); + } return result; } @@ -176,3 +179,7 @@ function handleResponse( normalizeHeaders(response.getHeaders()), ); } + +function capitalize(str: string): string { + return str[0].toUpperCase() + str.slice(1).toLowerCase(); +} diff --git a/test/__snapshots__/express.test.ts.snap b/test/__snapshots__/express.test.ts.snap index 6802cefe..c649eae0 100644 --- a/test/__snapshots__/express.test.ts.snap +++ b/test/__snapshots__/express.test.ts.snap @@ -39,9 +39,9 @@ exports[`mapping Express.js requests 1`] = ` "event": "call", "http_server_request": { "headers": { - "content-type": "application/json", - "host": "localhost:27627", - "transfer-encoding": "chunked", + "Content-Type": "application/json", + "Host": "localhost:27627", + "Transfer-Encoding": "chunked", }, "normalized_path_info": "/api/:ident", "path_info": "/api/bar", @@ -109,7 +109,7 @@ exports[`mapping Express.js requests 1`] = ` "event": "call", "http_server_request": { "headers": { - "host": "localhost:27627", + "Host": "localhost:27627", }, "normalized_path_info": "/api/:ident", "path_info": "/api/foo", @@ -142,7 +142,7 @@ exports[`mapping Express.js requests 1`] = ` "event": "call", "http_server_request": { "headers": { - "host": "localhost:27627", + "Host": "localhost:27627", }, "path_info": "/", "protocol": "HTTP/1.1", @@ -191,10 +191,10 @@ exports[`mapping Express.js requests 1`] = ` "event": "return", "http_server_response": { "headers": { - "content-length": "12", - "content-type": "text/html; charset=utf-8", - "etag": "W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE"", - "x-powered-by": "Express", + "Content-Length": "12", + "Content-Type": "text/html; charset=utf-8", + "Etag": "W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE"", + "X-Powered-By": "Express", }, "status_code": 200, }, @@ -206,7 +206,7 @@ exports[`mapping Express.js requests 1`] = ` "event": "call", "http_server_request": { "headers": { - "host": "localhost:27627", + "Host": "localhost:27627", }, "path_info": "/nonexistent", "protocol": "HTTP/1.1", @@ -220,11 +220,11 @@ exports[`mapping Express.js requests 1`] = ` "event": "return", "http_server_response": { "headers": { - "content-length": "150", - "content-security-policy": "default-src 'none'", - "content-type": "text/html; charset=utf-8", - "x-content-type-options": "nosniff", - "x-powered-by": "Express", + "Content-Length": "150", + "Content-Security-Policy": "default-src 'none'", + "Content-Type": "text/html; charset=utf-8", + "X-Content-Type-Options": "nosniff", + "X-Powered-By": "Express", }, "status_code": 404, }, @@ -236,7 +236,7 @@ exports[`mapping Express.js requests 1`] = ` "event": "call", "http_server_request": { "headers": { - "host": "localhost:27627", + "Host": "localhost:27627", }, "path_info": "/api/foo", "protocol": "HTTP/1.1", @@ -316,10 +316,10 @@ exports[`mapping Express.js requests 1`] = ` "event": "return", "http_server_response": { "headers": { - "content-length": "42", - "content-type": "application/json; charset=utf-8", - "etag": "W/"2a-YHNH/nKM8UUG4pNEEtm91sktuKc"", - "x-powered-by": "Express", + "Content-Length": "42", + "Content-Type": "application/json; charset=utf-8", + "Etag": "W/"2a-YHNH/nKM8UUG4pNEEtm91sktuKc"", + "X-Powered-By": "Express", }, "status_code": 200, }, @@ -331,9 +331,9 @@ exports[`mapping Express.js requests 1`] = ` "event": "call", "http_server_request": { "headers": { - "content-type": "application/json", - "host": "localhost:27627", - "transfer-encoding": "chunked", + "Content-Type": "application/json", + "Host": "localhost:27627", + "Transfer-Encoding": "chunked", }, "path_info": "/api/bar", "protocol": "HTTP/1.1", @@ -467,10 +467,10 @@ exports[`mapping Express.js requests 1`] = ` "event": "return", "http_server_response": { "headers": { - "content-length": "99", - "content-type": "application/json; charset=utf-8", - "etag": "W/"63-avsgRi3I+MK54okDiWb1V4/K3j8"", - "x-powered-by": "Express", + "Content-Length": "99", + "Content-Type": "application/json; charset=utf-8", + "Etag": "W/"63-avsgRi3I+MK54okDiWb1V4/K3j8"", + "X-Powered-By": "Express", }, "status_code": 200, }, diff --git a/test/__snapshots__/httpClient.test.ts.snap b/test/__snapshots__/httpClient.test.ts.snap index 9b21579f..b31389ac 100644 --- a/test/__snapshots__/httpClient.test.ts.snap +++ b/test/__snapshots__/httpClient.test.ts.snap @@ -64,8 +64,8 @@ exports[`mapping http client requests 1`] = ` "event": "call", "http_client_request": { "headers": { - "host": "localhost:27628", - "test-header": "This test header is added after ClientRequest creation", + "Host": "localhost:27628", + "Test-Header": "This test header is added after ClientRequest creation", }, "request_method": "GET", "url": "http://localhost:27628/endpoint/one", @@ -78,7 +78,7 @@ exports[`mapping http client requests 1`] = ` "event": "return", "http_client_response": { "headers": { - "transfer-encoding": "chunked", + "Transfer-Encoding": "chunked", }, "status_code": 200, }, @@ -90,8 +90,8 @@ exports[`mapping http client requests 1`] = ` "event": "call", "http_client_request": { "headers": { - "content-type": "application/json", - "host": "localhost:27628", + "Content-Type": "application/json", + "Host": "localhost:27628", }, "request_method": "POST", "url": "http://localhost:27628/endpoint/two", @@ -104,8 +104,8 @@ exports[`mapping http client requests 1`] = ` "event": "return", "http_client_response": { "headers": { - "content-type": "text/html", - "transfer-encoding": "chunked", + "Content-Type": "text/html", + "Transfer-Encoding": "chunked", }, "status_code": 404, }, @@ -117,7 +117,7 @@ exports[`mapping http client requests 1`] = ` "event": "call", "http_client_request": { "headers": { - "host": "localhost:27628", + "Host": "localhost:27628", }, "request_method": "GET", "url": "http://localhost:27628/endpoint/three", @@ -130,8 +130,8 @@ exports[`mapping http client requests 1`] = ` "event": "return", "http_client_response": { "headers": { - "content-type": "text/html", - "transfer-encoding": "chunked", + "Content-Type": "text/html", + "Transfer-Encoding": "chunked", }, "status_code": 404, }, diff --git a/test/helpers.ts b/test/helpers.ts index dfb7b55a..861c4b27 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -83,10 +83,10 @@ function fixEvent(event: unknown) { "headers" in event.http_server_request && typeof event.http_server_request.headers === "object" && event.http_server_request.headers && - "connection" in event.http_server_request.headers + "Connection" in event.http_server_request.headers ) // the default of this varies between node versions - delete event.http_server_request.headers.connection; + delete event.http_server_request.headers.Connection; if ( "http_client_response" in event && @@ -96,12 +96,12 @@ function fixEvent(event: unknown) { typeof event.http_client_response.headers === "object" && event.http_client_response.headers ) { - if ("date" in event.http_client_response.headers) - delete event.http_client_response.headers.date; - if ("connection" in event.http_client_response.headers) - delete event.http_client_response.headers.connection; - if ("keep-alive" in event.http_client_response.headers) - delete event.http_client_response.headers["keep-alive"]; + if ("Date" in event.http_client_response.headers) + delete event.http_client_response.headers.Date; + if ("Connection" in event.http_client_response.headers) + delete event.http_client_response.headers.Connection; + if ("Keep-Alive" in event.http_client_response.headers) + delete event.http_client_response.headers["Keep-Alive"]; } if ("elapsed" in event && typeof event.elapsed === "number") event.elapsed = 31.337; } From 982f4b1e77bbe6d8f9eb3d2ef56f24d6a0ce8c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Rzepecki?= Date: Thu, 30 Nov 2023 14:52:14 +0100 Subject: [PATCH 2/2] fix: Handle HTTP requests intercepted by nock Fixes #47 --- .../nock-npm-13.4.0-200f928100-30c3751854.zip | Bin 0 -> 60979 bytes ...pagate-npm-2.0.1-2074bf76d3-c4febaee2b.zip | Bin 0 -> 5867 bytes package.json | 1 + src/AppMap.d.ts | 2 +- src/hooks/http.ts | 18 +- test/__snapshots__/httpClient.test.ts.snap | 184 +++++++++++++++++- test/helpers.ts | 12 +- test/httpClient.test.ts | 11 +- test/httpClient/index.ts | 12 ++ test/httpClient/package.json | 8 + yarn.lock | 26 +++ 11 files changed, 263 insertions(+), 11 deletions(-) create mode 100644 .yarn/cache/nock-npm-13.4.0-200f928100-30c3751854.zip create mode 100644 .yarn/cache/propagate-npm-2.0.1-2074bf76d3-c4febaee2b.zip create mode 100644 test/httpClient/package.json diff --git a/.yarn/cache/nock-npm-13.4.0-200f928100-30c3751854.zip b/.yarn/cache/nock-npm-13.4.0-200f928100-30c3751854.zip new file mode 100644 index 0000000000000000000000000000000000000000..41f8bda10a27553241527e27ea3dfa66fcfab2cc GIT binary patch literal 60979 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 literal 0 HcmV?d00001 diff --git a/.yarn/cache/propagate-npm-2.0.1-2074bf76d3-c4febaee2b.zip b/.yarn/cache/propagate-npm-2.0.1-2074bf76d3-c4febaee2b.zip new file mode 100644 index 0000000000000000000000000000000000000000..2a4a26dfd3e19398bdbd88cd51b4848111edd4eb GIT binary patch literal 5867 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 literal 0 HcmV?d00001 diff --git a/package.json b/package.json index cd65f377..e99b7386 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ }, "workspaces": [ "test/express", + "test/httpClient", "test/jest", "test/mocha", "test/vitest", diff --git a/src/AppMap.d.ts b/src/AppMap.d.ts index 62d8390b..5e77d746 100644 --- a/src/AppMap.d.ts +++ b/src/AppMap.d.ts @@ -190,7 +190,7 @@ namespace AppMap { export type Event = CallEvent | ReturnEvent; export interface AppMap { - version: "1.12"; + version: string; metadata?: Metadata; classMap: ClassMap; events?: Event[]; diff --git a/src/hooks/http.ts b/src/hooks/http.ts index 2131795a..94dfaead 100644 --- a/src/hooks/http.ts +++ b/src/hooks/http.ts @@ -62,7 +62,7 @@ function handleClientRequest(request: http.ClientRequest) { const startTime = getTime(); request.on("finish", () => { - const url = new URL(`${request.protocol}//${request.host}${request.path}`); + const url = extractRequestURL(request); // Setting port to the default port for the protocol makes it empty string. // See: https://nodejs.org/api/url.html#urlport url.port = request.socket?.remotePort + ""; @@ -78,6 +78,17 @@ function handleClientRequest(request: http.ClientRequest) { }); } +function extractRequestURL(request: ClientRequest): URL { + let { protocol, host } = request; + /* nock OverridenClientRequest stores protocol and host on options instead */ + if ("options" in request && request.options && typeof request.options === "object") { + protocol = getStringField(request.options, "protocol") ?? protocol; + host = getStringField(request.options, "host") ?? host; + } + + return new URL(`${protocol}//${host}${request.path}`); +} + function handleClientResponse( requestEvent: AppMap.HttpClientRequestEvent, startTime: number, @@ -136,6 +147,11 @@ function getNormalizedPath(req: http.IncomingMessage) { } } +function getStringField(obj: object, field: string): string | undefined { + const v = getField(obj, field); + if (v && typeof v === "string") return v; +} + function getField(obj: object, field: string): unknown { if (field in obj) return (obj as never)[field]; } diff --git a/test/__snapshots__/httpClient.test.ts.snap b/test/__snapshots__/httpClient.test.ts.snap index b31389ac..7f26d139 100644 --- a/test/__snapshots__/httpClient.test.ts.snap +++ b/test/__snapshots__/httpClient.test.ts.snap @@ -8,7 +8,7 @@ exports[`mapping http client requests 1`] = ` { "children": [ { - "location": "./index.ts:18", + "location": "./index.ts:19", "name": "makeRequests", "static": true, "type": "function", @@ -41,7 +41,7 @@ exports[`mapping http client requests 1`] = ` "defined_class": "", "event": "call", "id": 1, - "lineno": 18, + "lineno": 19, "method_id": "makeRequests", "parameters": [], "path": "./index.ts", @@ -141,7 +141,185 @@ exports[`mapping http client requests 1`] = ` }, ], "metadata": { - "app": "appmap-node", + "app": "http-client-appmap-node-test", + "client": { + "name": "appmap-node", + "url": "https://github.com/getappmap/appmap-node", + "version": "test node-appmap version", + }, + "language": { + "engine": "Node.js", + "name": "javascript", + "version": "test node version", + }, + "name": "test process recording", + "recorder": { + "name": "process", + "type": "process", + }, + }, + "version": "1.12", +} +`; + +exports[`mapping mocked http client requests 1`] = ` +{ + "classMap": [ + { + "children": [ + { + "children": [ + { + "location": "./index.ts:19", + "name": "makeRequests", + "static": true, + "type": "function", + }, + { + "location": "./index.ts:39", + "name": "mock", + "static": true, + "type": "function", + }, + ], + "name": "index", + "type": "class", + }, + ], + "name": "index", + "type": "package", + }, + ], + "eventUpdates": { + "4": { + "elapsed": 31.337, + "event": "return", + "id": 4, + "parent_id": 3, + "return_value": { + "class": "Promise", + "object_id": 1, + "value": "Promise { undefined }", + }, + "thread_id": 0, + }, + }, + "events": [ + { + "defined_class": "", + "event": "call", + "id": 1, + "lineno": 39, + "method_id": "mock", + "parameters": [], + "path": "./index.ts", + "static": true, + "thread_id": 0, + }, + { + "elapsed": 31.337, + "event": "return", + "id": 2, + "parent_id": 1, + "thread_id": 0, + }, + { + "defined_class": "", + "event": "call", + "id": 3, + "lineno": 19, + "method_id": "makeRequests", + "parameters": [], + "path": "./index.ts", + "static": true, + "thread_id": 0, + }, + { + "elapsed": 31.337, + "event": "return", + "id": 4, + "parent_id": 3, + "return_value": { + "class": "Promise", + "object_id": 1, + "value": "Promise { }", + }, + "thread_id": 0, + }, + { + "event": "call", + "http_client_request": { + "headers": { + "Host": "localhost:27628", + "Test-Header": "This test header is added after ClientRequest creation", + }, + "url": "http://localhost:27628/endpoint/one", + }, + "id": 5, + "thread_id": 0, + }, + { + "elapsed": 31.337, + "event": "return", + "http_client_response": { + "headers": {}, + "status_code": 200, + }, + "id": 6, + "parent_id": 5, + "thread_id": 0, + }, + { + "event": "call", + "http_client_request": { + "headers": { + "Content-Type": "application/json", + "Host": "localhost:27628", + }, + "request_method": "POST", + "url": "http://localhost:27628/endpoint/two", + }, + "id": 7, + "thread_id": 0, + }, + { + "elapsed": 31.337, + "event": "return", + "http_client_response": { + "headers": {}, + "status_code": 200, + }, + "id": 8, + "parent_id": 7, + "thread_id": 0, + }, + { + "event": "call", + "http_client_request": { + "headers": { + "Host": "localhost:27628", + }, + "url": "http://localhost:27628/endpoint/three", + }, + "id": 9, + "thread_id": 0, + }, + { + "elapsed": 31.337, + "event": "return", + "http_client_response": { + "headers": { + "Content-Type": "text/html", + }, + "status_code": 404, + }, + "id": 10, + "parent_id": 9, + "thread_id": 0, + }, + ], + "metadata": { + "app": "http-client-appmap-node-test", "client": { "name": "appmap-node", "url": "https://github.com/getappmap/appmap-node", diff --git a/test/helpers.ts b/test/helpers.ts index 861c4b27..416b16c4 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -43,7 +43,7 @@ export function integrationTest(name: string, fn?: jest.ProvidesCallback, timeou type AppMap = object & Record<"events", unknown>; -export function readAppmap(path?: string): AppMap { +export function readAppmap(path?: string): AppMap.AppMap { if (!path) { const files = globSync(resolve(target, "tmp/**/*.appmap.json")); expect(files.length).toBe(1); @@ -54,18 +54,20 @@ export function readAppmap(path?: string): AppMap { assert(typeof result === "object" && result && "events" in result); assert(result.events instanceof Array); result.events.forEach(fixEvent); - if ("classMap" in result && result.classMap instanceof Array) fixClassMap(result.classMap); + assert("classMap" in result && result.classMap instanceof Array); + assert("version" in result && typeof result.version === "string"); + fixClassMap(result.classMap); if ("metadata" in result && typeof result.metadata === "object" && result.metadata) fixMetadata(result.metadata as AppMap.Metadata); if ("eventUpdates" in result && typeof result.eventUpdates === "object" && result.eventUpdates) Object.values(result.eventUpdates).forEach(fixEvent); - return result; + return result as AppMap.AppMap; } -export function readAppmaps(): Record { +export function readAppmaps(): Record { const files = globSync(resolve(target, "tmp/**/*.appmap.json")); - const maps = files.map<[string, AppMap]>((path) => [fixPath(path), readAppmap(path)]); + const maps = files.map<[string, AppMap.AppMap]>((path) => [fixPath(path), readAppmap(path)]); return Object.fromEntries(maps); } diff --git a/test/httpClient.test.ts b/test/httpClient.test.ts index 61e0c33c..2e3044e5 100644 --- a/test/httpClient.test.ts +++ b/test/httpClient.test.ts @@ -1,6 +1,6 @@ import http from "node:http"; -import { integrationTest, readAppmap, spawnAppmapNode } from "./helpers"; +import { integrationTest, readAppmap, runAppmapNode, spawnAppmapNode } from "./helpers"; import { SERVER_PORT, TEST_HEADER_VALUE } from "./httpClient"; integrationTest("mapping http client requests", async () => { @@ -24,3 +24,12 @@ integrationTest("mapping http client requests", async () => { expect(JSON.stringify(appMap.events)).toContain(TEST_HEADER_VALUE); expect(appMap).toMatchSnapshot(); }); + +integrationTest("mapping mocked http client requests", () => { + expect(runAppmapNode("yarn", "exec", "ts-node", "index.ts", "--mock").status).toBe(0); + const appMap = readAppmap(); + + // Make sure we capture the headers modified/added after ClientRequest creation. + expect(JSON.stringify(appMap.events)).toContain(TEST_HEADER_VALUE); + expect(appMap).toMatchSnapshot(); +}); diff --git a/test/httpClient/index.ts b/test/httpClient/index.ts index 0f8916ad..16568b1d 100644 --- a/test/httpClient/index.ts +++ b/test/httpClient/index.ts @@ -1,4 +1,5 @@ import http, { ClientRequest } from "node:http"; +import nock from "nock"; export const SERVER_PORT = 27628; export const TEST_HEADER_VALUE = "This test header is added after ClientRequest creation"; @@ -35,4 +36,15 @@ async function makeRequests() { await consume(r3); } +function mock() { + const n = nock(`http://localhost:${SERVER_PORT}`); + n.get("/endpoint/one").reply(200, "Hello World!"); + n.post("/endpoint/two?p1=v1&p2=v2").reply(200, "Hello World!"); + n.get("/endpoint/three").reply(404, undefined, { "Content-Type": "text/html" }); +} + +if (process.argv.includes("--mock")) { + mock(); +} + void makeRequests(); diff --git a/test/httpClient/package.json b/test/httpClient/package.json new file mode 100644 index 00000000..773ea4bd --- /dev/null +++ b/test/httpClient/package.json @@ -0,0 +1,8 @@ +{ + "name": "http-client-appmap-node-test", + "packageManager": "yarn@3.6.3", + "private": true, + "dependencies": { + "nock": "^13.4.0" + } +} diff --git a/yarn.lock b/yarn.lock index 2ace6435..a2224def 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4898,6 +4898,14 @@ __metadata: languageName: node linkType: hard +"http-client-appmap-node-test@workspace:test/httpClient": + version: 0.0.0-use.local + resolution: "http-client-appmap-node-test@workspace:test/httpClient" + dependencies: + nock: ^13.4.0 + languageName: unknown + linkType: soft + "http-errors@npm:2.0.0": version: 2.0.0 resolution: "http-errors@npm:2.0.0" @@ -6915,6 +6923,17 @@ __metadata: languageName: node linkType: hard +"nock@npm:^13.4.0": + version: 13.4.0 + resolution: "nock@npm:13.4.0" + dependencies: + debug: ^4.1.0 + json-stringify-safe: ^5.0.1 + propagate: ^2.0.0 + checksum: 30c3751854f9c412df5f99e01eeaef25b2583d3cae80b8c46524acb39d8b7fa61043603472ad94a3adc4b7d1e0f3098e6bb06e787734cbfbde2751891115b311 + languageName: node + linkType: hard + "node-addon-api@npm:^4.2.0": version: 4.3.0 resolution: "node-addon-api@npm:4.3.0" @@ -8071,6 +8090,13 @@ __metadata: languageName: node linkType: hard +"propagate@npm:^2.0.0": + version: 2.0.1 + resolution: "propagate@npm:2.0.1" + checksum: c4febaee2be0979e82fb6b3727878fd122a98d64a7fa3c9d09b0576751b88514a9e9275b1b92e76b364d488f508e223bd7e1dcdc616be4cdda876072fbc2a96c + languageName: node + linkType: hard + "proto-list@npm:~1.2.1": version: 1.2.4 resolution: "proto-list@npm:1.2.4"