3 * Copyright(c) 2014 Jonathan Ong
4 * Copyright(c) 2014-2017 Douglas Christopher Wilson
11 * Module dependencies.
15 var url = require('url')
24 module.exports = parseurl
25 module.exports.original = originalurl
28 * Parse the `req` url with memoization.
30 * @param {ServerRequest} req
35 function parseurl (req) {
38 if (url === undefined) {
43 var parsed = req._parsedUrl
45 if (fresh(url, parsed)) {
46 // Return cached URL parse
51 parsed = fastparse(url)
54 return (req._parsedUrl = parsed)
58 * Parse the `req` original url with fallback and memoization.
60 * @param {ServerRequest} req
65 function originalurl (req) {
66 var url = req.originalUrl
68 if (typeof url !== 'string') {
73 var parsed = req._parsedOriginalUrl
75 if (fresh(url, parsed)) {
76 // Return cached URL parse
81 parsed = fastparse(url)
84 return (req._parsedOriginalUrl = parsed)
88 * Parse the `str` url with fast-path short-cut.
95 function fastparse (str) {
96 if (typeof str !== 'string' || str.charCodeAt(0) !== 0x2f /* / */) {
104 // This takes the regexp from https://github.com/joyent/node/pull/7878
105 // Which is /^(\/[^?#\s]*)(\?[^#\s]*)?$/
106 // And unrolls it into a for loop
107 for (var i = 1; i < str.length; i++) {
108 switch (str.charCodeAt(i)) {
110 if (search === null) {
111 pathname = str.substring(0, i)
112 query = str.substring(i + 1)
113 search = str.substring(i)
128 var url = Url !== undefined
134 url.pathname = pathname
136 if (search !== null) {
145 * Determine if parsed is still fresh for url.
147 * @param {string} url
148 * @param {object} parsedUrl
153 function fresh (url, parsedUrl) {
154 return typeof parsedUrl === 'object' &&
155 parsedUrl !== null &&
156 (Url === undefined || parsedUrl instanceof Url) &&
157 parsedUrl._raw === url