downloader.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const fs = require("fs");
  4. const path = require("path");
  5. const request = require("request");
  6. const url = require("url");
  7. const cli_1 = require("../cli");
  8. const http_utils_1 = require("../http_utils");
  9. let logger = new cli_1.Logger('downloader');
  10. /**
  11. * The file downloader.
  12. */
  13. class Downloader {
  14. /**
  15. * Http get the file. Check the content length of the file before writing the file.
  16. * If the content length does not match, remove it and download the file.
  17. *
  18. * @param binary The binary of interest.
  19. * @param fileName The file name.
  20. * @param outputDir The directory where files are downloaded and stored.
  21. * @param contentLength The content length of the existing file.
  22. * @param opt_proxy The proxy for downloading files.
  23. * @param opt_callback Callback method to be executed after the file is downloaded.
  24. * @returns Promise<boolean> Resolves true = downloaded. Resolves false = not downloaded.
  25. * Rejected with an error.
  26. */
  27. static getFile(binary, fileUrl, fileName, outputDir, contentLength, callback) {
  28. let filePath = path.resolve(outputDir, fileName);
  29. let file;
  30. let options = http_utils_1.HttpUtils.initOptions(fileUrl);
  31. let req = null;
  32. let resContentLength;
  33. return new Promise((resolve, reject) => {
  34. req = request(options);
  35. req.on('response', response => {
  36. if (response.statusCode === 200) {
  37. resContentLength = +response.headers['content-length'];
  38. if (contentLength === resContentLength) {
  39. // if the size is the same, do not download and stop here
  40. response.destroy();
  41. resolve(false);
  42. }
  43. else {
  44. let curl = outputDir + '/' + fileName + ' ' + options.url;
  45. if (http_utils_1.HttpUtils.requestOpts.proxy) {
  46. let pathUrl = url.parse(options.url.toString()).path;
  47. let host = url.parse(options.url.toString()).host;
  48. let newFileUrl = url.resolve(http_utils_1.HttpUtils.requestOpts.proxy, pathUrl);
  49. curl = outputDir + '/' + fileName + ' \'' + newFileUrl +
  50. '\' -H \'host:' + host + '\'';
  51. }
  52. if (http_utils_1.HttpUtils.requestOpts.ignoreSSL) {
  53. curl = 'k ' + curl;
  54. }
  55. logger.info('curl -o' + curl);
  56. // only pipe if the headers are different length
  57. file = fs.createWriteStream(filePath);
  58. req.pipe(file);
  59. file.on('close', () => {
  60. fs.stat(filePath, (error, stats) => {
  61. if (error) {
  62. error.msg = 'Error: Got error ' + error + ' from ' + fileUrl;
  63. return reject(error);
  64. }
  65. if (stats.size != resContentLength) {
  66. error.msg = 'Error: corrupt download for ' + fileName +
  67. '. Please re-run webdriver-manager update';
  68. fs.unlinkSync(filePath);
  69. reject(error);
  70. }
  71. if (callback) {
  72. callback(binary, outputDir, fileName);
  73. }
  74. resolve(true);
  75. });
  76. });
  77. }
  78. }
  79. else {
  80. let error = new Error();
  81. error.msg =
  82. 'Expected response code 200, received: ' + response.statusCode;
  83. reject(error);
  84. }
  85. });
  86. req.on('error', error => {
  87. if (error.code === 'ETIMEDOUT') {
  88. error.msg = 'Connection timeout downloading: ' + fileUrl +
  89. '. Default timeout is 4 minutes.';
  90. }
  91. else if (error.connect) {
  92. error.msg = 'Could not connect to the server to download: ' + fileUrl;
  93. }
  94. reject(error);
  95. });
  96. })
  97. .catch(error => {
  98. logger.error(error.msg || error.message);
  99. });
  100. }
  101. }
  102. exports.Downloader = Downloader;
  103. //# sourceMappingURL=downloader.js.map