UNPKG

@sap-cloud-sdk/core

Version:
155 lines • 7.2 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.urlAndAgent = exports.getUrlProtocol = exports.getAgentConfig = void 0; var https_1 = __importDefault(require("https")); var http_1 = __importDefault(require("http")); var util_1 = require("@sap-cloud-sdk/util"); var scp_cf_1 = require("../connectivity/scp-cf"); var proxy_util_1 = require("./proxy-util"); var logger = (0, util_1.createLogger)({ package: 'core', messageContext: 'http-agent' }); /** * Returns the http or https-agent config depending on the destination URL. * If the destination contains a proxy configuration, the agent will be a proxy-agent. * If not it will be the default http-agent coming from node. * @param destination - determining which kind of configuration is returned * @returns The http or http-agent configuration. */ function getAgentConfig(destination) { var agentType = destination.proxyConfiguration ? AgentType.PROXY : AgentType.DEFAULT; // eslint-disable-next-line @typescript-eslint/no-shadow var certificateOptions = getCertificateOption(destination); if (agentType === AgentType.PROXY) { return createProxyAgent(destination, certificateOptions); } return createDefaultAgent(destination, certificateOptions); } exports.getAgentConfig = getAgentConfig; var AgentType; (function (AgentType) { AgentType[AgentType["DEFAULT"] = 0] = "DEFAULT"; AgentType[AgentType["PROXY"] = 1] = "PROXY"; })(AgentType || (AgentType = {})); function createProxyAgent(destination, options) { if (!destination.proxyConfiguration) { throw new Error("The destination proxy configuration: ".concat(destination.proxyConfiguration, " is undefined.")); } return (0, proxy_util_1.proxyAgent)(destination, options); } var trustAllOptions = function (destination) { return function (options) { return (0, util_1.assoc)('rejectUnauthorized', !destination.isTrustingAllCertificates, options); }; }; var certificateOptions = function (destination) { return function (options) { if (destination.keyStoreName && destination.keyStorePassword) { var certificate = selectCertificate(destination); logger.debug("Certificate with name \"".concat(certificate.name, "\" selected.")); return __assign(__assign({}, options), { pfx: Buffer.from(certificate.content, 'base64'), passphrase: destination.keyStorePassword }); } return options; }; }; /** * @hidden * The http agents (proxy and default) use node tls for the certificate handling. This method creates the options with the pfx and passphrase. * https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options * @param destination - Destination object * @returns Options, which can be used later by tls.createSecureContext() e.g. pfx and passphrase or an empty object, if the protocol is not 'https:' or no client information are in the definition. */ function getCertificateOption(destination) { // http case: no certificate needed if ((0, scp_cf_1.getProtocolOrDefault)(destination) === scp_cf_1.Protocol.HTTP) { if (destination.isTrustingAllCertificates) { logger.warn('"isTrustingAllCertificates" is not available for HTTP.'); } return {}; } // https case: get certificate options if (destination.isTrustingAllCertificates) { logger.warn('"isTrustingAllCertificates" property in the provided destination is set to "true". This is highly discouraged in production.'); } var options = trustAllOptions(destination)({}); return certificateOptions(destination)(options); } var supportedCertificateFormats = ['p12', 'pfx']; function hasSupportedFormat(certificate) { var certificateFormat = (0, util_1.last)(certificate.name.split('.')); if (certificateFormat) { return supportedCertificateFormats.includes(certificateFormat); } return false; } function selectCertificate(destination) { var certificate = destination.certificates.find(function (c) { return c.name === destination.keyStoreName; }); if (!certificate) { throw Error("No certificate with name ".concat(destination.keyStoreName, " could be found on the destination!")); } if (!hasSupportedFormat(certificate)) { var format = (0, util_1.last)(certificate.name.split('.')); throw Error("The format of the provided certificate '".concat(certificate.name, "' is not supported. Supported formats are: ").concat(supportedCertificateFormats.join(', '), ". ").concat(format && ['jks', 'keystore'].includes(format) ? "You can convert Java Keystores (.jks, .keystore) into PKCS#12 keystores using the JVM's keytool CLI: keytool -importkeystore -srckeystore your-keystore.jks -destkeystore your-keystore.p12 -deststoretype pkcs12" : '')); } return certificate; } // eslint-disable-next-line valid-jsdoc /** * @hidden * See https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener for details on the possible options */ function createDefaultAgent(destination, options) { if ((0, scp_cf_1.getProtocolOrDefault)(destination) === scp_cf_1.Protocol.HTTPS) { return { httpsAgent: new https_1.default.Agent(options) }; } return { httpAgent: new http_1.default.Agent(options) }; } /** * @deprecated Since v1.5.1. use getProtocolOrDefault instead * Takes the destination URL and return everything before the `://`. * @param destination - URL of this destination is parsed * @returns The protocol either `undefined` if no `://` is found or anything before the delimiter. */ function getUrlProtocol(destination) { if (destination.url) { var urlParts = destination.url.toLowerCase().split('://'); if (urlParts.length > 1) { return urlParts[0]; } } } exports.getUrlProtocol = getUrlProtocol; /** * Builds part of the request config containing the URL and if needed proxy agents or normal http agents. * Considers the `no_proxy` environment variable together with the `targetUri`. * @param targetUri - Used as baseURL in request config. * @returns HttpRequestConfig containing baseUrl and http(s) agents. */ function urlAndAgent(targetUri) { var destination = { url: targetUri, proxyType: 'Internet' }; if ((0, proxy_util_1.proxyStrategy)(destination) === proxy_util_1.ProxyStrategy.INTERNET_PROXY) { destination = (0, proxy_util_1.addProxyConfigurationInternet)(destination); } return __assign({ url: destination.url }, getAgentConfig(destination)); } exports.urlAndAgent = urlAndAgent; //# sourceMappingURL=http-agent.js.map