From 4d2f5b86a0e996c76aee85ff695658e277aefd87 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Wed, 2 Oct 2024 12:14:25 +0200 Subject: [PATCH] Don't use deprecated url.parse function (#4743) --- .../dd-trace/src/exporters/common/request.js | 42 ++++--------------- .../common/url-to-http-options-polyfill.js | 31 ++++++++++++++ 2 files changed, 39 insertions(+), 34 deletions(-) create mode 100644 packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js diff --git a/packages/dd-trace/src/exporters/common/request.js b/packages/dd-trace/src/exporters/common/request.js index 6823119c0d8..ab8b697eef6 100644 --- a/packages/dd-trace/src/exporters/common/request.js +++ b/packages/dd-trace/src/exporters/common/request.js @@ -6,10 +6,9 @@ const { Readable } = require('stream') const http = require('http') const https = require('https') -// eslint-disable-next-line n/no-deprecated-api -const { parse: urlParse } = require('url') const zlib = require('zlib') +const { urlToHttpOptions } = require('./url-to-http-options-polyfill') const docker = require('./docker') const { httpAgent, httpsAgent } = require('./agents') const { storage } = require('../../../../datadog-core') @@ -20,39 +19,14 @@ const containerId = docker.id() let activeRequests = 0 -// TODO: Replace with `url.urlToHttpOptions` when supported by all versions -function urlToOptions (url) { - const agent = url.agent || http.globalAgent - const options = { - protocol: url.protocol || agent.protocol, - hostname: typeof url.hostname === 'string' && url.hostname.startsWith('[') - ? url.hostname.slice(1, -1) - : url.hostname || - url.host || - 'localhost', - 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 -} +function parseUrl (urlObjOrString) { + if (typeof urlObjOrString === 'object') return urlToHttpOptions(urlObjOrString) -function fromUrlString (urlString) { - const url = typeof urlToHttpOptions === 'function' - ? urlToOptions(new URL(urlString)) - : urlParse(urlString) + const url = urlToHttpOptions(new URL(urlObjOrString)) - // Add the 'hostname' back if we're using named pipes - if (url.protocol === 'unix:' && url.host === '.') { - const udsPath = urlString.replace(/^unix:/, '') + // Special handling if we're using named pipes on Windows + if (url.protocol === 'unix:' && url.hostname === '.') { + const udsPath = urlObjOrString.slice(5) url.path = udsPath url.pathname = udsPath } @@ -66,7 +40,7 @@ function request (data, options, callback) { } if (options.url) { - const url = typeof options.url === 'object' ? urlToOptions(options.url) : fromUrlString(options.url) + const url = parseUrl(options.url) if (url.protocol === 'unix:') { options.socketPath = url.pathname } else { diff --git a/packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js b/packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js new file mode 100644 index 00000000000..4ba6b337b08 --- /dev/null +++ b/packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js @@ -0,0 +1,31 @@ +'use strict' + +const { urlToHttpOptions } = require('url') + +// TODO: Remove `urlToHttpOptions` polyfill once we drop support for the older Cypress versions that uses a built-in +// version of Node.js doesn't include that function. +module.exports = { + urlToHttpOptions: urlToHttpOptions ?? function (url) { + const { hostname, pathname, port, username, password, search } = url + const options = { + __proto__: null, + ...url, // In case the url object was extended by the user. + protocol: url.protocol, + hostname: typeof hostname === 'string' && hostname.startsWith('[') + ? hostname.slice(1, -1) + : hostname, + hash: url.hash, + search, + pathname, + path: `${pathname || ''}${search || ''}`, + href: url.href + } + if (port !== '') { + options.port = Number(port) + } + if (username || password) { + options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(password)}` + } + return options + } +}