/*! * 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 ); }