| /*! |
| * parseurl |
| * Copyright(c) 2014 Jonathan Ong |
| * Copyright(c) 2014 Douglas Christopher Wilson |
| * MIT Licensed |
| */ |
| |
| 'use strict' |
| |
| /** |
| * 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 |
| } |