Skip to content

Commit 82364f0

Browse files
Fix requests patching edge case (#146)
* Fix requests patching edge case * Re-apploy _logHttpRequest * Add command to log special case * Fix linting issues
1 parent 7d1b8a7 commit 82364f0

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

src/trace/patch-http.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { LogLevel, setLogLevel } from "../utils";
77
import { parentIDHeader, SampleMode, samplingPriorityHeader, traceIDHeader, Source } from "./constants";
88
import { patchHttp, unpatchHttp } from "./patch-http";
99
import { TraceContextService } from "./trace-context-service";
10+
import { URL } from "url";
1011

1112
describe("patchHttp", () => {
1213
let traceWrapper = {
@@ -131,4 +132,22 @@ describe("patchHttp", () => {
131132
expect(headers[parentIDHeader]).toBeUndefined();
132133
expect(headers[samplingPriorityHeader]).toBeUndefined();
133134
});
135+
it("injects tracing headers when using the new WHATWG URL object", () => {
136+
nock("http://www.example.com").get("/").reply(200, {});
137+
patchHttp(contextService);
138+
const url = new URL("http://www.example.com");
139+
const req = http.request(url);
140+
expectHeaders(req);
141+
});
142+
it("injects tracing headers when using the new WHATWG URL object and callback", (done) => {
143+
nock("http://www.example.com").get("/").reply(200, {});
144+
patchHttp(contextService);
145+
const url = new URL("http://www.example.com");
146+
const req = http.request(url, {}, () => {
147+
done();
148+
});
149+
req.end();
150+
151+
expectHeaders(req);
152+
});
134153
});

src/trace/patch-http.ts

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@ export function unpatchHttp() {
3535
function patchMethod(mod: typeof http | typeof https, method: "get" | "request", contextService: TraceContextService) {
3636
shimmer.wrap(mod, method, (original) => {
3737
const fn = (arg1: any, arg2: any, arg3: any) => {
38-
const { options, callback } = normalizeArgs(arg1, arg2, arg3);
39-
const requestOpts = getRequestOptionsWithTraceContext(options, contextService);
38+
[arg1, arg2, arg3] = addTraceContextToArgs(contextService, arg1, arg2, arg3);
4039

41-
if (isIntegrationTest()) {
42-
_logHttpRequest(requestOpts);
40+
if (arg3 === undefined || arg3 === null) {
41+
return original(arg1, arg2);
42+
} else {
43+
return original(arg1, arg2, arg3);
4344
}
44-
45-
return original(requestOpts, callback);
4645
};
4746
return fn as any;
4847
});
@@ -54,23 +53,37 @@ function unpatchMethod(mod: typeof http | typeof https, method: "get" | "request
5453
}
5554

5655
/**
57-
* The input into the http.request function has 6 different overloads. This method normalized the inputs
58-
* into a consistent format.
56+
* Finds the RequestOptions in the args and injects context into headers
5957
*/
60-
function normalizeArgs(
58+
function addTraceContextToArgs(
59+
contextService: TraceContextService,
6160
arg1: string | URL | http.RequestOptions,
6261
arg2?: RequestCallback | http.RequestOptions,
6362
arg3?: RequestCallback,
6463
) {
65-
let options: http.RequestOptions = typeof arg1 === "string" ? parse(arg1) : { ...arg1 };
66-
options.headers = options.headers || {};
67-
let callback = arg3;
68-
if (typeof arg2 === "function") {
69-
callback = arg2;
70-
} else if (typeof arg2 === "object") {
71-
options = { ...options, ...arg2 };
64+
let requestOpts: http.RequestOptions | undefined;
65+
if (typeof arg1 === "string" || arg1 instanceof URL) {
66+
if (arg2 === undefined || arg2 === null) {
67+
requestOpts = {
68+
method: "GET",
69+
};
70+
requestOpts = getRequestOptionsWithTraceContext(requestOpts, contextService);
71+
return [arg1, requestOpts, arg3];
72+
} else if (typeof arg2 === "function") {
73+
requestOpts = {
74+
method: "GET",
75+
};
76+
requestOpts = getRequestOptionsWithTraceContext(requestOpts, contextService);
77+
return [arg1, requestOpts, arg2];
78+
} else {
79+
requestOpts = arg2 as http.RequestOptions;
80+
requestOpts = getRequestOptionsWithTraceContext(requestOpts, contextService);
81+
return [arg1, requestOpts, arg3];
82+
}
83+
} else {
84+
requestOpts = getRequestOptionsWithTraceContext(arg1, contextService);
85+
return [requestOpts, arg2, arg3];
7286
}
73-
return { options, callback };
7487
}
7588

7689
function getRequestOptionsWithTraceContext(
@@ -86,10 +99,16 @@ function getRequestOptionsWithTraceContext(
8699
...headers,
87100
...traceHeaders,
88101
};
89-
return {
102+
const requestOpts = {
90103
...options,
91104
headers,
92105
};
106+
// Logging all http requests during integration tests let's
107+
// us track traffic in our test snapshots
108+
if (isIntegrationTest()) {
109+
_logHttpRequest(requestOpts);
110+
}
111+
return requestOpts;
93112
}
94113

95114
function isIntegrationTest() {

0 commit comments

Comments
 (0)