UNPKG

@sentry/core

Version:
155 lines (137 loc) 4.84 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); // Curious about `thismessage:/`? See: https://www.rfc-editor.org/rfc/rfc2557.html // > When the methods above do not yield an absolute URI, a base URL // > of "thismessage:/" MUST be employed. This base URL has been // > defined for the sole purpose of resolving relative references // > within a multipart/related structure when no other base URI is // > specified. // // We need to provide a base URL to `parseStringToURLObject` because the fetch API gives us a // relative URL sometimes. // // This is the only case where we need to provide a base URL to `parseStringToURLObject` // because the relative URL is not valid on its own. const DEFAULT_BASE_URL = 'thismessage:/'; /** * Checks if the URL object is relative * * @param url - The URL object to check * @returns True if the URL object is relative, false otherwise */ function isURLObjectRelative(url) { return 'isRelative' in url; } /** * Parses string to a URL object * * @param url - The URL to parse * @returns The parsed URL object or undefined if the URL is invalid */ function parseStringToURLObject(url, urlBase) { const isRelative = url.startsWith('/'); const base = urlBase ?? (isRelative ? DEFAULT_BASE_URL : undefined); try { // Use `canParse` to short-circuit the URL constructor if it's not a valid URL // This is faster than trying to construct the URL and catching the error // Node 20+, Chrome 120+, Firefox 115+, Safari 17+ if ('canParse' in URL && !(URL ).canParse(url, base)) { return undefined; } const fullUrlObject = new URL(url, base); if (isRelative) { // Because we used a fake base URL, we need to return a relative URL object. // We cannot return anything about the origin, host, etc. because it will refer to the fake base URL. return { isRelative, pathname: fullUrlObject.pathname, search: fullUrlObject.search, hash: fullUrlObject.hash, }; } return fullUrlObject; } catch { // empty body } return undefined; } /** * Takes a URL object and returns a sanitized string which is safe to use as span name * see: https://develop.sentry.dev/sdk/data-handling/#structuring-data */ function getSanitizedUrlStringFromUrlObject(url) { if (isURLObjectRelative(url)) { return url.pathname; } const newUrl = new URL(url); newUrl.search = ''; newUrl.hash = ''; if (['80', '443'].includes(newUrl.port)) { newUrl.port = ''; } if (newUrl.password) { newUrl.password = '%filtered%'; } if (newUrl.username) { newUrl.username = '%filtered%'; } return newUrl.toString(); } /** * Parses string form of URL into an object * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B * // intentionally using regex and not <a/> href parsing trick because React Native and other * // environments where DOM might not be available * @returns parsed URL object */ function parseUrl(url) { if (!url) { return {}; } const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); if (!match) { return {}; } // coerce to undefined values to empty string so we don't get 'undefined' const query = match[6] || ''; const fragment = match[8] || ''; return { host: match[4], path: match[5], protocol: match[2], search: query, hash: fragment, relative: match[5] + query + fragment, // everything minus origin }; } /** * Strip the query string and fragment off of a given URL or path (if present) * * @param urlPath Full URL or path, including possible query string and/or fragment * @returns URL or path without query string or fragment */ function stripUrlQueryAndFragment(urlPath) { return (urlPath.split(/[?#]/, 1) )[0]; } /** * Takes a URL object and returns a sanitized string which is safe to use as span name * see: https://develop.sentry.dev/sdk/data-handling/#structuring-data */ function getSanitizedUrlString(url) { const { protocol, host, path } = url; const filteredHost = host // Always filter out authority ?.replace(/^.*@/, '[filtered]:[filtered]@') // Don't show standard :80 (http) and :443 (https) ports to reduce the noise // TODO: Use new URL global if it exists .replace(/(:80)$/, '') .replace(/(:443)$/, '') || ''; return `${protocol ? `${protocol}://` : ''}${filteredHost}${path}`; } exports.getSanitizedUrlString = getSanitizedUrlString; exports.getSanitizedUrlStringFromUrlObject = getSanitizedUrlStringFromUrlObject; exports.isURLObjectRelative = isURLObjectRelative; exports.parseStringToURLObject = parseStringToURLObject; exports.parseUrl = parseUrl; exports.stripUrlQueryAndFragment = stripUrlQueryAndFragment; //# sourceMappingURL=url.js.map