/*! * parseurl * Copyright(c) 2014 Jonathan Ong * Copyright(c) 2014 Douglas Christopher Wilson * MIT Licensed */ /** * Module dependencies. */ var url = require('url') var parse = url.parse var Url = url.Url /** * Pattern for a simple path case. * See: https://github.com/joyent/node/pull/7878 */ var simplePathRegExp = /^(\/\/?(?!\/)[^\?#\s]*)(\?[^#\s]*)?$/ /** * Exports. */ module.exports = parseurl module.exports.original = originalurl /** * Parse the `req` url with memoization. * * @param {ServerRequest} req * @return {Object} * @api 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} * @api 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} * @api private */ function fastparse(str) { // Try fast path regexp // See: https://github.com/joyent/node/pull/7878 var simplePath = typeof str === 'string' && simplePathRegExp.exec(str) // Construct simple URL if (simplePath) { var pathname = simplePath[1] var search = simplePath[2] || null var url = Url !== undefined ? new Url() : {} url.path = str url.href = str url.pathname = pathname url.search = search url.query = search && search.substr(1) return url } return parse(str) } /** * Determine if parsed is still fresh for url. * * @param {string} url * @param {object} parsedUrl * @return {boolean} * @api private */ function fresh(url, parsedUrl) { return typeof parsedUrl === 'object' && parsedUrl !== null && (Url === undefined || parsedUrl instanceof Url) && parsedUrl._raw === url }