-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
index.js
158 lines (129 loc) · 2.77 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*!
* 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 // eslint-disable-line
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
}