isURL.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = isURL;
  6. var _assertString = _interopRequireDefault(require("./util/assertString"));
  7. var _isFQDN = _interopRequireDefault(require("./isFQDN"));
  8. var _isIP = _interopRequireDefault(require("./isIP"));
  9. var _merge = _interopRequireDefault(require("./util/merge"));
  10. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  11. var default_url_options = {
  12. protocols: ['http', 'https', 'ftp'],
  13. require_tld: true,
  14. require_protocol: false,
  15. require_host: true,
  16. require_valid_protocol: true,
  17. allow_underscores: false,
  18. allow_trailing_dot: false,
  19. allow_protocol_relative_urls: false
  20. };
  21. var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;
  22. function isRegExp(obj) {
  23. return Object.prototype.toString.call(obj) === '[object RegExp]';
  24. }
  25. function checkHost(host, matches) {
  26. for (var i = 0; i < matches.length; i++) {
  27. var match = matches[i];
  28. if (host === match || isRegExp(match) && match.test(host)) {
  29. return true;
  30. }
  31. }
  32. return false;
  33. }
  34. function isURL(url, options) {
  35. (0, _assertString.default)(url);
  36. if (!url || url.length >= 2083 || /[\s<>]/.test(url)) {
  37. return false;
  38. }
  39. if (url.indexOf('mailto:') === 0) {
  40. return false;
  41. }
  42. options = (0, _merge.default)(options, default_url_options);
  43. var protocol, auth, host, hostname, port, port_str, split, ipv6;
  44. split = url.split('#');
  45. url = split.shift();
  46. split = url.split('?');
  47. url = split.shift();
  48. split = url.split('://');
  49. if (split.length > 1) {
  50. protocol = split.shift().toLowerCase();
  51. if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) {
  52. return false;
  53. }
  54. } else if (options.require_protocol) {
  55. return false;
  56. } else if (url.substr(0, 2) === '//') {
  57. if (!options.allow_protocol_relative_urls) {
  58. return false;
  59. }
  60. split[0] = url.substr(2);
  61. }
  62. url = split.join('://');
  63. if (url === '') {
  64. return false;
  65. }
  66. split = url.split('/');
  67. url = split.shift();
  68. if (url === '' && !options.require_host) {
  69. return true;
  70. }
  71. split = url.split('@');
  72. if (split.length > 1) {
  73. if (options.disallow_auth) {
  74. return false;
  75. }
  76. auth = split.shift();
  77. if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) {
  78. return false;
  79. }
  80. }
  81. hostname = split.join('@');
  82. port_str = null;
  83. ipv6 = null;
  84. var ipv6_match = hostname.match(wrapped_ipv6);
  85. if (ipv6_match) {
  86. host = '';
  87. ipv6 = ipv6_match[1];
  88. port_str = ipv6_match[2] || null;
  89. } else {
  90. split = hostname.split(':');
  91. host = split.shift();
  92. if (split.length) {
  93. port_str = split.join(':');
  94. }
  95. }
  96. if (port_str !== null) {
  97. port = parseInt(port_str, 10);
  98. if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) {
  99. return false;
  100. }
  101. }
  102. if (!(0, _isIP.default)(host) && !(0, _isFQDN.default)(host, options) && (!ipv6 || !(0, _isIP.default)(ipv6, 6))) {
  103. return false;
  104. }
  105. host = host || ipv6;
  106. if (options.host_whitelist && !checkHost(host, options.host_whitelist)) {
  107. return false;
  108. }
  109. if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
  110. return false;
  111. }
  112. return true;
  113. }
  114. module.exports = exports.default;
  115. module.exports.default = exports.default;