| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 | var {  _optionalChain} = require('@sentry/utils');Object.defineProperty(exports, '__esModule', { value: true });const core = require('@sentry/core');const utils = require('@sentry/utils');const debugBuild = require('../debug-build.js');const nodeVersion = require('../nodeVersion.js');const http = require('./utils/http.js');const _httpIntegration = ((options = {}) => {  const { breadcrumbs, tracing, shouldCreateSpanForRequest } = options;  const convertedOptions = {    breadcrumbs,    tracing:      tracing === false        ? false        : utils.dropUndefinedKeys({            // If tracing is forced to `true`, we don't want to set `enableIfHasTracingEnabled`            enableIfHasTracingEnabled: tracing === true ? undefined : true,            shouldCreateSpanForRequest,          }),  };  // eslint-disable-next-line deprecation/deprecation  return new Http(convertedOptions) ;}) ;/** * The http module integration instruments Node's internal http module. It creates breadcrumbs, spans for outgoing * http requests, and attaches trace data when tracing is enabled via its `tracing` option. * * By default, this will always create breadcrumbs, and will create spans if tracing is enabled. */const httpIntegration = core.defineIntegration(_httpIntegration);/** * The http module integration instruments Node's internal http module. It creates breadcrumbs, transactions for outgoing * http requests and attaches trace data when tracing is enabled via its `tracing` option. * * @deprecated Use `httpIntegration()` instead. */class Http  {  /**   * @inheritDoc   */   static __initStatic() {this.id = 'Http';}  /**   * @inheritDoc   */  // eslint-disable-next-line deprecation/deprecation   __init() {this.name = Http.id;}  /**   * @inheritDoc   */   constructor(options = {}) {Http.prototype.__init.call(this);    this._breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;    this._tracing = !options.tracing ? undefined : options.tracing === true ? {} : options.tracing;  }  /**   * @inheritDoc   */   setupOnce(    _addGlobalEventProcessor,    setupOnceGetCurrentHub,  ) {    // eslint-disable-next-line deprecation/deprecation    const clientOptions = _optionalChain([setupOnceGetCurrentHub, 'call', _ => _(), 'access', _2 => _2.getClient, 'call', _3 => _3(), 'optionalAccess', _4 => _4.getOptions, 'call', _5 => _5()]);    // If `tracing` is not explicitly set, we default this based on whether or not tracing is enabled.    // But for compatibility, we only do that if `enableIfHasTracingEnabled` is set.    const shouldCreateSpans = _shouldCreateSpans(this._tracing, clientOptions);    // No need to instrument if we don't want to track anything    if (!this._breadcrumbs && !shouldCreateSpans) {      return;    }    // Do not auto-instrument for other instrumenter    if (clientOptions && clientOptions.instrumenter !== 'sentry') {      debugBuild.DEBUG_BUILD && utils.logger.log('HTTP Integration is skipped because of instrumenter configuration.');      return;    }    const shouldCreateSpanForRequest = _getShouldCreateSpanForRequest(shouldCreateSpans, this._tracing, clientOptions);    // eslint-disable-next-line deprecation/deprecation    const tracePropagationTargets = _optionalChain([clientOptions, 'optionalAccess', _6 => _6.tracePropagationTargets]) || _optionalChain([this, 'access', _7 => _7._tracing, 'optionalAccess', _8 => _8.tracePropagationTargets]);    // eslint-disable-next-line @typescript-eslint/no-var-requires    const httpModule = require('http');    const wrappedHttpHandlerMaker = _createWrappedRequestMethodFactory(      httpModule,      this._breadcrumbs,      shouldCreateSpanForRequest,      tracePropagationTargets,    );    utils.fill(httpModule, 'get', wrappedHttpHandlerMaker);    utils.fill(httpModule, 'request', wrappedHttpHandlerMaker);    // NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it.    // If we do, we'd get double breadcrumbs and double spans for `https` calls.    // It has been changed in Node 9, so for all versions equal and above, we patch `https` separately.    if (nodeVersion.NODE_VERSION.major > 8) {      // eslint-disable-next-line @typescript-eslint/no-var-requires      const httpsModule = require('https');      const wrappedHttpsHandlerMaker = _createWrappedRequestMethodFactory(        httpsModule,        this._breadcrumbs,        shouldCreateSpanForRequest,        tracePropagationTargets,      );      utils.fill(httpsModule, 'get', wrappedHttpsHandlerMaker);      utils.fill(httpsModule, 'request', wrappedHttpsHandlerMaker);    }  }}Http.__initStatic();// for ease of reading below/** * Function which creates a function which creates wrapped versions of internal `request` and `get` calls within `http` * and `https` modules. (NB: Not a typo - this is a creator^2!) * * @param breadcrumbsEnabled Whether or not to record outgoing requests as breadcrumbs * @param tracingEnabled Whether or not to record outgoing requests as tracing spans * * @returns A function which accepts the exiting handler and returns a wrapped handler */function _createWrappedRequestMethodFactory(  httpModule,  breadcrumbsEnabled,  shouldCreateSpanForRequest,  tracePropagationTargets,) {  // We're caching results so we don't have to recompute regexp every time we create a request.  const createSpanUrlMap = new utils.LRUMap(100);  const headersUrlMap = new utils.LRUMap(100);  const shouldCreateSpan = (url) => {    if (shouldCreateSpanForRequest === undefined) {      return true;    }    const cachedDecision = createSpanUrlMap.get(url);    if (cachedDecision !== undefined) {      return cachedDecision;    }    const decision = shouldCreateSpanForRequest(url);    createSpanUrlMap.set(url, decision);    return decision;  };  const shouldAttachTraceData = (url) => {    if (tracePropagationTargets === undefined) {      return true;    }    const cachedDecision = headersUrlMap.get(url);    if (cachedDecision !== undefined) {      return cachedDecision;    }    const decision = utils.stringMatchesSomePattern(url, tracePropagationTargets);    headersUrlMap.set(url, decision);    return decision;  };  /**   * Captures Breadcrumb based on provided request/response pair   */  function addRequestBreadcrumb(    event,    requestSpanData,    req,    res,  ) {    // eslint-disable-next-line deprecation/deprecation    if (!core.getCurrentHub().getIntegration(Http)) {      return;    }    core.addBreadcrumb(      {        category: 'http',        data: {          status_code: res && res.statusCode,          ...requestSpanData,        },        type: 'http',      },      {        event,        request: req,        response: res,      },    );  }  return function wrappedRequestMethodFactory(originalRequestMethod) {    return function wrappedMethod( ...args) {      const requestArgs = http.normalizeRequestArgs(httpModule, args);      const requestOptions = requestArgs[0];      // eslint-disable-next-line deprecation/deprecation      const rawRequestUrl = http.extractRawUrl(requestOptions);      const requestUrl = http.extractUrl(requestOptions);      const client = core.getClient();      // we don't want to record requests to Sentry as either breadcrumbs or spans, so just use the original method      if (core.isSentryRequestUrl(requestUrl, client)) {        return originalRequestMethod.apply(httpModule, requestArgs);      }      const scope = core.getCurrentScope();      const isolationScope = core.getIsolationScope();      const parentSpan = core.getActiveSpan();      const data = getRequestSpanData(requestUrl, requestOptions);      const requestSpan = shouldCreateSpan(rawRequestUrl)        ? // eslint-disable-next-line deprecation/deprecation          _optionalChain([parentSpan, 'optionalAccess', _9 => _9.startChild, 'call', _10 => _10({            op: 'http.client',            origin: 'auto.http.node.http',            description: `${data['http.method']} ${data.url}`,            data,          })])        : undefined;      if (client && shouldAttachTraceData(rawRequestUrl)) {        const { traceId, spanId, sampled, dsc } = {          ...isolationScope.getPropagationContext(),          ...scope.getPropagationContext(),        };        const sentryTraceHeader = requestSpan          ? core.spanToTraceHeader(requestSpan)          : utils.generateSentryTraceHeader(traceId, spanId, sampled);        const sentryBaggageHeader = utils.dynamicSamplingContextToSentryBaggageHeader(          dsc ||            (requestSpan              ? core.getDynamicSamplingContextFromSpan(requestSpan)              : core.getDynamicSamplingContextFromClient(traceId, client, scope)),        );        addHeadersToRequestOptions(requestOptions, requestUrl, sentryTraceHeader, sentryBaggageHeader);      } else {        debugBuild.DEBUG_BUILD &&          utils.logger.log(            `[Tracing] Not adding sentry-trace header to outgoing request (${requestUrl}) due to mismatching tracePropagationTargets option.`,          );      }      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access      return originalRequestMethod        .apply(httpModule, requestArgs)        .once('response', function ( res) {          // eslint-disable-next-line @typescript-eslint/no-this-alias          const req = this;          if (breadcrumbsEnabled) {            addRequestBreadcrumb('response', data, req, res);          }          if (requestSpan) {            if (res.statusCode) {              core.setHttpStatus(requestSpan, res.statusCode);            }            requestSpan.updateName(              http.cleanSpanDescription(core.spanToJSON(requestSpan).description || '', requestOptions, req) || '',            );            requestSpan.end();          }        })        .once('error', function () {          // eslint-disable-next-line @typescript-eslint/no-this-alias          const req = this;          if (breadcrumbsEnabled) {            addRequestBreadcrumb('error', data, req);          }          if (requestSpan) {            core.setHttpStatus(requestSpan, 500);            requestSpan.updateName(              http.cleanSpanDescription(core.spanToJSON(requestSpan).description || '', requestOptions, req) || '',            );            requestSpan.end();          }        });    };  };}function addHeadersToRequestOptions(  requestOptions,  requestUrl,  sentryTraceHeader,  sentryBaggageHeader,) {  // Don't overwrite sentry-trace and baggage header if it's already set.  const headers = requestOptions.headers || {};  if (headers['sentry-trace']) {    return;  }  debugBuild.DEBUG_BUILD &&    utils.logger.log(`[Tracing] Adding sentry-trace header ${sentryTraceHeader} to outgoing request to "${requestUrl}": `);  requestOptions.headers = {    ...requestOptions.headers,    'sentry-trace': sentryTraceHeader,    // Setting a header to `undefined` will crash in node so we only set the baggage header when it's defined    ...(sentryBaggageHeader &&      sentryBaggageHeader.length > 0 && { baggage: normalizeBaggageHeader(requestOptions, sentryBaggageHeader) }),  };}function getRequestSpanData(requestUrl, requestOptions) {  const method = requestOptions.method || 'GET';  const data = {    url: requestUrl,    'http.method': method,  };  if (requestOptions.hash) {    // strip leading "#"    data['http.fragment'] = requestOptions.hash.substring(1);  }  if (requestOptions.search) {    // strip leading "?"    data['http.query'] = requestOptions.search.substring(1);  }  return data;}function normalizeBaggageHeader(  requestOptions,  sentryBaggageHeader,) {  if (!requestOptions.headers || !requestOptions.headers.baggage) {    return sentryBaggageHeader;  } else if (!sentryBaggageHeader) {    return requestOptions.headers.baggage ;  } else if (Array.isArray(requestOptions.headers.baggage)) {    return [...requestOptions.headers.baggage, sentryBaggageHeader];  }  // Type-cast explanation:  // Technically this the following could be of type `(number | string)[]` but for the sake of simplicity  // we say this is undefined behaviour, since it would not be baggage spec conform if the user did this.  return [requestOptions.headers.baggage, sentryBaggageHeader] ;}/** Exported for tests only. */function _shouldCreateSpans(  tracingOptions,  clientOptions,) {  return tracingOptions === undefined    ? false    : tracingOptions.enableIfHasTracingEnabled      ? core.hasTracingEnabled(clientOptions)      : true;}/** Exported for tests only. */function _getShouldCreateSpanForRequest(  shouldCreateSpans,  tracingOptions,  clientOptions,) {  const handler = shouldCreateSpans    ? // eslint-disable-next-line deprecation/deprecation      _optionalChain([tracingOptions, 'optionalAccess', _11 => _11.shouldCreateSpanForRequest]) || _optionalChain([clientOptions, 'optionalAccess', _12 => _12.shouldCreateSpanForRequest])    : () => false;  return handler;}exports.Http = Http;exports._getShouldCreateSpanForRequest = _getShouldCreateSpanForRequest;exports._shouldCreateSpans = _shouldCreateSpans;exports.httpIntegration = httpIntegration;//# sourceMappingURL=http.js.map
 |