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