package.build.npm.esm.integrations.httpclient.js.map Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of browser Show documentation
Show all versions of browser Show documentation
Official Sentry SDK for browsers
{"version":3,"file":"httpclient.js","sources":["../../../../src/integrations/httpclient.ts"],"sourcesContent":["import { SENTRY_XHR_DATA_KEY, addXhrInstrumentationHandler } from '@sentry-internal/browser-utils';\nimport { captureEvent, defineIntegration, getClient, isSentryRequestUrl } from '@sentry/core';\nimport type { Client, Event as SentryEvent, IntegrationFn, SentryWrappedXMLHttpRequest } from '@sentry/types';\nimport {\n GLOBAL_OBJ,\n addExceptionMechanism,\n addFetchInstrumentationHandler,\n logger,\n supportsNativeFetch,\n} from '@sentry/utils';\n\nimport { DEBUG_BUILD } from '../debug-build';\n\nexport type HttpStatusCodeRange = [number, number] | number;\nexport type HttpRequestTarget = string | RegExp;\n\nconst INTEGRATION_NAME = 'HttpClient';\n\ninterface HttpClientOptions {\n /**\n * HTTP status codes that should be considered failed.\n * This array can contain tuples of `[begin, end]` (both inclusive),\n * single status codes, or a combinations of both\n *\n * Example: [[500, 505], 507]\n * Default: [[500, 599]]\n */\n failedRequestStatusCodes: HttpStatusCodeRange[];\n\n /**\n * Targets to track for failed requests.\n * This array can contain strings or regular expressions.\n *\n * Example: ['http://localhost', /api\\/.*\\/]\n * Default: [/.*\\/]\n */\n failedRequestTargets: HttpRequestTarget[];\n}\n\nconst _httpClientIntegration = ((options: Partial = {}) => {\n const _options: HttpClientOptions = {\n failedRequestStatusCodes: [[500, 599]],\n failedRequestTargets: [/.*/],\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client): void {\n _wrapFetch(client, _options);\n _wrapXHR(client, _options);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Create events for failed client side HTTP requests.\n */\nexport const httpClientIntegration = defineIntegration(_httpClientIntegration);\n\n/**\n * Interceptor function for fetch requests\n *\n * @param requestInfo The Fetch API request info\n * @param response The Fetch API response\n * @param requestInit The request init object\n */\nfunction _fetchResponseHandler(\n options: HttpClientOptions,\n requestInfo: RequestInfo,\n response: Response,\n requestInit?: RequestInit,\n): void {\n if (_shouldCaptureResponse(options, response.status, response.url)) {\n const request = _getRequest(requestInfo, requestInit);\n\n let requestHeaders, responseHeaders, requestCookies, responseCookies;\n\n if (_shouldSendDefaultPii()) {\n [requestHeaders, requestCookies] = _parseCookieHeaders('Cookie', request);\n [responseHeaders, responseCookies] = _parseCookieHeaders('Set-Cookie', response);\n }\n\n const event = _createEvent({\n url: request.url,\n method: request.method,\n status: response.status,\n requestHeaders,\n responseHeaders,\n requestCookies,\n responseCookies,\n });\n\n captureEvent(event);\n }\n}\n\nfunction _parseCookieHeaders(\n cookieHeader: string,\n obj: Request | Response,\n): [Record, Record | undefined] {\n const headers = _extractFetchHeaders(obj.headers);\n let cookies;\n\n try {\n const cookieString = headers[cookieHeader] || headers[cookieHeader.toLowerCase()] || undefined;\n\n if (cookieString) {\n cookies = _parseCookieString(cookieString);\n }\n } catch (e) {\n DEBUG_BUILD && logger.log(`Could not extract cookies from header ${cookieHeader}`);\n }\n\n return [headers, cookies];\n}\n\n/**\n * Interceptor function for XHR requests\n *\n * @param xhr The XHR request\n * @param method The HTTP method\n * @param headers The HTTP headers\n */\nfunction _xhrResponseHandler(\n options: HttpClientOptions,\n xhr: XMLHttpRequest,\n method: string,\n headers: Record,\n): void {\n if (_shouldCaptureResponse(options, xhr.status, xhr.responseURL)) {\n let requestHeaders, responseCookies, responseHeaders;\n\n if (_shouldSendDefaultPii()) {\n try {\n const cookieString = xhr.getResponseHeader('Set-Cookie') || xhr.getResponseHeader('set-cookie') || undefined;\n\n if (cookieString) {\n responseCookies = _parseCookieString(cookieString);\n }\n } catch (e) {\n DEBUG_BUILD && logger.log('Could not extract cookies from response headers');\n }\n\n try {\n responseHeaders = _getXHRResponseHeaders(xhr);\n } catch (e) {\n DEBUG_BUILD && logger.log('Could not extract headers from response');\n }\n\n requestHeaders = headers;\n }\n\n const event = _createEvent({\n url: xhr.responseURL,\n method,\n status: xhr.status,\n requestHeaders,\n // Can't access request cookies from XHR\n responseHeaders,\n responseCookies,\n });\n\n captureEvent(event);\n }\n}\n\n/**\n * Extracts response size from `Content-Length` header when possible\n *\n * @param headers\n * @returns The response size in bytes or undefined\n */\nfunction _getResponseSizeFromHeaders(headers?: Record): number | undefined {\n if (headers) {\n const contentLength = headers['Content-Length'] || headers['content-length'];\n\n if (contentLength) {\n return parseInt(contentLength, 10);\n }\n }\n\n return undefined;\n}\n\n/**\n * Creates an object containing cookies from the given cookie string\n *\n * @param cookieString The cookie string to parse\n * @returns The parsed cookies\n */\nfunction _parseCookieString(cookieString: string): Record {\n return cookieString.split('; ').reduce((acc: Record, cookie: string) => {\n const [key, value] = cookie.split('=');\n if (key && value) {\n acc[key] = value;\n }\n return acc;\n }, {});\n}\n\n/**\n * Extracts the headers as an object from the given Fetch API request or response object\n *\n * @param headers The headers to extract\n * @returns The extracted headers as an object\n */\nfunction _extractFetchHeaders(headers: Headers): Record {\n const result: Record = {};\n\n headers.forEach((value, key) => {\n result[key] = value;\n });\n\n return result;\n}\n\n/**\n * Extracts the response headers as an object from the given XHR object\n *\n * @param xhr The XHR object to extract the response headers from\n * @returns The response headers as an object\n */\nfunction _getXHRResponseHeaders(xhr: XMLHttpRequest): Record {\n const headers = xhr.getAllResponseHeaders();\n\n if (!headers) {\n return {};\n }\n\n return headers.split('\\r\\n').reduce((acc: Record, line: string) => {\n const [key, value] = line.split(': ');\n if (key && value) {\n acc[key] = value;\n }\n return acc;\n }, {});\n}\n\n/**\n * Checks if the given target url is in the given list of targets\n *\n * @param target The target url to check\n * @returns true if the target url is in the given list of targets, false otherwise\n */\nfunction _isInGivenRequestTargets(\n failedRequestTargets: HttpClientOptions['failedRequestTargets'],\n target: string,\n): boolean {\n return failedRequestTargets.some((givenRequestTarget: HttpRequestTarget) => {\n if (typeof givenRequestTarget === 'string') {\n return target.includes(givenRequestTarget);\n }\n\n return givenRequestTarget.test(target);\n });\n}\n\n/**\n * Checks if the given status code is in the given range\n *\n * @param status The status code to check\n * @returns true if the status code is in the given range, false otherwise\n */\nfunction _isInGivenStatusRanges(\n failedRequestStatusCodes: HttpClientOptions['failedRequestStatusCodes'],\n status: number,\n): boolean {\n return failedRequestStatusCodes.some((range: HttpStatusCodeRange) => {\n if (typeof range === 'number') {\n return range === status;\n }\n\n return status >= range[0] && status <= range[1];\n });\n}\n\n/**\n * Wraps `fetch` function to capture request and response data\n */\nfunction _wrapFetch(client: Client, options: HttpClientOptions): void {\n if (!supportsNativeFetch()) {\n return;\n }\n\n addFetchInstrumentationHandler(handlerData => {\n if (getClient() !== client) {\n return;\n }\n\n const { response, args } = handlerData;\n const [requestInfo, requestInit] = args as [RequestInfo, RequestInit | undefined];\n\n if (!response) {\n return;\n }\n\n _fetchResponseHandler(options, requestInfo, response as Response, requestInit);\n });\n}\n\n/**\n * Wraps XMLHttpRequest to capture request and response data\n */\nfunction _wrapXHR(client: Client, options: HttpClientOptions): void {\n if (!('XMLHttpRequest' in GLOBAL_OBJ)) {\n return;\n }\n\n addXhrInstrumentationHandler(handlerData => {\n if (getClient() !== client) {\n return;\n }\n\n const xhr = handlerData.xhr as SentryWrappedXMLHttpRequest & XMLHttpRequest;\n\n const sentryXhrData = xhr[SENTRY_XHR_DATA_KEY];\n\n if (!sentryXhrData) {\n return;\n }\n\n const { method, request_headers: headers } = sentryXhrData;\n\n try {\n _xhrResponseHandler(options, xhr, method, headers);\n } catch (e) {\n DEBUG_BUILD && logger.warn('Error while extracting response event form XHR response', e);\n }\n });\n}\n\n/**\n * Checks whether to capture given response as an event\n *\n * @param status response status code\n * @param url response url\n */\nfunction _shouldCaptureResponse(options: HttpClientOptions, status: number, url: string): boolean {\n return (\n _isInGivenStatusRanges(options.failedRequestStatusCodes, status) &&\n _isInGivenRequestTargets(options.failedRequestTargets, url) &&\n !isSentryRequestUrl(url, getClient())\n );\n}\n\n/**\n * Creates a synthetic Sentry event from given response data\n *\n * @param data response data\n * @returns event\n */\nfunction _createEvent(data: {\n url: string;\n method: string;\n status: number;\n responseHeaders?: Record;\n responseCookies?: Record;\n requestHeaders?: Record;\n requestCookies?: Record;\n}): SentryEvent {\n const message = `HTTP Client Error with status code: ${data.status}`;\n\n const event: SentryEvent = {\n message,\n exception: {\n values: [\n {\n type: 'Error',\n value: message,\n },\n ],\n },\n request: {\n url: data.url,\n method: data.method,\n headers: data.requestHeaders,\n cookies: data.requestCookies,\n },\n contexts: {\n response: {\n status_code: data.status,\n headers: data.responseHeaders,\n cookies: data.responseCookies,\n body_size: _getResponseSizeFromHeaders(data.responseHeaders),\n },\n },\n };\n\n addExceptionMechanism(event, {\n type: 'http.client',\n handled: false,\n });\n\n return event;\n}\n\nfunction _getRequest(requestInfo: RequestInfo, requestInit?: RequestInit): Request {\n if (!requestInit && requestInfo instanceof Request) {\n return requestInfo;\n }\n\n // If both are set, we try to construct a new Request with the given arguments\n // However, if e.g. the original request has a `body`, this will throw an error because it was already accessed\n // In this case, as a fallback, we just use the original request - using both is rather an edge case\n if (requestInfo instanceof Request && requestInfo.bodyUsed) {\n return requestInfo;\n }\n\n return new Request(requestInfo, requestInit);\n}\n\nfunction _shouldSendDefaultPii(): boolean {\n const client = getClient();\n return client ? Boolean(client.getOptions().sendDefaultPii) : false;\n}\n"],"names":[],"mappings":"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"}