Skip to content

Commit 48b6da9

Browse files
committed
keep property values
1 parent 743c4eb commit 48b6da9

File tree

4 files changed

+88
-4
lines changed

4 files changed

+88
-4
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as Sentry from '@sentry/node';
2+
import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests';
3+
4+
export type TestAPIResponse = { test_data: { host: string; 'sentry-trace': string; baggage: string } };
5+
6+
Sentry.init({
7+
dsn: 'https://[email protected]/1337',
8+
release: '1.0',
9+
environment: 'prod',
10+
// disable requests to /express
11+
tracePropagationTargets: [/^(?!.*express).*$/],
12+
tracesSampleRate: 1.0,
13+
transport: loggingTransport,
14+
});
15+
16+
import cors from 'cors';
17+
import express from 'express';
18+
import http from 'http';
19+
20+
const app = express();
21+
22+
app.use(cors());
23+
24+
app.get('/test/express-property-values', (req, res) => {
25+
const incomingBaggage = req.headers.baggage;
26+
27+
// Forward the incoming baggage (which contains property values) to the outgoing request
28+
// This tests that property values with = signs are preserved during parsing and re-serialization
29+
const headers = http.get({ hostname: 'somewhere.not.sentry', headers: { baggage: incomingBaggage } }).getHeaders();
30+
31+
// Responding with the headers outgoing request headers back to the assertions.
32+
res.send({ test_data: headers });
33+
});
34+
35+
Sentry.setupExpressErrorHandler(app);
36+
37+
startExpressServerAndSendPortToRunner(app);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { afterAll, expect, test } from 'vitest';
2+
import { cleanupChildProcesses, createRunner } from '../../../../utils/runner';
3+
import type { TestAPIResponse } from './server';
4+
5+
afterAll(() => {
6+
cleanupChildProcesses();
7+
});
8+
9+
test('should preserve baggage property values with equal signs (W3C spec compliance)', async () => {
10+
const runner = createRunner(__dirname, 'server.ts').start();
11+
12+
// W3C spec example: https://www.w3.org/TR/baggage/#example
13+
const response = await runner.makeRequest<TestAPIResponse>('get', '/test/express-property-values', {
14+
headers: {
15+
'sentry-trace': '12312012123120121231201212312012-1121201211212012-1',
16+
baggage: 'key1=value1;property1;property2,key2=value2,key3=value3; propertyKey=propertyValue',
17+
},
18+
});
19+
20+
expect(response).toBeDefined();
21+
22+
// The baggage should be parsed and re-serialized, preserving property values with = signs
23+
const baggageItems = response?.test_data.baggage?.split(',').map(item => decodeURIComponent(item.trim()));
24+
25+
expect(baggageItems).toContain('key1=value1;property1;property2');
26+
expect(baggageItems).toContain('key2=value2');
27+
expect(baggageItems).toContain('key3=value3; propertyKey=propertyValue');
28+
});

packages/core/src/utils/baggage.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,24 @@ export function parseBaggageHeader(
113113
function baggageHeaderToObject(baggageHeader: string): Record<string, string> {
114114
return baggageHeader
115115
.split(',')
116-
.map(baggageEntry =>
117-
baggageEntry.split('=').map(keyOrValue => {
116+
.map(baggageEntry => {
117+
const eqIdx = baggageEntry.indexOf('=');
118+
if (eqIdx === -1) {
119+
// Likely an invalid entry
120+
return [];
121+
}
122+
const key = baggageEntry.slice(0, eqIdx);
123+
const value = baggageEntry.slice(eqIdx + 1);
124+
return [key, value].map(keyOrValue => {
118125
try {
119126
return decodeURIComponent(keyOrValue.trim());
120127
} catch {
121128
// We ignore errors here, e.g. if the value cannot be URL decoded.
122129
// This will then be skipped in the next step
123130
return;
124131
}
125-
}),
126-
)
132+
});
133+
})
127134
.reduce<Record<string, string>>((acc, [key, value]) => {
128135
if (key && value) {
129136
acc[key] = value;

packages/core/test/lib/utils/baggage.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,16 @@ describe('parseBaggageHeader', () => {
7171
const actual = parseBaggageHeader(input);
7272
expect(actual).toStrictEqual(expectedOutput);
7373
});
74+
75+
test('should preserve property values with equal signs', () => {
76+
// see https://www.w3.org/TR/baggage/#example
77+
const baggageHeader = 'key1=value1;property1;property2, key2 = value2, key3=value3; propertyKey=propertyValue';
78+
const result = parseBaggageHeader(baggageHeader);
79+
80+
expect(result).toStrictEqual({
81+
key1: 'value1;property1;property2',
82+
key2: 'value2',
83+
key3: 'value3; propertyKey=propertyValue',
84+
});
85+
});
7486
});

0 commit comments

Comments
 (0)