@swarmmachina/swm-core 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmmachina/swm-core",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Zero-dependency high-performance HTTP/WebSocket server built on uWebSockets.js",
5
5
  "keywords": [
6
6
  "http",
@@ -6,6 +6,12 @@ export default class HttpContext {
6
6
  #ip = ''
7
7
  #method = ''
8
8
  #url = ''
9
+ #headersCached = false
10
+ #headers = {}
11
+ #fullQuery = null
12
+ #fullQueryParsed = false
13
+ #query = {}
14
+ #params = {}
9
15
  #statusOverride = null
10
16
  #contentLength = undefined
11
17
  #bodyParser = new BodyParser()
@@ -112,6 +118,12 @@ export default class HttpContext {
112
118
  this.#ip = ''
113
119
  this.#url = ''
114
120
  this.#method = ''
121
+ this.#headersCached = false
122
+ this.#headers = {}
123
+ this.#fullQuery = null
124
+ this.#fullQueryParsed = false
125
+ this.#query = {}
126
+ this.#params = {}
115
127
 
116
128
  this.#bodyParser.reset(this, maxSize)
117
129
  this.#resStreamer.reset(this, res)
@@ -138,6 +150,12 @@ export default class HttpContext {
138
150
  this.#ip = ''
139
151
  this.#url = ''
140
152
  this.#method = ''
153
+ this.#headersCached = false
154
+ this.#headers = {}
155
+ this.#fullQuery = null
156
+ this.#fullQueryParsed = false
157
+ this.#query = {}
158
+ this.#params = {}
141
159
 
142
160
  this.#bodyParser.clear()
143
161
  this.#resStreamer.clear()
@@ -166,6 +184,68 @@ export default class HttpContext {
166
184
  }
167
185
  }
168
186
 
187
+ cacheHeaders() {
188
+ if (this.#headersCached || !this.req) {
189
+ return
190
+ }
191
+
192
+ this.req.forEach((key, value) => {
193
+ this.#headers[key] = value
194
+ })
195
+
196
+ this.#headersCached = true
197
+ }
198
+
199
+ cacheQuery() {
200
+ if (this.#fullQuery !== null || !this.req) {
201
+ return
202
+ }
203
+
204
+ const fullQuery = this.req.getQuery()
205
+
206
+ this.#fullQuery = typeof fullQuery === 'string' ? fullQuery : ''
207
+ this.#fullQueryParsed = false
208
+ }
209
+
210
+ #parseFullQuery() {
211
+ if (this.#fullQueryParsed) {
212
+ return
213
+ }
214
+
215
+ const fullQuery = this.#fullQuery
216
+
217
+ if (!fullQuery) {
218
+ this.#fullQueryParsed = true
219
+ return
220
+ }
221
+
222
+ let start = 0
223
+
224
+ while (start <= fullQuery.length) {
225
+ let end = fullQuery.indexOf('&', start)
226
+
227
+ if (end === -1) {
228
+ end = fullQuery.length
229
+ }
230
+
231
+ const eq = fullQuery.indexOf('=', start)
232
+ const hasEq = eq !== -1 && eq < end
233
+ const key = hasEq ? fullQuery.slice(start, eq) : fullQuery.slice(start, end)
234
+
235
+ if (!(key in this.#query)) {
236
+ this.#query[key] = hasEq ? fullQuery.slice(eq + 1, end) : ''
237
+ }
238
+
239
+ if (end === fullQuery.length) {
240
+ break
241
+ }
242
+
243
+ start = end + 1
244
+ }
245
+
246
+ this.#fullQueryParsed = true
247
+ }
248
+
169
249
  ip() {
170
250
  if (!this.res) {
171
251
  return ''
@@ -213,7 +293,25 @@ export default class HttpContext {
213
293
  * @returns {string|undefined}
214
294
  */
215
295
  query(name) {
216
- return this.req.getQuery(name)
296
+ if (name in this.#query) {
297
+ return this.#query[name]
298
+ }
299
+
300
+ if (this.#fullQuery !== null) {
301
+ this.#parseFullQuery()
302
+
303
+ if (name in this.#query) {
304
+ return this.#query[name]
305
+ }
306
+
307
+ this.#query[name] = undefined
308
+ return undefined
309
+ }
310
+
311
+ const value = this.req.getQuery(name)
312
+
313
+ this.#query[name] = value
314
+ return value
217
315
  }
218
316
 
219
317
  /**
@@ -221,7 +319,14 @@ export default class HttpContext {
221
319
  * @returns {string|undefined}
222
320
  */
223
321
  param(i) {
224
- return this.req.getParameter(i)
322
+ if (i in this.#params) {
323
+ return this.#params[i]
324
+ }
325
+
326
+ const value = this.req.getParameter(i)
327
+
328
+ this.#params[i] = value
329
+ return value
225
330
  }
226
331
 
227
332
  /**
@@ -229,7 +334,18 @@ export default class HttpContext {
229
334
  * @returns {string}
230
335
  */
231
336
  header(name) {
232
- return this.req.getHeader(name)
337
+ if (name in this.#headers) {
338
+ return this.#headers[name]
339
+ }
340
+
341
+ if (this.#headersCached) {
342
+ return ''
343
+ }
344
+
345
+ const value = this.req.getHeader(name)
346
+
347
+ this.#headers[name] = value
348
+ return value
233
349
  }
234
350
 
235
351
  contentLength() {
package/src/index.js CHANGED
@@ -325,6 +325,11 @@ export default class Server {
325
325
  }
326
326
 
327
327
  if (isPromise(result)) {
328
+ ctx.method()
329
+ ctx.url()
330
+ ctx.cacheQuery()
331
+ ctx.cacheHeaders()
332
+
328
333
  // eslint-disable-next-line promise/catch-or-return
329
334
  result.then(ctx.onResolve, ctx.onReject)
330
335
  return