{"version":3,"file":"undici.js","sources":["../../../../../src/integrations/node-fetch/vendored/undici.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * NOTICE from the Sentry authors:\n * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/ed97091c9890dd18e52759f2ea98e9d7593b3ae4/packages/instrumentation-undici\n * - Upstream version: @opentelemetry/instrumentation-undici@0.24.0\n * - Tracking issue: https://github.com/getsentry/sentry-javascript/issues/20165\n * - Minor TypeScript strictness adjustments for this repository's compiler settings\n */\n/* eslint-disable -- vendored @opentelemetry/instrumentation-undici (#20165) */\n\nimport * as diagch from 'diagnostics_channel';\nimport { URL } from 'url';\n\nimport { InstrumentationBase, safeExecuteInTheMiddle } from '@opentelemetry/instrumentation';\nimport type { Attributes, Histogram, HrTime, Span } from '@opentelemetry/api';\nimport {\n  context,\n  INVALID_SPAN_CONTEXT,\n  propagation,\n  SpanKind,\n  SpanStatusCode,\n  trace,\n  ValueType,\n} from '@opentelemetry/api';\nimport { hrTime, hrTimeDuration, hrTimeToMilliseconds } from '@opentelemetry/core';\nimport {\n  ATTR_ERROR_TYPE,\n  ATTR_HTTP_REQUEST_METHOD,\n  ATTR_HTTP_REQUEST_METHOD_ORIGINAL,\n  ATTR_HTTP_RESPONSE_STATUS_CODE,\n  ATTR_NETWORK_PEER_ADDRESS,\n  ATTR_NETWORK_PEER_PORT,\n  ATTR_SERVER_ADDRESS,\n  ATTR_SERVER_PORT,\n  ATTR_URL_FULL,\n  ATTR_URL_PATH,\n  ATTR_URL_QUERY,\n  ATTR_URL_SCHEME,\n  ATTR_USER_AGENT_ORIGINAL,\n  METRIC_HTTP_CLIENT_REQUEST_DURATION,\n} from '@opentelemetry/semantic-conventions';\n\nimport type {\n  ListenerRecord,\n  RequestHeadersMessage,\n  RequestMessage,\n  RequestTrailersMessage,\n  ResponseHeadersMessage,\n} from './internal-types';\nimport type { UndiciInstrumentationConfig, UndiciRequest } from './types';\n\nimport { SDK_VERSION } from '@sentry/core';\n\ninterface InstrumentationRecord {\n  span: Span;\n  attributes: Attributes;\n  startTime: HrTime;\n}\n\nconst PACKAGE_NAME = '@sentry/instrumentation-undici';\n\n// A combination of https://github.com/elastic/apm-agent-nodejs and\n// https://github.com/gadget-inc/opentelemetry-instrumentations/blob/main/packages/opentelemetry-instrumentation-undici/src/index.ts\nexport class UndiciInstrumentation extends InstrumentationBase<UndiciInstrumentationConfig> {\n  // Keep ref to avoid https://github.com/nodejs/node/issues/42170 bug and for\n  // unsubscribing.\n  declare private _channelSubs: Array<ListenerRecord>;\n  private _recordFromReq = new WeakMap<UndiciRequest, InstrumentationRecord>();\n\n  declare private _httpClientDurationHistogram: Histogram;\n\n  constructor(config: UndiciInstrumentationConfig = {}) {\n    super(PACKAGE_NAME, SDK_VERSION, config);\n  }\n\n  // No need to instrument files/modules\n  protected override init() {\n    return undefined;\n  }\n\n  override disable(): void {\n    super.disable();\n    this._channelSubs.forEach(sub => sub.unsubscribe());\n    this._channelSubs.length = 0;\n  }\n\n  override enable(): void {\n    // \"enabled\" handling is currently a bit messy with InstrumentationBase.\n    // If constructed with `{enabled: false}`, this `.enable()` is still called,\n    // and `this.getConfig().enabled !== this.isEnabled()`, creating confusion.\n    //\n    // For now, this class will setup for instrumenting if `.enable()` is\n    // called, but use `this.getConfig().enabled` to determine if\n    // instrumentation should be generated. This covers the more likely common\n    // case of config being given a construction time, rather than later via\n    // `instance.enable()`, `.disable()`, or `.setConfig()` calls.\n    super.enable();\n\n    // This method is called by the super-class constructor before ours is\n    // called. So we need to ensure the property is initalized.\n    this._channelSubs = this._channelSubs || [];\n\n    // Avoid to duplicate subscriptions\n    if (this._channelSubs.length > 0) {\n      return;\n    }\n\n    this.subscribeToChannel('undici:request:create', this.onRequestCreated.bind(this));\n    this.subscribeToChannel('undici:client:sendHeaders', this.onRequestHeaders.bind(this));\n    this.subscribeToChannel('undici:request:headers', this.onResponseHeaders.bind(this));\n    this.subscribeToChannel('undici:request:trailers', this.onDone.bind(this));\n    this.subscribeToChannel('undici:request:error', this.onError.bind(this));\n  }\n\n  protected override _updateMetricInstruments() {\n    this._httpClientDurationHistogram = this.meter.createHistogram(METRIC_HTTP_CLIENT_REQUEST_DURATION, {\n      description: 'Measures the duration of outbound HTTP requests.',\n      unit: 's',\n      valueType: ValueType.DOUBLE,\n      advice: {\n        explicitBucketBoundaries: [0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10],\n      },\n    });\n  }\n\n  private subscribeToChannel(diagnosticChannel: string, onMessage: (message: any, name: string | symbol) => void) {\n    // `diagnostics_channel` had a ref counting bug until v18.19.0.\n    // https://github.com/nodejs/node/pull/47520\n    const [major = 0, minor = 0] = process.version\n      .replace('v', '')\n      .split('.')\n      .map(n => Number(n));\n    const useNewSubscribe = major > 18 || (major === 18 && minor >= 19);\n\n    let unsubscribe: () => void;\n    if (useNewSubscribe) {\n      diagch.subscribe?.(diagnosticChannel, onMessage);\n      unsubscribe = () => diagch.unsubscribe?.(diagnosticChannel, onMessage);\n    } else {\n      const channel = diagch.channel(diagnosticChannel);\n      channel.subscribe(onMessage);\n      unsubscribe = () => channel.unsubscribe(onMessage);\n    }\n\n    this._channelSubs.push({\n      name: diagnosticChannel,\n      unsubscribe,\n    });\n  }\n\n  private parseRequestHeaders(request: UndiciRequest) {\n    const result = new Map<string, string | string[]>();\n\n    if (Array.isArray(request.headers)) {\n      // headers are an array [k1, v2, k2, v2] (undici v6+)\n      // values could be string or a string[] for multiple values\n      for (let i = 0; i < request.headers.length; i += 2) {\n        const key = request.headers[i];\n        const value = request.headers[i + 1];\n\n        // Key should always be a string, but the types don't know that, and let's be safe\n        if (typeof key === 'string' && value !== undefined) {\n          result.set(key.toLowerCase(), value);\n        }\n      }\n    } else if (typeof request.headers === 'string') {\n      // headers are a raw string (undici v5)\n      // headers could be repeated in several lines for multiple values\n      const headers = request.headers.split('\\r\\n');\n      for (const line of headers) {\n        if (!line) {\n          continue;\n        }\n        const colonIndex = line.indexOf(':');\n        if (colonIndex === -1) {\n          // Invalid header? Probably this can't happen, but again let's be safe.\n          continue;\n        }\n        const key = line.substring(0, colonIndex).toLowerCase();\n        const value = line.substring(colonIndex + 1).trim();\n        const allValues = result.get(key);\n\n        if (allValues && Array.isArray(allValues)) {\n          allValues.push(value);\n        } else if (allValues) {\n          result.set(key, [allValues, value]);\n        } else {\n          result.set(key, value);\n        }\n      }\n    }\n    return result;\n  }\n\n  // This is the 1st message we receive for each request (fired after request creation). Here we will\n  // create the span and populate some atttributes, then link the span to the request for further\n  // span processing\n  private onRequestCreated({ request }: RequestMessage): void {\n    // Ignore if:\n    // - instrumentation is disabled\n    // - ignored by config\n    // - method is 'CONNECT'\n    const config = this.getConfig();\n    const enabled = config.enabled !== false;\n    const shouldIgnoreReq = safeExecuteInTheMiddle(\n      () => !enabled || request.method === 'CONNECT' || config.ignoreRequestHook?.(request),\n      e => e && this._diag.error('caught ignoreRequestHook error: ', e),\n      true,\n    );\n\n    if (shouldIgnoreReq) {\n      return;\n    }\n\n    const startTime = hrTime();\n    let requestUrl;\n    try {\n      requestUrl = new URL(request.path, request.origin);\n    } catch (err) {\n      this._diag.warn('could not determine url.full:', err);\n      // Skip instrumenting this request.\n      return;\n    }\n    const urlScheme = requestUrl.protocol.replace(':', '');\n    const requestMethod = this.getRequestMethod(request.method);\n    const attributes: Attributes = {\n      [ATTR_HTTP_REQUEST_METHOD]: requestMethod,\n      [ATTR_HTTP_REQUEST_METHOD_ORIGINAL]: request.method,\n      [ATTR_URL_FULL]: requestUrl.toString(),\n      [ATTR_URL_PATH]: requestUrl.pathname,\n      [ATTR_URL_QUERY]: requestUrl.search,\n      [ATTR_URL_SCHEME]: urlScheme,\n    };\n\n    const schemePorts: Record<string, string> = { https: '443', http: '80' };\n    const serverAddress = requestUrl.hostname;\n    const serverPort = requestUrl.port || schemePorts[urlScheme];\n\n    attributes[ATTR_SERVER_ADDRESS] = serverAddress;\n    if (serverPort && !isNaN(Number(serverPort))) {\n      attributes[ATTR_SERVER_PORT] = Number(serverPort);\n    }\n\n    // Get user agent from headers\n    const headersMap = this.parseRequestHeaders(request);\n    const userAgentValues = headersMap.get('user-agent');\n\n    if (userAgentValues) {\n      // NOTE: having multiple user agents is not expected so\n      // we're going to take last one like `curl` does\n      // ref: https://curl.se/docs/manpage.html#-A\n      const userAgent = Array.isArray(userAgentValues) ? userAgentValues[userAgentValues.length - 1] : userAgentValues;\n      attributes[ATTR_USER_AGENT_ORIGINAL] = userAgent;\n    }\n\n    // Get attributes from the hook if present\n    const hookAttributes = safeExecuteInTheMiddle(\n      () => config.startSpanHook?.(request),\n      e => e && this._diag.error('caught startSpanHook error: ', e),\n      true,\n    );\n    if (hookAttributes) {\n      Object.entries(hookAttributes).forEach(([key, val]) => {\n        attributes[key] = val;\n      });\n    }\n\n    // Check if parent span is required via config and:\n    // - if a parent is required but not present, we use a `NoopSpan` to still\n    //   propagate context without recording it.\n    // - create a span otherwise\n    const activeCtx = context.active();\n    const currentSpan = trace.getSpan(activeCtx);\n    let span: Span;\n\n    if (config.requireParentforSpans && (!currentSpan || !trace.isSpanContextValid(currentSpan.spanContext()))) {\n      span = trace.wrapSpanContext(INVALID_SPAN_CONTEXT);\n    } else {\n      span = this.tracer.startSpan(\n        requestMethod === '_OTHER' ? 'HTTP' : requestMethod,\n        {\n          kind: SpanKind.CLIENT,\n          attributes: attributes,\n        },\n        activeCtx,\n      );\n    }\n\n    // Execute the request hook if defined\n    safeExecuteInTheMiddle(\n      () => config.requestHook?.(span, request),\n      e => e && this._diag.error('caught requestHook error: ', e),\n      true,\n    );\n\n    // Context propagation goes last so no hook can tamper\n    // the propagation headers\n    const requestContext = trace.setSpan(context.active(), span);\n    const addedHeaders: Record<string, string> = {};\n    propagation.inject(requestContext, addedHeaders);\n\n    const headerEntries = Object.entries(addedHeaders);\n\n    for (let i = 0; i < headerEntries.length; i++) {\n      const pair = headerEntries[i];\n      if (!pair) {\n        continue;\n      }\n      const [k, v] = pair;\n\n      if (typeof request.addHeader === 'function') {\n        request.addHeader(k, v);\n      } else if (typeof request.headers === 'string') {\n        request.headers += `${k}: ${v}\\r\\n`;\n      } else if (Array.isArray(request.headers)) {\n        // undici@6.11.0 accidentally, briefly removed `request.addHeader()`.\n        request.headers.push(k, v);\n      }\n    }\n    this._recordFromReq.set(request, { span, attributes, startTime });\n  }\n\n  // This is the 2nd message we receive for each request. It is fired when connection with\n  // the remote is established and about to send the first byte. Here we do have info about the\n  // remote address and port so we can populate some `network.*` attributes into the span\n  private onRequestHeaders({ request, socket }: RequestHeadersMessage): void {\n    const record = this._recordFromReq.get(request);\n\n    if (!record) {\n      return;\n    }\n\n    const config = this.getConfig();\n    const { span } = record;\n    const { remoteAddress, remotePort } = socket;\n    const spanAttributes: Attributes = {\n      [ATTR_NETWORK_PEER_ADDRESS]: remoteAddress,\n      [ATTR_NETWORK_PEER_PORT]: remotePort,\n    };\n\n    // After hooks have been processed (which may modify request headers)\n    // we can collect the headers based on the configuration\n    if (config.headersToSpanAttributes?.requestHeaders) {\n      const headersToAttribs = new Set(config.headersToSpanAttributes.requestHeaders.map(n => n.toLowerCase()));\n      const headersMap = this.parseRequestHeaders(request);\n\n      for (const [name, value] of headersMap.entries()) {\n        if (headersToAttribs.has(name)) {\n          const attrValue = Array.isArray(value) ? value : [value];\n          spanAttributes[`http.request.header.${name}`] = attrValue;\n        }\n      }\n    }\n\n    span.setAttributes(spanAttributes);\n  }\n\n  // This is the 3rd message we get for each request and it's fired when the server\n  // headers are received, body may not be accessible yet.\n  // From the response headers we can set the status and content length\n  private onResponseHeaders({ request, response }: ResponseHeadersMessage): void {\n    const record = this._recordFromReq.get(request);\n\n    if (!record) {\n      return;\n    }\n\n    const { span, attributes } = record;\n    const spanAttributes: Attributes = {\n      [ATTR_HTTP_RESPONSE_STATUS_CODE]: response.statusCode,\n    };\n\n    const config = this.getConfig();\n\n    // Execute the response hook if defined\n    safeExecuteInTheMiddle(\n      () => config.responseHook?.(span, { request, response }),\n      e => e && this._diag.error('caught responseHook error: ', e),\n      true,\n    );\n\n    if (config.headersToSpanAttributes?.responseHeaders) {\n      const headersToAttribs = new Set();\n      config.headersToSpanAttributes?.responseHeaders.forEach(name => headersToAttribs.add(name.toLowerCase()));\n\n      for (let idx = 0; idx < response.headers.length; idx = idx + 2) {\n        const nameBuf = response.headers[idx];\n        const valueBuf = response.headers[idx + 1];\n        if (nameBuf === undefined || valueBuf === undefined) {\n          continue;\n        }\n        const name = nameBuf.toString().toLowerCase();\n        const value = valueBuf;\n\n        if (headersToAttribs.has(name)) {\n          const attrName = `http.response.header.${name}`;\n          if (!Object.prototype.hasOwnProperty.call(spanAttributes, attrName)) {\n            spanAttributes[attrName] = [value.toString()];\n          } else {\n            (spanAttributes[attrName] as string[]).push(value.toString());\n          }\n        }\n      }\n    }\n\n    span.setAttributes(spanAttributes);\n    span.setStatus({\n      code: response.statusCode >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.UNSET,\n    });\n    record.attributes = Object.assign(attributes, spanAttributes);\n  }\n\n  // This is the last event we receive if the request went without any errors\n  private onDone({ request }: RequestTrailersMessage): void {\n    const record = this._recordFromReq.get(request);\n\n    if (!record) {\n      return;\n    }\n\n    const { span, attributes, startTime } = record;\n\n    // End the span\n    span.end();\n    this._recordFromReq.delete(request);\n\n    // Record metrics\n    this.recordRequestDuration(attributes, startTime);\n  }\n\n  // This is the event we get when something is wrong in the request like\n  // - invalid options when calling `fetch` global API or any undici method for request\n  // - connectivity errors such as unreachable host\n  // - requests aborted through an `AbortController.signal`\n  // NOTE: server errors are considered valid responses and it's the lib consumer\n  // who should deal with that.\n  private onError({ request, error }: any): void {\n    const record = this._recordFromReq.get(request);\n\n    if (!record) {\n      return;\n    }\n\n    const { span, attributes, startTime } = record;\n\n    // NOTE: in `undici@6.3.0` when request aborted the error type changes from\n    // a custom error (`RequestAbortedError`) to a built-in `DOMException` carrying\n    // some differences:\n    // - `code` is from DOMEXception (ABORT_ERR: 20)\n    // - `message` changes\n    // - stacktrace is smaller and contains node internal frames\n    span.recordException(error);\n    span.setStatus({\n      code: SpanStatusCode.ERROR,\n      message: error.message,\n    });\n    span.end();\n    this._recordFromReq.delete(request);\n\n    // Record metrics (with the error)\n    attributes[ATTR_ERROR_TYPE] = error.message;\n    this.recordRequestDuration(attributes, startTime);\n  }\n\n  private recordRequestDuration(attributes: Attributes, startTime: HrTime) {\n    // Time to record metrics\n    const metricsAttributes: Attributes = {};\n    // Get the attribs already in span attributes\n    const keysToCopy = [\n      ATTR_HTTP_RESPONSE_STATUS_CODE,\n      ATTR_HTTP_REQUEST_METHOD,\n      ATTR_SERVER_ADDRESS,\n      ATTR_SERVER_PORT,\n      ATTR_URL_SCHEME,\n      ATTR_ERROR_TYPE,\n    ];\n    keysToCopy.forEach(key => {\n      if (key in attributes) {\n        metricsAttributes[key] = attributes[key];\n      }\n    });\n\n    // Take the duration and record it\n    const durationSeconds = hrTimeToMilliseconds(hrTimeDuration(startTime, hrTime())) / 1000;\n    this._httpClientDurationHistogram.record(durationSeconds, metricsAttributes);\n  }\n\n  private getRequestMethod(original: string): string {\n    const knownMethods = {\n      CONNECT: true,\n      OPTIONS: true,\n      HEAD: true,\n      GET: true,\n      POST: true,\n      PUT: true,\n      PATCH: true,\n      DELETE: true,\n      TRACE: true,\n      // QUERY from https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/\n      QUERY: true,\n    };\n\n    if (original.toUpperCase() in knownMethods) {\n      return original.toUpperCase();\n    }\n\n    return '_OTHER';\n  }\n}\n"],"names":[],"mappings":"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"}