108 lines
2.1 KiB
JavaScript
108 lines
2.1 KiB
JavaScript
|
|
||
|
var URL = require('url');
|
||
|
var isValid = require('./is-valid.js');
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Utility to cleanup the base host value. Also removes url fragments.
|
||
|
*
|
||
|
* Works for:
|
||
|
* - hostname
|
||
|
* - //hostname
|
||
|
* - scheme://hostname
|
||
|
* - scheme+scheme://hostname
|
||
|
*
|
||
|
* @param {string} value
|
||
|
* @return {String}
|
||
|
*/
|
||
|
|
||
|
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||
|
var hasPrefixRE = /^(([a-z][a-z0-9+.-]*)?:)?\/\//;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @see https://github.com/oncletom/tld.js/issues/95
|
||
|
*
|
||
|
* @param {string} value
|
||
|
*/
|
||
|
function trimTrailingDots(value) {
|
||
|
if (value[value.length - 1] === '.') {
|
||
|
return value.substr(0, value.length - 1);
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Fast check to avoid calling `trim` when not needed.
|
||
|
*
|
||
|
* @param {string} value
|
||
|
*/
|
||
|
function checkTrimmingNeeded(value) {
|
||
|
return (
|
||
|
value.length > 0 && (
|
||
|
value.charCodeAt(0) <= 32 ||
|
||
|
value.charCodeAt(value.length - 1) <= 32
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Fast check to avoid calling `toLowerCase` when not needed.
|
||
|
*
|
||
|
* @param {string} value
|
||
|
*/
|
||
|
function checkLowerCaseNeeded(value) {
|
||
|
for (var i = 0; i < value.length; i += 1) {
|
||
|
var code = value.charCodeAt(i);
|
||
|
if (code >= 65 && code <= 90) { // [A-Z]
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
module.exports = function extractHostname(value) {
|
||
|
// First check if `value` is already a valid hostname.
|
||
|
if (isValid(value)) {
|
||
|
return trimTrailingDots(value);
|
||
|
}
|
||
|
|
||
|
var url = value;
|
||
|
|
||
|
if (typeof url !== 'string') {
|
||
|
url = '' + url;
|
||
|
}
|
||
|
|
||
|
var needsTrimming = checkTrimmingNeeded(url);
|
||
|
if (needsTrimming) {
|
||
|
url = url.trim();
|
||
|
}
|
||
|
|
||
|
var needsLowerCase = checkLowerCaseNeeded(url);
|
||
|
if (needsLowerCase) {
|
||
|
url = url.toLowerCase();
|
||
|
}
|
||
|
|
||
|
// Try again after `url` has been transformed to lowercase and trimmed.
|
||
|
if ((needsLowerCase || needsTrimming) && isValid(url)) {
|
||
|
return trimTrailingDots(url);
|
||
|
}
|
||
|
|
||
|
// Proceed with heavier url parsing to extract the hostname.
|
||
|
if (!hasPrefixRE.test(url)) {
|
||
|
url = '//' + url;
|
||
|
}
|
||
|
|
||
|
var parts = URL.parse(url, null, true);
|
||
|
|
||
|
if (parts.hostname) {
|
||
|
return trimTrailingDots(parts.hostname);
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
};
|