1- import { Baggage , BaggageObj } from '@sentry/types' ;
1+ import { Baggage , BaggageObj , TraceparentData } from '@sentry/types' ;
22
33import { IS_DEBUG_BUILD } from './flags' ;
44import { logger } from './logger' ;
@@ -17,8 +17,8 @@ export const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;
1717export const MAX_BAGGAGE_STRING_LENGTH = 8192 ;
1818
1919/** Create an instance of Baggage */
20- export function createBaggage ( initItems : BaggageObj , baggageString : string = '' ) : Baggage {
21- return [ { ...initItems } , baggageString ] ;
20+ export function createBaggage ( initItems : BaggageObj , baggageString : string = '' , frozen : boolean = false ) : Baggage {
21+ return [ { ...initItems } , baggageString , frozen ] ;
2222}
2323
2424/** Get a value from baggage */
@@ -28,7 +28,9 @@ export function getBaggageValue(baggage: Baggage, key: keyof BaggageObj): Baggag
2828
2929/** Add a value to baggage */
3030export function setBaggageValue ( baggage : Baggage , key : keyof BaggageObj , value : BaggageObj [ keyof BaggageObj ] ) : void {
31- baggage [ 0 ] [ key ] = value ;
31+ if ( ! isBaggageFrozen ( baggage ) ) {
32+ baggage [ 0 ] [ key ] = value ;
33+ }
3234}
3335
3436/** Check if the Sentry part of the passed baggage (i.e. the first element in the tuple) is empty */
@@ -55,6 +57,23 @@ export function getThirdPartyBaggage(baggage: Baggage): string {
5557 return baggage [ 1 ] ;
5658}
5759
60+ /**
61+ * Checks if baggage is frozen (i.e. immutable)
62+ * @param baggage
63+ * @returns true if baggage is frozen, else false
64+ */
65+ export function isBaggageFrozen ( baggage : Baggage ) : boolean {
66+ return baggage [ 2 ] ;
67+ }
68+
69+ /**
70+ * Freezes baggage (i.e. makes it immutable)
71+ * @param baggage
72+ */
73+ export function freezeBaggage ( baggage : Baggage ) : void {
74+ baggage [ 2 ] = true ;
75+ }
76+
5877/** Serialize a baggage object */
5978export function serializeBaggage ( baggage : Baggage ) : string {
6079 return Object . keys ( baggage [ 0 ] ) . reduce ( ( prev , key : keyof BaggageObj ) => {
@@ -71,7 +90,7 @@ export function serializeBaggage(baggage: Baggage): string {
7190 } , baggage [ 1 ] ) ;
7291}
7392
74- /** Parse a baggage header to a string */
93+ /** Parse a baggage header from a string and return a Baggage object */
7594export function parseBaggageString ( inputBaggageString : string ) : Baggage {
7695 return inputBaggageString . split ( ',' ) . reduce (
7796 ( [ baggageObj , baggageString ] , curr ) => {
@@ -84,12 +103,13 @@ export function parseBaggageString(inputBaggageString: string): Baggage {
84103 [ baggageKey ] : decodeURIComponent ( val ) ,
85104 } ,
86105 baggageString ,
106+ false ,
87107 ] ;
88108 } else {
89- return [ baggageObj , baggageString === '' ? curr : `${ baggageString } ,${ curr } ` ] ;
109+ return [ baggageObj , baggageString === '' ? curr : `${ baggageString } ,${ curr } ` , false ] ;
90110 }
91111 } ,
92- [ { } , '' ] ,
112+ [ { } , '' , false ] ,
93113 ) ;
94114}
95115
@@ -121,3 +141,27 @@ export function mergeAndSerializeBaggage(incomingBaggage?: Baggage, headerBaggag
121141 ) ;
122142 return serializeBaggage ( finalBaggage ) ;
123143}
144+
145+ /**
146+ * Helper function that takes a raw baggage string (if available) and the processed sentry-trace header
147+ * data (if available), parses the baggage string and creates a Baggage object
148+ * If there is no baggage string, it will create an empty Baggage object.
149+ * In a second step, this functions determines when the created Baggage object should be frozen to prevent mutation
150+ * of the Sentry data.
151+ *
152+ * Extracted this logic to a function because it's duplicated in a lot of places.
153+ *
154+ * @param rawBaggageString
155+ * @param traceparentData
156+ */
157+ // parseBaggagePlusMutability
158+ export function parseAndFreezeBaggageIfNecessary (
159+ rawBaggageString : string | false | undefined | null ,
160+ traceparentData : TraceparentData | string | false | undefined | null ,
161+ ) : Baggage {
162+ const baggage = parseBaggageString ( rawBaggageString || '' ) ;
163+ if ( ! isSentryBaggageEmpty ( baggage ) || ( traceparentData && isSentryBaggageEmpty ( baggage ) ) ) {
164+ freezeBaggage ( baggage ) ;
165+ }
166+ return baggage ;
167+ }
0 commit comments