150 lines
3.4 KiB
JavaScript
150 lines
3.4 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = isURL;
|
|
|
|
var _assertString = require('./util/assertString');
|
|
|
|
var _assertString2 = _interopRequireDefault(_assertString);
|
|
|
|
var _isFQDN = require('./isFQDN');
|
|
|
|
var _isFQDN2 = _interopRequireDefault(_isFQDN);
|
|
|
|
var _isIP = require('./isIP');
|
|
|
|
var _isIP2 = _interopRequireDefault(_isIP);
|
|
|
|
var _merge = require('./util/merge');
|
|
|
|
var _merge2 = _interopRequireDefault(_merge);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var default_url_options = {
|
|
protocols: ['http', 'https', 'ftp'],
|
|
require_tld: true,
|
|
require_protocol: false,
|
|
require_host: true,
|
|
require_valid_protocol: true,
|
|
allow_underscores: false,
|
|
allow_trailing_dot: false,
|
|
allow_protocol_relative_urls: false
|
|
};
|
|
|
|
var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;
|
|
|
|
function isRegExp(obj) {
|
|
return Object.prototype.toString.call(obj) === '[object RegExp]';
|
|
}
|
|
|
|
function checkHost(host, matches) {
|
|
for (var i = 0; i < matches.length; i++) {
|
|
var match = matches[i];
|
|
if (host === match || isRegExp(match) && match.test(host)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function isURL(url, options) {
|
|
(0, _assertString2.default)(url);
|
|
if (!url || url.length >= 2083 || /[\s<>]/.test(url)) {
|
|
return false;
|
|
}
|
|
if (url.indexOf('mailto:') === 0) {
|
|
return false;
|
|
}
|
|
options = (0, _merge2.default)(options, default_url_options);
|
|
var protocol = void 0,
|
|
auth = void 0,
|
|
host = void 0,
|
|
hostname = void 0,
|
|
port = void 0,
|
|
port_str = void 0,
|
|
split = void 0,
|
|
ipv6 = void 0;
|
|
|
|
split = url.split('#');
|
|
url = split.shift();
|
|
|
|
split = url.split('?');
|
|
url = split.shift();
|
|
|
|
split = url.split('://');
|
|
if (split.length > 1) {
|
|
protocol = split.shift().toLowerCase();
|
|
if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) {
|
|
return false;
|
|
}
|
|
} else if (options.require_protocol) {
|
|
return false;
|
|
} else if (url.substr(0, 2) === '//') {
|
|
if (!options.allow_protocol_relative_urls) {
|
|
return false;
|
|
}
|
|
split[0] = url.substr(2);
|
|
}
|
|
url = split.join('://');
|
|
|
|
if (url === '') {
|
|
return false;
|
|
}
|
|
|
|
split = url.split('/');
|
|
url = split.shift();
|
|
|
|
if (url === '' && !options.require_host) {
|
|
return true;
|
|
}
|
|
|
|
split = url.split('@');
|
|
if (split.length > 1) {
|
|
auth = split.shift();
|
|
if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) {
|
|
return false;
|
|
}
|
|
}
|
|
hostname = split.join('@');
|
|
|
|
port_str = null;
|
|
ipv6 = null;
|
|
var ipv6_match = hostname.match(wrapped_ipv6);
|
|
if (ipv6_match) {
|
|
host = '';
|
|
ipv6 = ipv6_match[1];
|
|
port_str = ipv6_match[2] || null;
|
|
} else {
|
|
split = hostname.split(':');
|
|
host = split.shift();
|
|
if (split.length) {
|
|
port_str = split.join(':');
|
|
}
|
|
}
|
|
|
|
if (port_str !== null) {
|
|
port = parseInt(port_str, 10);
|
|
if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!(0, _isIP2.default)(host) && !(0, _isFQDN2.default)(host, options) && (!ipv6 || !(0, _isIP2.default)(ipv6, 6))) {
|
|
return false;
|
|
}
|
|
|
|
host = host || ipv6;
|
|
|
|
if (options.host_whitelist && !checkHost(host, options.host_whitelist)) {
|
|
return false;
|
|
}
|
|
if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
module.exports = exports['default']; |