webdriver-manager-replacement
Version:
webdriver-manager-replacement
250 lines • 8.92 kB
JavaScript
;
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