chore: Switch to axios in App download
MODIFY
lib/basedriver/helpers.js
lib/basedriver/helpers.js
@@ -2,13 +2,10 @@ import _ from 'lodash';
import path from 'path';
import url from 'url';
import logger from './logger';
-import _fs from 'fs';
-import B from 'bluebird';
-import { tempDir, fs, util, zip, timing } from 'appium-support';
-import request from 'request';
-import asyncRequest from 'request-promise';
+import { tempDir, fs, util, zip, net } from 'appium-support';
import LRU from 'lru-cache';
import AsyncLock from 'async-lock';
+import axios from 'axios';
const ZIP_EXTS = ['.zip', '.ipa'];
@@ -34,6 +31,7 @@ const APPLICATIONS_CACHE = new LRU({
const APPLICATIONS_CACHE_GUARD = new AsyncLock();
const SANITIZE_REPLACEMENT = '-';
const DEFAULT_BASENAME = 'appium-app';
+const APP_DOWNLOAD_TIMEOUT_MS = 120 * 1000;
process.on('exit', () => {
if (!APPLICATIONS_CACHE.length) {
@@ -57,15 +55,13 @@ process.on('exit', () => {
async function retrieveHeaders (link) {
try {
- const response = await asyncRequest({
+ return (await axios({
url: link,
method: 'HEAD',
- resolveWithFullResponse: true,
timeout: 5000,
- });
- return response.headers;
+ })).headers;
} catch (e) {
- logger.debug(`Cannot send HEAD request to '${link}'. Original error: ${e.message}`);
+ logger.info(`Cannot send HEAD request to '${link}'. Original error: ${e.message}`);
}
return {};
}
@@ -292,31 +288,12 @@ async function configureApp (app, supportedAppExtensions) {
async function downloadApp (app, targetPath) {
const {href} = url.parse(app);
- const timer = new timing.Timer().start();
try {
- // don't use request-promise here, we need streams
- await new B((resolve, reject) => {
- request(href)
- .on('error', reject) // handle real errors, like connection errors
- .on('response', (res) => {
- // handle responses that fail, like 404s
- if (res.statusCode >= 400) {
- return reject(new Error(`${res.statusCode} - ${res.statusMessage}`));
- }
- })
- .pipe(_fs.createWriteStream(targetPath))
- .on('close', resolve);
+ await net.downloadFile(href, targetPath, {
+ timeout: APP_DOWNLOAD_TIMEOUT_MS,
});
} catch (err) {
- throw new Error(`Problem downloading app from url ${href}: ${err.message}`);
- }
- const secondsElapsed = timer.getDuration().asSeconds;
- const {size} = await fs.stat(targetPath);
- logger.debug(`'${href}' (${util.toReadableSizeString(size)}) ` +
- `has been downloaded to '${targetPath}' in ${secondsElapsed.toFixed(3)}s`);
- if (secondsElapsed >= 2) {
- const bytesPerSec = Math.floor(size / secondsElapsed);
- logger.debug(`Approximate download speed: ${util.toReadableSizeString(bytesPerSec)}/s`);
+ throw new Error(`Unable to download the app: ${err.message}`);
}
return targetPath;
}

MODIFY
package.json
package.json
],
"dependencies": {
"@babel/runtime": "^7.0.0",
- "appium-support": "^2.43.0",
+ "appium-support": "^2.46.0",
"async-lock": "^1.0.0",
"asyncbox": "^2.3.1",
+ "axios": "^0.19.2",
"bluebird": "^3.5.3",
"body-parser": "^1.18.2",
"colors": "^1.1.2",
"lru-cache": "^5.0.0",
"method-override": "^3.0.0",
"morgan": "^1.9.0",
- "request": "^2.83.0",
- "request-promise": "^4.2.2",
+ "request": "^2.88.2",
+ "request-promise": "^4.2.5",
"serve-favicon": "^2.4.5",
"source-map-support": "^0.5.5",
"validate.js": "^0.13.0",

MODIFY
test/basedriver/helpers-e2e-specs.js
test/basedriver/helpers-e2e-specs.js
@@ -140,7 +140,7 @@ describe('app download and configuration', function () {
});
it('should handle zip file that cannot be downloaded', async function () {
await configureApp(`${serverUrl}/missing/FakeIOSApp.app.zip`, '.app')
- .should.eventually.be.rejectedWith(/Problem downloading app from url/);
+ .should.eventually.be.rejected;
});
it('should handle invalid protocol', async function () {
await configureApp('file://C:/missing/FakeIOSApp.app.zip', '.app')

chore: Switch to axios in App download (#407)