Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var core_1 = require("@sentry/core");
var utils_1 = require("@sentry/utils");
var url_1 = require("url");
var NODE_VERSION = utils_1.parseSemver(process.versions.node);
/**
 * Checks whether given url points to Sentry server
 * @param url url to verify
 */
function isSentryRequest(url) {
    var _a;
    var dsn = (_a = core_1.getCurrentHub().getClient()) === null || _a === void 0 ? void 0 : _a.getDsn();
    return dsn ? url.includes(dsn.host) : false;
}
exports.isSentryRequest = isSentryRequest;
/**
 * Assemble a URL to be used for breadcrumbs and spans.
 *
 * @param requestOptions RequestOptions object containing the component parts for a URL
 * @returns Fully-formed URL
 */
function extractUrl(requestOptions) {
    var protocol = requestOptions.protocol || '';
    var hostname = requestOptions.hostname || requestOptions.host || '';
    // Don't log standard :80 (http) and :443 (https) ports to reduce the noise
    var port = !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 ? '' : ":" + requestOptions.port;
    var path = requestOptions.path ? requestOptions.path : '/';
    return protocol + "//" + hostname + port + path;
}
exports.extractUrl = extractUrl;
/**
 * Handle various edge cases in the span description (for spans representing http(s) requests).
 *
 * @param description current `description` property of the span representing the request
 * @param requestOptions Configuration data for the request
 * @param Request Request object
 *
 * @returns The cleaned description
 */
function cleanSpanDescription(description, requestOptions, request) {
    var _a, _b, _c;
    // nothing to clean
    if (!description) {
        return description;
    }
    // eslint-disable-next-line prefer-const
    var _d = tslib_1.__read(description.split(' '), 2), method = _d[0], requestUrl = _d[1];
    // superagent sticks the protocol in a weird place (we check for host because if both host *and* protocol are missing,
    // we're likely dealing with an internal route and this doesn't apply)
    if (requestOptions.host && !requestOptions.protocol) {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
        requestOptions.protocol = (_b = (_a = request) === null || _a === void 0 ? void 0 : _a.agent) === null || _b === void 0 ? void 0 : _b.protocol; // worst comes to worst, this is undefined and nothing changes
        requestUrl = extractUrl(requestOptions);
    }
    // internal routes can end up starting with a triple slash rather than a single one
    if ((_c = requestUrl) === null || _c === void 0 ? void 0 : _c.startsWith('///')) {
        requestUrl = requestUrl.slice(2);
    }
    return method + " " + requestUrl;
}
exports.cleanSpanDescription = cleanSpanDescription;
/**
 * Convert a URL object into a RequestOptions object.
 *
 * Copied from Node's internals (where it's used in http(s).request() and http(s).get()), modified only to use the
 * RequestOptions type above.
 *
 * See https://github.com/nodejs/node/blob/master/lib/internal/url.js.
 */
function urlToOptions(url) {
    var options = {
        protocol: url.protocol,
        hostname: typeof url.hostname === 'string' && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
        hash: url.hash,
        search: url.search,
        pathname: url.pathname,
        path: "" + (url.pathname || '') + (url.search || ''),
        href: url.href,
    };
    if (url.port !== '') {
        options.port = Number(url.port);
    }
    if (url.username || url.password) {
        options.auth = url.username + ":" + url.password;
    }
    return options;
}
exports.urlToOptions = urlToOptions;
/**
 * Normalize inputs to `http(s).request()` and `http(s).get()`.
 *
 * Legal inputs to `http(s).request()` and `http(s).get()` can take one of ten forms:
 *     [ RequestOptions | string | URL ],
 *     [ RequestOptions | string | URL, RequestCallback ],
 *     [ string | URL, RequestOptions ], and
 *     [ string | URL, RequestOptions, RequestCallback ].
 *
 * This standardizes to one of two forms: [ RequestOptions ] and [ RequestOptions, RequestCallback ]. A similar thing is
 * done as the first step of `http(s).request()` and `http(s).get()`; this just does it early so that we can interact
 * with the args in a standard way.
 *
 * @param requestArgs The inputs to `http(s).request()` or `http(s).get()`, as an array.
 *
 * @returns Equivalent args of the form [ RequestOptions ] or [ RequestOptions, RequestCallback ].
 */
function normalizeRequestArgs(httpModule, requestArgs) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    var callback, requestOptions;
    // pop off the callback, if there is one
    if (typeof requestArgs[requestArgs.length - 1] === 'function') {
        callback = requestArgs.pop();
    }
    // create a RequestOptions object of whatever's at index 0
    if (typeof requestArgs[0] === 'string') {
        requestOptions = urlToOptions(new url_1.URL(requestArgs[0]));
    }
    else if (requestArgs[0] instanceof url_1.URL) {
        requestOptions = urlToOptions(requestArgs[0]);
    }
    else {
        requestOptions = requestArgs[0];
    }
    // if the options were given separately from the URL, fold them in
    if (requestArgs.length === 2) {
        requestOptions = tslib_1.__assign(tslib_1.__assign({}, requestOptions), requestArgs[1]);
    }
    // Figure out the protocol if it's currently missing
    if (requestOptions.protocol === undefined) {
        // Worst case we end up populating protocol with undefined, which it already is
        /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
        // NOTE: Prior to Node 9, `https` used internals of `http` module, thus we don't patch it.
        // Because of that, we cannot rely on `httpModule` to provide us with valid protocol,
        // as it will always return `http`, even when using `https` module.
        //
        // See test/integrations/http.test.ts for more details on Node <=v8 protocol issue.
        if (NODE_VERSION.major && NODE_VERSION.major > 8) {
            requestOptions.protocol =
                ((_b = (_a = httpModule) === null || _a === void 0 ? void 0 : _a.globalAgent) === null || _b === void 0 ? void 0 : _b.protocol) || ((_c = requestOptions.agent) === null || _c === void 0 ? void 0 : _c.protocol) || ((_d = requestOptions._defaultAgent) === null || _d === void 0 ? void 0 : _d.protocol);
        }
        else {
            requestOptions.protocol =
                ((_e = requestOptions.agent) === null || _e === void 0 ? void 0 : _e.protocol) || ((_f = requestOptions._defaultAgent) === null || _f === void 0 ? void 0 : _f.protocol) || ((_h = (_g = httpModule) === null || _g === void 0 ? void 0 : _g.globalAgent) === null || _h === void 0 ? void 0 : _h.protocol);
        }
        /* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
    }
    // return args in standardized form
    if (callback) {
        return [requestOptions, callback];
    }
    else {
        return [requestOptions];
    }
}
exports.normalizeRequestArgs = normalizeRequestArgs;
//# sourceMappingURL=http.js.map