You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
2.4 KiB
JavaScript

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