You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
2.7 KiB
158 lines
2.7 KiB
/*! |
|
* parseurl |
|
* Copyright(c) 2014 Jonathan Ong |
|
* Copyright(c) 2014-2017 Douglas Christopher Wilson |
|
* MIT Licensed |
|
*/ |
|
|
|
'use strict' |
|
|
|
/** |
|
* Module dependencies. |
|
* @private |
|
*/ |
|
|
|
var url = require('url') |
|
var parse = url.parse |
|
var Url = url.Url |
|
|
|
/** |
|
* Module exports. |
|
* @public |
|
*/ |
|
|
|
module.exports = parseurl |
|
module.exports.original = originalurl |
|
|
|
/** |
|
* Parse the `req` url with memoization. |
|
* |
|
* @param {ServerRequest} req |
|
* @return {Object} |
|
* @public |
|
*/ |
|
|
|
function parseurl (req) { |
|
var url = req.url |
|
|
|
if (url === undefined) { |
|
// URL is undefined |
|
return undefined |
|
} |
|
|
|
var parsed = req._parsedUrl |
|
|
|
if (fresh(url, parsed)) { |
|
// Return cached URL parse |
|
return parsed |
|
} |
|
|
|
// Parse the URL |
|
parsed = fastparse(url) |
|
parsed._raw = url |
|
|
|
return (req._parsedUrl = parsed) |
|
}; |
|
|
|
/** |
|
* Parse the `req` original url with fallback and memoization. |
|
* |
|
* @param {ServerRequest} req |
|
* @return {Object} |
|
* @public |
|
*/ |
|
|
|
function originalurl (req) { |
|
var url = req.originalUrl |
|
|
|
if (typeof url !== 'string') { |
|
// Fallback |
|
return parseurl(req) |
|
} |
|
|
|
var parsed = req._parsedOriginalUrl |
|
|
|
if (fresh(url, parsed)) { |
|
// Return cached URL parse |
|
return parsed |
|
} |
|
|
|
// Parse the URL |
|
parsed = fastparse(url) |
|
parsed._raw = url |
|
|
|
return (req._parsedOriginalUrl = parsed) |
|
}; |
|
|
|
/** |
|
* Parse the `str` url with fast-path short-cut. |
|
* |
|
* @param {string} str |
|
* @return {Object} |
|
* @private |
|
*/ |
|
|
|
function fastparse (str) { |
|
if (typeof str !== 'string' || str.charCodeAt(0) !== 0x2f /* / */) { |
|
return parse(str) |
|
} |
|
|
|
var pathname = str |
|
var query = null |
|
var search = null |
|
|
|
// This takes the regexp from https://github.com/joyent/node/pull/7878 |
|
// Which is /^(\/[^?#\s]*)(\?[^#\s]*)?$/ |
|
// And unrolls it into a for loop |
|
for (var i = 1; i < str.length; i++) { |
|
switch (str.charCodeAt(i)) { |
|
case 0x3f: /* ? */ |
|
if (search === null) { |
|
pathname = str.substring(0, i) |
|
query = str.substring(i + 1) |
|
search = str.substring(i) |
|
} |
|
break |
|
case 0x09: /* \t */ |
|
case 0x0a: /* \n */ |
|
case 0x0c: /* \f */ |
|
case 0x0d: /* \r */ |
|
case 0x20: /* */ |
|
case 0x23: /* # */ |
|
case 0xa0: |
|
case 0xfeff: |
|
return parse(str) |
|
} |
|
} |
|
|
|
var url = Url !== undefined |
|
? new Url() |
|
: {} |
|
|
|
url.path = str |
|
url.href = str |
|
url.pathname = pathname |
|
|
|
if (search !== null) { |
|
url.query = query |
|
url.search = search |
|
} |
|
|
|
return url |
|
} |
|
|
|
/** |
|
* Determine if parsed is still fresh for url. |
|
* |
|
* @param {string} url |
|
* @param {object} parsedUrl |
|
* @return {boolean} |
|
* @private |
|
*/ |
|
|
|
function fresh (url, parsedUrl) { |
|
return typeof parsedUrl === 'object' && |
|
parsedUrl !== null && |
|
(Url === undefined || parsedUrl instanceof Url) && |
|
parsedUrl._raw === url |
|
}
|
|
|