{"version":3,"file":"captureRequestBody.js","sources":["../../../src/utils/captureRequestBody.ts"],"sourcesContent":["import type { IncomingMessage } from 'node:http';\nimport type { Scope } from '@sentry/core';\nimport { debug } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { MAX_BODY_BYTE_LENGTH } from '../integrations/http/constants';\n\n/**\n * This method patches the request object to capture the body.\n * Instead of actually consuming the streamed body ourselves, which has potential side effects,\n * we monkey patch `req.on('data')` to intercept the body chunks.\n * This way, we only read the body if the user also consumes the body, ensuring we do not change any behavior in unexpected ways.\n */\nexport function patchRequestToCaptureBody(\n req: IncomingMessage,\n isolationScope: Scope,\n maxIncomingRequestBodySize: 'small' | 'medium' | 'always',\n integrationName: string,\n): void {\n let bodyByteLength = 0;\n const chunks: Buffer[] = [];\n\n DEBUG_BUILD && debug.log(integrationName, 'Patching request.on');\n\n /**\n * We need to keep track of the original callbacks, in order to be able to remove listeners again.\n * Since `off` depends on having the exact same function reference passed in, we need to be able to map\n * original listeners to our wrapped ones.\n */\n const callbackMap = new WeakMap();\n\n const maxBodySize =\n maxIncomingRequestBodySize === 'small'\n ? 1_000\n : maxIncomingRequestBodySize === 'medium'\n ? 10_000\n : MAX_BODY_BYTE_LENGTH;\n\n try {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n req.on = new Proxy(req.on, {\n apply: (target, thisArg, args: Parameters) => {\n const [event, listener, ...restArgs] = args;\n\n if (event === 'data') {\n DEBUG_BUILD &&\n debug.log(integrationName, `Handling request.on(\"data\") with maximum body size of ${maxBodySize}b`);\n\n const callback = new Proxy(listener, {\n apply: (target, thisArg, args: Parameters) => {\n try {\n const chunk = args[0] as Buffer | string;\n const bufferifiedChunk = Buffer.from(chunk);\n\n if (bodyByteLength < maxBodySize) {\n chunks.push(bufferifiedChunk);\n bodyByteLength += bufferifiedChunk.byteLength;\n } else if (DEBUG_BUILD) {\n debug.log(\n integrationName,\n `Dropping request body chunk because maximum body length of ${maxBodySize}b is exceeded.`,\n );\n }\n } catch (err) {\n DEBUG_BUILD && debug.error(integrationName, 'Encountered error while storing body chunk.');\n }\n\n return Reflect.apply(target, thisArg, args);\n },\n });\n\n callbackMap.set(listener, callback);\n\n return Reflect.apply(target, thisArg, [event, callback, ...restArgs]);\n }\n\n return Reflect.apply(target, thisArg, args);\n },\n });\n\n // Ensure we also remove callbacks correctly\n // eslint-disable-next-line @typescript-eslint/unbound-method\n req.off = new Proxy(req.off, {\n apply: (target, thisArg, args: Parameters) => {\n const [, listener] = args;\n\n const callback = callbackMap.get(listener);\n if (callback) {\n callbackMap.delete(listener);\n\n const modifiedArgs = args.slice();\n modifiedArgs[1] = callback;\n return Reflect.apply(target, thisArg, modifiedArgs);\n }\n\n return Reflect.apply(target, thisArg, args);\n },\n });\n\n req.on('end', () => {\n try {\n const body = Buffer.concat(chunks).toString('utf-8');\n if (body) {\n // Using Buffer.byteLength here, because the body may contain characters that are not 1 byte long\n const bodyByteLength = Buffer.byteLength(body, 'utf-8');\n const truncatedBody =\n bodyByteLength > maxBodySize\n ? `${Buffer.from(body)\n .subarray(0, maxBodySize - 3)\n .toString('utf-8')}...`\n : body;\n\n isolationScope.setSDKProcessingMetadata({ normalizedRequest: { data: truncatedBody } });\n }\n } catch (error) {\n if (DEBUG_BUILD) {\n debug.error(integrationName, 'Error building captured request body', error);\n }\n }\n });\n } catch (error) {\n if (DEBUG_BUILD) {\n debug.error(integrationName, 'Error patching request to capture body', error);\n }\n }\n}\n"],"names":["DEBUG_BUILD","debug","MAX_BODY_BYTE_LENGTH"],"mappings":"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"}