From 5b0fb7b40dd6809dc9c362378b90e0ee8fa45f62 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 6 Dec 2023 08:08:18 -0800 Subject: [PATCH] fix(instrumentation-http): do not mutate given headers object for outgoing http requests (#4346) Fixes: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1609 --- experimental/CHANGELOG.md | 1 + .../opentelemetry-instrumentation-http/src/http.ts | 4 ++++ .../test/integrations/http-enable.test.ts | 14 ++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index ea641d5254..0454299c68 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to experimental packages in this project will be documented * fix(instrumentation-fetch): only access navigator if it is defined [#4063](https://github.com/open-telemetry/opentelemetry-js/pull/4063) * allows for experimental usage of this instrumentation with non-browser runtimes * fix(instrumentation-http): memory leak when responses are not resumed +* fix(instrumentation-http): Do not mutate given headers object for outgoing http requests. Fixes aws-sdk signing error on retries. [#4346](https://github.com/open-telemetry/opentelemetry-js/pull/4346) ## 0.45.1 diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts index 81e08ac860..337d058033 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts @@ -675,6 +675,10 @@ export class HttpInstrumentation extends InstrumentationBase { if (!optionsParsed.headers) { optionsParsed.headers = {}; + } else { + // Make a copy of the headers object to avoid mutating an object the + // caller might have a reference to. + optionsParsed.headers = Object.assign({}, optionsParsed.headers); } propagation.inject(requestContext, optionsParsed.headers); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts index 625b8b6549..a04027a2c9 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts @@ -269,6 +269,20 @@ describe('HttpInstrumentation Integration tests', () => { assertSpan(span, SpanKind.CLIENT, validations); }); + it('should not mutate given headers object when adding propagation headers', async () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 0); + + const headers = { 'x-foo': 'foo' }; + const result = await httpRequest.get( + new url.URL(`${protocol}://localhost:${mockServerPort}/?query=test`), + { headers } + ); + assert.deepStrictEqual(headers, { 'x-foo': 'foo' }); + assert.ok(result.reqHeaders[DummyPropagation.TRACE_CONTEXT_KEY]); + assert.ok(result.reqHeaders[DummyPropagation.SPAN_CONTEXT_KEY]); + }); + it('should create a span for GET requests and add propagation headers with Expect headers', async () => { let spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 0);