url-file-manager.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. const isUrlRe = /^(?:https?:)?\/\//i;
  2. import url from 'url';
  3. let request;
  4. import AbstractFileManager from '../less/environment/abstract-file-manager.js';
  5. import logger from '../less/logger';
  6. class UrlFileManager extends AbstractFileManager {
  7. supports(filename, currentDirectory, options, environment) {
  8. return isUrlRe.test( filename ) || isUrlRe.test(currentDirectory);
  9. }
  10. loadFile(filename, currentDirectory, options, environment) {
  11. return new Promise((fulfill, reject) => {
  12. if (request === undefined) {
  13. try { request = require('request'); }
  14. catch (e) { request = null; }
  15. }
  16. if (!request) {
  17. reject({ type: 'File', message: 'optional dependency \'request\' required to import over http(s)\n' });
  18. return;
  19. }
  20. let urlStr = isUrlRe.test( filename ) ? filename : url.resolve(currentDirectory, filename);
  21. const urlObj = url.parse(urlStr);
  22. if (!urlObj.protocol) {
  23. urlObj.protocol = 'http';
  24. urlStr = urlObj.format();
  25. }
  26. request.get({uri: urlStr, strictSSL: !options.insecure }, (error, res, body) => {
  27. if (error) {
  28. reject({ type: 'File', message: `resource '${urlStr}' gave this Error:\n ${error}\n` });
  29. return;
  30. }
  31. if (res && res.statusCode === 404) {
  32. reject({ type: 'File', message: `resource '${urlStr}' was not found\n` });
  33. return;
  34. }
  35. if (!body) {
  36. logger.warn(`Warning: Empty body (HTTP ${res.statusCode}) returned by "${urlStr}"`);
  37. }
  38. fulfill({ contents: body, filename: urlStr });
  39. });
  40. });
  41. }
  42. }
  43. export default UrlFileManager;