UNPKG

@sentry/utils

Version:
167 lines (146 loc) 5.76 kB
import { logger } from './logger.js'; var BAGGAGE_HEADER_NAME = 'baggage'; var SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-'; var SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/; /** * Max length of a serialized baggage string * * https://www.w3.org/TR/baggage/#limits */ var MAX_BAGGAGE_STRING_LENGTH = 8192; /** Create an instance of Baggage */ function createBaggage(initItems, baggageString = '', mutable = true) { return [{ ...initItems }, baggageString, mutable]; } /** Get a value from baggage */ function getBaggageValue(baggage, key) { return baggage[0][key]; } /** Add a value to baggage */ function setBaggageValue(baggage, key, value) { if (isBaggageMutable(baggage)) { baggage[0][key] = value; } } /** Check if the Sentry part of the passed baggage (i.e. the first element in the tuple) is empty */ function isSentryBaggageEmpty(baggage) { return Object.keys(baggage[0]).length === 0; } /** Check if the Sentry part of the passed baggage (i.e. the first element in the tuple) is empty */ function isBaggageEmpty(baggage) { var thirdPartyBaggage = getThirdPartyBaggage(baggage); return isSentryBaggageEmpty(baggage) && (thirdPartyBaggage == undefined || thirdPartyBaggage.length === 0); } /** Returns Sentry specific baggage values */ function getSentryBaggageItems(baggage) { return baggage[0]; } /** * Returns 3rd party baggage string of @param baggage * @param baggage */ function getThirdPartyBaggage(baggage) { return baggage[1]; } /** * Checks if baggage is mutable * @param baggage * @returns true if baggage is mutable, else false */ function isBaggageMutable(baggage) { return baggage[2]; } /** * Sets the passed baggage immutable * @param baggage */ function setBaggageImmutable(baggage) { baggage[2] = false; } /** Serialize a baggage object */ function serializeBaggage(baggage) { return Object.keys(baggage[0]).reduce((prev, key) => { var val = baggage[0][key] ; var baggageEntry = `${SENTRY_BAGGAGE_KEY_PREFIX}${encodeURIComponent(key)}=${encodeURIComponent(val)}`; var newVal = prev === '' ? baggageEntry : `${prev},${baggageEntry}`; if (newVal.length > MAX_BAGGAGE_STRING_LENGTH) { (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn(`Not adding key: ${key} with val: ${val} to baggage due to exceeding baggage size limits.`); return prev; } else { return newVal; } }, baggage[1]); } /** Parse a baggage header from a string and return a Baggage object */ function parseBaggageString(inputBaggageString) { return inputBaggageString.split(',').reduce( ([baggageObj, baggageString], curr) => { const [key, val] = curr.split('='); if (SENTRY_BAGGAGE_KEY_PREFIX_REGEX.test(key)) { var baggageKey = decodeURIComponent(key.split('-')[1]); return [ { ...baggageObj, [baggageKey]: decodeURIComponent(val), }, baggageString, true, ]; } else { return [baggageObj, baggageString === '' ? curr : `${baggageString},${curr}`, true]; } }, [{}, '', true], ); } /** * Merges the baggage header we saved from the incoming request (or meta tag) with * a possibly created or modified baggage header by a third party that's been added * to the outgoing request header. * * In case @param headerBaggageString exists, we can safely add the the 3rd party part of @param headerBaggage * with our @param incomingBaggage. This is possible because if we modified anything beforehand, * it would only affect parts of the sentry baggage (@see Baggage interface). * * @param incomingBaggage the baggage header of the incoming request that might contain sentry entries * @param headerBaggageString possibly existing baggage header string added from a third party to request headers * * @return a merged and serialized baggage string to be propagated with the outgoing request */ function mergeAndSerializeBaggage(incomingBaggage, headerBaggageString) { if (!incomingBaggage && !headerBaggageString) { return ''; } var headerBaggage = (headerBaggageString && parseBaggageString(headerBaggageString)) || undefined; var thirdPartyHeaderBaggage = headerBaggage && getThirdPartyBaggage(headerBaggage); var finalBaggage = createBaggage( (incomingBaggage && incomingBaggage[0]) || {}, thirdPartyHeaderBaggage || (incomingBaggage && incomingBaggage[1]) || '', ); return serializeBaggage(finalBaggage); } /** * Helper function that takes a raw baggage string (if available) and the processed sentry-trace header * data (if available), parses the baggage string and creates a Baggage object * If there is no baggage string, it will create an empty Baggage object. * In a second step, this functions determines if the created Baggage object should be set immutable * to prevent mutation of the Sentry data. * * Extracted this logic to a function because it's duplicated in a lot of places. * * @param rawBaggageString * @param sentryTraceHeader */ function parseBaggageSetMutability( rawBaggageString, sentryTraceHeader, ) { var baggage = parseBaggageString(rawBaggageString || ''); if (!isSentryBaggageEmpty(baggage) || (sentryTraceHeader && isSentryBaggageEmpty(baggage))) { setBaggageImmutable(baggage); } return baggage; } export { BAGGAGE_HEADER_NAME, MAX_BAGGAGE_STRING_LENGTH, SENTRY_BAGGAGE_KEY_PREFIX, SENTRY_BAGGAGE_KEY_PREFIX_REGEX, createBaggage, getBaggageValue, getSentryBaggageItems, getThirdPartyBaggage, isBaggageEmpty, isBaggageMutable, isSentryBaggageEmpty, mergeAndSerializeBaggage, parseBaggageSetMutability, parseBaggageString, serializeBaggage, setBaggageImmutable, setBaggageValue }; //# sourceMappingURL=baggage.js.map