UNPKG

webdriver-manager-replacement

Version:
250 lines 8.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const loglevel = require("loglevel"); const path = require("path"); const request = require("request"); const url = require("url"); const log = loglevel.getLogger('webdriver-manager'); /** * Initialize the request options. * @param requestUrl The request url. * @param httpOptions The http options for the request. */ function initOptions(requestUrl, httpOptions) { let options = { url: requestUrl, // default Linux can be anywhere from 20-120 seconds // increasing this arbitrarily to 4 minutes timeout: 240000 }; options = optionsSSL(options, httpOptions.ignoreSSL); options = optionsProxy(options, requestUrl, httpOptions.proxy); if (httpOptions.headers) { for (const key of Object.keys(httpOptions.headers)) { options = addHeader(options, key, httpOptions.headers[key]); } } return options; } exports.initOptions = initOptions; /** * Set ignore SSL option. * @param options The HTTP options * @param optIgnoreSSL The ignore SSL option. */ function optionsSSL(options, optIgnoreSSL) { if (optIgnoreSSL) { options.strictSSL = !optIgnoreSSL; options.rejectUnauthorized = !optIgnoreSSL; } return options; } exports.optionsSSL = optionsSSL; function optionsProxy(options, requestUrl, optProxy) { if (optProxy) { options.proxy = resolveProxy(requestUrl, optProxy); if (url.parse(options.proxy).protocol === 'http:') { options.url = requestUrl.replace('https:', 'http:'); } } return options; } exports.optionsProxy = optionsProxy; /** * Resolves proxy based on values set. * @param requestUrl The url to download the file. * @param optProxy The proxy to connect to to download files. * @return Either undefined or the proxy. */ function resolveProxy(requestUrl, optProxy) { if (optProxy) { return optProxy; } else { const protocol = url.parse(requestUrl).protocol; const hostname = url.parse(requestUrl).hostname; // If the NO_PROXY environment variable exists and matches the host name, // to ignore the resolve proxy. // Check to see if it exists and equal to empty string is to help with // testing const noProxy = process.env.NO_PROXY || process.env.no_proxy; if (noProxy) { // array of hostnames/domain names listed in the NO_PROXY environment // variable const noProxyTokens = noProxy.split(','); // check if the fileUrl hostname part does not end with one of the // NO_PROXY environment variable's hostnames/domain names for (const noProxyToken of noProxyTokens) { if (hostname.indexOf(noProxyToken) !== -1) { return undefined; } } } // If the HTTPS_PROXY and HTTP_PROXY environment variable is set, // use that as the proxy const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy; const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy; if (protocol === 'https:') { return httpsProxy || httpProxy; } else if (protocol === 'http:') { return httpProxy; } } return undefined; } exports.resolveProxy = resolveProxy; /** * Builds a curl command for logging purposes. * @param requestOptions The request options. * @param fileName The file name path. * @returns The curl command. */ function curlCommand(requestOptions, fileName) { let curl = `${requestOptions.url}`; if (requestOptions.proxy) { const pathUrl = url.parse(requestOptions.url.toString()).path; const host = url.parse(requestOptions.url.toString()).host; if (requestOptions.proxy) { const modifiedUrl = url.resolve(requestOptions.proxy, pathUrl); curl = `"${modifiedUrl}" -H "host: ${host}"`; } } if (requestOptions.headers) { for (const headerName of Object.keys(requestOptions.headers)) { curl += ` -H "${headerName}: ${requestOptions.headers[headerName]}"`; } } if (requestOptions.ignoreSSL) { curl = `-k ${curl}`; } if (fileName) { curl = `-o ${fileName} ${curl}`; } return `curl ${curl}`; } exports.curlCommand = curlCommand; /** * Add a header to the request. * @param options The options to add a header. * @param name The key name of the header. * @param value The value of the header. * @returns The modified options object. */ function addHeader(options, name, value) { if (!options.headers) { options.headers = {}; } options.headers[name] = value; return options; } exports.addHeader = addHeader; /** * The request to download the binary. * @param binaryUrl The download url for the binary. * @param httpOptions The http options for the request. * @param isLogInfo Log info or debug */ function requestBinary(binaryUrl, httpOptions, isLogInfo = true) { const options = initOptions(binaryUrl, httpOptions); options.followRedirect = false; options.followAllRedirects = false; if (isLogInfo) { log.info(curlCommand(options, httpOptions.fileName)); } else { log.debug(curlCommand(options, httpOptions.fileName)); } return new Promise((resolve, reject) => { const req = request(options); req.on('response', response => { let contentLength; if (response.statusCode === 200) { // Check to see if the size is the same. // If the file size is the same, do not download and stop here. contentLength = +response.headers['content-length']; if (contentLength === httpOptions.fileSize) { response.destroy(); resolve(false); } else { // Only pipe if the headers are different length. const dir = path.dirname(httpOptions.fileName); try { fs.mkdirSync(dir); } catch (err) { } const file = fs.createWriteStream(httpOptions.fileName); req.pipe(file); file.on('close', () => { fs.stat(httpOptions.fileName, (error, stats) => { if (error) { reject(error); } if (stats.size !== contentLength) { fs.unlinkSync(httpOptions.fileName); reject(error); } resolve(true); }); }); file.on('error', (error) => { reject(error); }); } } else if (response.statusCode === 302) { const location = response.headers['location']; if (!httpOptions.headers) { httpOptions.headers = {}; } for (const header of Object.keys(response.headers)) { httpOptions.headers[header] = response.headers[header]; } resolve(requestBinary(location, httpOptions, false)); } else { reject(new Error('response status code is not 200')); } }); req.on('error', error => { reject(error); }); }); } exports.requestBinary = requestBinary; /** * Request the body from the url and log the curl. * @param requestUrl The request url. * @param httpOptions The http options for the request. * @returns A promise string of the response body. */ function requestBody(requestUrl, httpOptions) { const options = initOptions(requestUrl, httpOptions); log.info(curlCommand(options, httpOptions.fileName)); options.followRedirect = true; return new Promise((resolve, reject) => { const req = request(options); req.on('response', response => { if (response.statusCode === 200) { let output = ''; response.on('data', (data) => { output += data; }); response.on('end', () => { resolve(output); }); } else { reject(new Error('response status code is not 200')); } }); req.on('error', error => { reject(error); }); }); } exports.requestBody = requestBody; //# sourceMappingURL=http_utils.js.map