Files
klz-cables.com/.pnpm-store/v10/files/18/4c67dc8e5c94c94db88b31f7c968639fed0e565d35a90564263e41e66330042012338d01a30464d5f42a4e8826c654526012384c27c9aa16ba176dce4b6f09
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

1 line
15 KiB
Plaintext

{"version":3,"file":"httpIntegration.js","sources":["../../../../src/light/integrations/httpIntegration.ts"],"sourcesContent":["import type { ChannelListener } from 'node:diagnostics_channel';\nimport { subscribe } from 'node:diagnostics_channel';\nimport type { ClientRequest, IncomingMessage, RequestOptions, Server } from 'node:http';\nimport type { Integration, IntegrationFn } from '@sentry/core';\nimport {\n continueTrace,\n debug,\n generateSpanId,\n getCurrentScope,\n getIsolationScope,\n httpRequestToRequestData,\n LRUMap,\n stripUrlQueryAndFragment,\n withIsolationScope,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport { patchRequestToCaptureBody } from '../../utils/captureRequestBody';\nimport {\n addRequestBreadcrumb,\n addTracePropagationHeadersToOutgoingRequest,\n getRequestOptions,\n} from '../../utils/outgoingHttpRequest';\nimport type { LightNodeClient } from '../client';\n\nconst INTEGRATION_NAME = 'Http';\n\n// We keep track of emit functions we wrapped, to avoid double wrapping\nconst wrappedEmitFns = new WeakSet<typeof Server.prototype.emit>();\n\nexport interface HttpIntegrationOptions {\n /**\n * Do not capture the request body for incoming HTTP requests to URLs where the given callback returns `true`.\n * This can be useful for long running requests where the body is not needed and we want to avoid capturing it.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the incoming request.\n * @param request Contains the {@type RequestOptions} object used to make the incoming request.\n */\n ignoreRequestBody?: (url: string, request: RequestOptions) => boolean;\n\n /**\n * Controls the maximum size of incoming HTTP request bodies attached to events.\n *\n * Available options:\n * - 'none': No request bodies will be attached\n * - 'small': Request bodies up to 1,000 bytes will be attached\n * - 'medium': Request bodies up to 10,000 bytes will be attached (default)\n * - 'always': Request bodies will always be attached\n *\n * Note that even with 'always' setting, bodies exceeding 1MB will never be attached\n * for performance and security reasons.\n *\n * @default 'medium'\n */\n maxRequestBodySize?: 'none' | 'small' | 'medium' | 'always';\n\n /**\n * Whether breadcrumbs should be recorded for outgoing requests.\n *\n * @default `true`\n */\n breadcrumbs?: boolean;\n\n /**\n * Do not capture breadcrumbs or propagate trace headers for outgoing HTTP requests to URLs\n * where the given callback returns `true`.\n *\n * @param url Contains the entire URL, including query string (if any), protocol, host, etc. of the outgoing request.\n * @param request Contains the {@type RequestOptions} object used to make the outgoing request.\n */\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n}\n\nconst _httpIntegration = ((options: HttpIntegrationOptions = {}) => {\n const _options = {\n maxRequestBodySize: options.maxRequestBodySize ?? 'medium',\n ignoreRequestBody: options.ignoreRequestBody,\n breadcrumbs: options.breadcrumbs ?? true,\n ignoreOutgoingRequests: options.ignoreOutgoingRequests,\n };\n\n const propagationDecisionMap = new LRUMap<string, boolean>(100);\n const ignoreOutgoingRequestsMap = new WeakMap<ClientRequest, boolean>();\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n const onHttpServerRequestStart = ((_data: unknown) => {\n const data = _data as { server: Server };\n instrumentServer(data.server, _options);\n }) satisfies ChannelListener;\n\n const onHttpClientRequestCreated = ((_data: unknown) => {\n const data = _data as { request: ClientRequest };\n onOutgoingRequestCreated(data.request, _options, propagationDecisionMap, ignoreOutgoingRequestsMap);\n }) satisfies ChannelListener;\n\n const onHttpClientResponseFinish = ((_data: unknown) => {\n const data = _data as { request: ClientRequest; response: IncomingMessage };\n onOutgoingRequestFinish(data.request, data.response, _options, ignoreOutgoingRequestsMap);\n }) satisfies ChannelListener;\n\n const onHttpClientRequestError = ((_data: unknown) => {\n const data = _data as { request: ClientRequest };\n onOutgoingRequestFinish(data.request, undefined, _options, ignoreOutgoingRequestsMap);\n }) satisfies ChannelListener;\n\n subscribe('http.server.request.start', onHttpServerRequestStart);\n subscribe('http.client.request.created', onHttpClientRequestCreated);\n subscribe('http.client.response.finish', onHttpClientResponseFinish);\n subscribe('http.client.request.error', onHttpClientRequestError);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * This integration handles incoming and outgoing HTTP requests in light mode (without OpenTelemetry).\n *\n * It uses Node's native diagnostics channels (Node.js 22+) for request isolation,\n * trace propagation, and breadcrumb creation.\n */\nexport const httpIntegration = _httpIntegration as (options?: HttpIntegrationOptions) => Integration & {\n name: 'Http';\n setupOnce: () => void;\n};\n\n/**\n * Instrument a server to capture incoming requests.\n */\nfunction instrumentServer(\n server: Server,\n {\n ignoreRequestBody,\n maxRequestBodySize,\n }: {\n ignoreRequestBody?: (url: string, request: IncomingMessage) => boolean;\n maxRequestBodySize: 'small' | 'medium' | 'always' | 'none';\n },\n): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const originalEmit: typeof Server.prototype.emit = server.emit;\n\n if (wrappedEmitFns.has(originalEmit)) {\n return;\n }\n\n const newEmit = new Proxy(originalEmit, {\n apply(target, thisArg, args: [event: string, ...args: unknown[]]) {\n // Only handle request events\n if (args[0] !== 'request') {\n return target.apply(thisArg, args);\n }\n\n const client = getCurrentScope().getClient<LightNodeClient>();\n\n if (!client) {\n return target.apply(thisArg, args);\n }\n\n DEBUG_BUILD && debug.log(INTEGRATION_NAME, 'Handling incoming request');\n\n const isolationScope = getIsolationScope().clone();\n const request = args[1] as IncomingMessage;\n\n const normalizedRequest = httpRequestToRequestData(request);\n\n // request.ip is non-standard but some frameworks set this\n const ipAddress = (request as { ip?: string }).ip || request.socket?.remoteAddress;\n\n const url = request.url || '/';\n if (maxRequestBodySize !== 'none' && !ignoreRequestBody?.(url, request)) {\n patchRequestToCaptureBody(request, isolationScope, maxRequestBodySize, INTEGRATION_NAME);\n }\n\n // Update the isolation scope, isolate this request\n isolationScope.setSDKProcessingMetadata({ normalizedRequest, ipAddress });\n\n // attempt to update the scope's `transactionName` based on the request URL\n // Ideally, framework instrumentations coming after the HttpInstrumentation\n // update the transactionName once we get a parameterized route.\n const httpMethod = (request.method || 'GET').toUpperCase();\n const httpTargetWithoutQueryFragment = stripUrlQueryAndFragment(url);\n\n const bestEffortTransactionName = `${httpMethod} ${httpTargetWithoutQueryFragment}`;\n\n isolationScope.setTransactionName(bestEffortTransactionName);\n\n return withIsolationScope(isolationScope, () => {\n // Handle trace propagation using Sentry's continueTrace\n // This replaces OpenTelemetry's propagation.extract() + context.with()\n const sentryTrace = normalizedRequest.headers?.['sentry-trace'];\n const baggage = normalizedRequest.headers?.['baggage'];\n\n return continueTrace(\n {\n sentryTrace: Array.isArray(sentryTrace) ? sentryTrace[0] : sentryTrace,\n baggage: Array.isArray(baggage) ? baggage[0] : baggage,\n },\n () => {\n // Set propagationSpanId after continueTrace because it calls withScope +\n // setPropagationContext internally, which would overwrite any previously set value.\n getCurrentScope().getPropagationContext().propagationSpanId = generateSpanId();\n return target.apply(thisArg, args);\n },\n );\n });\n },\n });\n\n wrappedEmitFns.add(newEmit);\n server.emit = newEmit;\n}\n\nfunction onOutgoingRequestCreated(\n request: ClientRequest,\n options: { ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean },\n propagationDecisionMap: LRUMap<string, boolean>,\n ignoreOutgoingRequestsMap: WeakMap<ClientRequest, boolean>,\n): void {\n const shouldIgnore = shouldIgnoreOutgoingRequest(request, options);\n ignoreOutgoingRequestsMap.set(request, shouldIgnore);\n\n if (shouldIgnore) {\n return;\n }\n\n addTracePropagationHeadersToOutgoingRequest(request, propagationDecisionMap);\n}\n\nfunction onOutgoingRequestFinish(\n request: ClientRequest,\n response: IncomingMessage | undefined,\n options: {\n breadcrumbs: boolean;\n ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean;\n },\n ignoreOutgoingRequestsMap: WeakMap<ClientRequest, boolean>,\n): void {\n if (!options.breadcrumbs) {\n return;\n }\n\n // Note: We cannot rely on the map being set by `onOutgoingRequestCreated`, because that channel\n // only exists since Node 22\n const shouldIgnore = ignoreOutgoingRequestsMap.get(request) ?? shouldIgnoreOutgoingRequest(request, options);\n\n if (shouldIgnore) {\n return;\n }\n\n addRequestBreadcrumb(request, response);\n}\n\n/** Check if the given outgoing request should be ignored. */\nfunction shouldIgnoreOutgoingRequest(\n request: ClientRequest,\n options: { ignoreOutgoingRequests?: (url: string, request: RequestOptions) => boolean },\n): boolean {\n // Check if tracing is suppressed (e.g. for Sentry's own transport requests)\n if (getCurrentScope().getScopeData().sdkProcessingMetadata.__SENTRY_SUPPRESS_TRACING__) {\n return true;\n }\n\n const { ignoreOutgoingRequests } = options;\n\n if (!ignoreOutgoingRequests) {\n return false;\n }\n\n const url = `${request.protocol}//${request.getHeader('host') || request.host}${request.path}`;\n return ignoreOutgoingRequests(url, getRequestOptions(request));\n}\n"],"names":["LRUMap","subscribe","getCurrentScope","DEBUG_BUILD","debug","getIsolationScope","httpRequestToRequestData","patchRequestToCaptureBody","stripUrlQueryAndFragment","withIsolationScope","continueTrace","generateSpanId","addTracePropagationHeadersToOutgoingRequest","addRequestBreadcrumb","getRequestOptions"],"mappings":"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"}