159 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			159 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | /*! | ||
|  |  * 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 | ||
|  | } |