@adonisjs/http-server 6.8.2-8 → 7.0.0-0

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.
Files changed (107) hide show
  1. package/build/chunk-XX72ATFY.js +4388 -0
  2. package/build/factories/main.d.ts +149 -6
  3. package/build/factories/main.js +331 -14
  4. package/build/index.d.ts +272 -14
  5. package/build/index.js +308 -22
  6. package/build/{src/server/main.d.ts → main-29eaaee4.d.ts} +12 -17
  7. package/build/main-e5b46c83.d.ts +2210 -0
  8. package/build/src/types/main.d.ts +14 -7
  9. package/build/src/types/main.js +0 -15
  10. package/package.json +65 -55
  11. package/build/factories/http_context.d.ts +0 -25
  12. package/build/factories/http_context.js +0 -51
  13. package/build/factories/http_server.d.ts +0 -8
  14. package/build/factories/http_server.js +0 -26
  15. package/build/factories/qs_parser_factory.d.ts +0 -20
  16. package/build/factories/qs_parser_factory.js +0 -44
  17. package/build/factories/request.d.ts +0 -29
  18. package/build/factories/request.js +0 -73
  19. package/build/factories/response.d.ts +0 -29
  20. package/build/factories/response.js +0 -77
  21. package/build/factories/router.d.ts +0 -23
  22. package/build/factories/router.js +0 -45
  23. package/build/factories/server_factory.d.ts +0 -29
  24. package/build/factories/server_factory.js +0 -65
  25. package/build/src/cookies/client.d.ts +0 -37
  26. package/build/src/cookies/client.js +0 -84
  27. package/build/src/cookies/drivers/encrypted.d.ts +0 -16
  28. package/build/src/cookies/drivers/encrypted.js +0 -36
  29. package/build/src/cookies/drivers/plain.d.ts +0 -15
  30. package/build/src/cookies/drivers/plain.js +0 -33
  31. package/build/src/cookies/drivers/signed.d.ts +0 -16
  32. package/build/src/cookies/drivers/signed.js +0 -36
  33. package/build/src/cookies/parser.d.ts +0 -37
  34. package/build/src/cookies/parser.js +0 -167
  35. package/build/src/cookies/serializer.d.ts +0 -33
  36. package/build/src/cookies/serializer.js +0 -79
  37. package/build/src/debug.d.ts +0 -3
  38. package/build/src/debug.js +0 -10
  39. package/build/src/define_config.d.ts +0 -5
  40. package/build/src/define_config.js +0 -51
  41. package/build/src/define_middleware.d.ts +0 -11
  42. package/build/src/define_middleware.js +0 -35
  43. package/build/src/exception_handler.d.ts +0 -90
  44. package/build/src/exception_handler.js +0 -239
  45. package/build/src/exceptions.d.ts +0 -84
  46. package/build/src/exceptions.js +0 -38
  47. package/build/src/helpers.d.ts +0 -23
  48. package/build/src/helpers.js +0 -84
  49. package/build/src/http_context/local_storage.d.ts +0 -12
  50. package/build/src/http_context/local_storage.js +0 -39
  51. package/build/src/http_context/main.d.ts +0 -58
  52. package/build/src/http_context/main.js +0 -105
  53. package/build/src/qs.d.ts +0 -11
  54. package/build/src/qs.js +0 -25
  55. package/build/src/redirect.d.ts +0 -42
  56. package/build/src/redirect.js +0 -140
  57. package/build/src/request.d.ts +0 -565
  58. package/build/src/request.js +0 -865
  59. package/build/src/response.d.ts +0 -540
  60. package/build/src/response.js +0 -1208
  61. package/build/src/router/brisk.d.ts +0 -42
  62. package/build/src/router/brisk.js +0 -85
  63. package/build/src/router/executor.d.ts +0 -8
  64. package/build/src/router/executor.js +0 -29
  65. package/build/src/router/factories/use_return_value.d.ts +0 -6
  66. package/build/src/router/factories/use_return_value.js +0 -22
  67. package/build/src/router/group.d.ts +0 -65
  68. package/build/src/router/group.js +0 -207
  69. package/build/src/router/lookup_store/main.d.ts +0 -49
  70. package/build/src/router/lookup_store/main.js +0 -86
  71. package/build/src/router/lookup_store/route_finder.d.ts +0 -21
  72. package/build/src/router/lookup_store/route_finder.js +0 -49
  73. package/build/src/router/lookup_store/url_builder.d.ts +0 -52
  74. package/build/src/router/lookup_store/url_builder.js +0 -209
  75. package/build/src/router/main.d.ts +0 -128
  76. package/build/src/router/main.js +0 -316
  77. package/build/src/router/matchers.d.ts +0 -27
  78. package/build/src/router/matchers.js +0 -36
  79. package/build/src/router/parser.d.ts +0 -5
  80. package/build/src/router/parser.js +0 -17
  81. package/build/src/router/resource.d.ts +0 -54
  82. package/build/src/router/resource.js +0 -216
  83. package/build/src/router/route.d.ts +0 -92
  84. package/build/src/router/route.js +0 -293
  85. package/build/src/router/store.d.ts +0 -66
  86. package/build/src/router/store.js +0 -195
  87. package/build/src/server/factories/final_handler.d.ts +0 -9
  88. package/build/src/server/factories/final_handler.js +0 -30
  89. package/build/src/server/factories/middleware_handler.d.ts +0 -8
  90. package/build/src/server/factories/middleware_handler.js +0 -16
  91. package/build/src/server/factories/write_response.d.ts +0 -6
  92. package/build/src/server/factories/write_response.js +0 -24
  93. package/build/src/server/main.js +0 -283
  94. package/build/src/types/base.d.ts +0 -19
  95. package/build/src/types/base.js +0 -9
  96. package/build/src/types/middleware.d.ts +0 -35
  97. package/build/src/types/middleware.js +0 -9
  98. package/build/src/types/qs.d.ts +0 -68
  99. package/build/src/types/qs.js +0 -9
  100. package/build/src/types/request.d.ts +0 -39
  101. package/build/src/types/request.js +0 -9
  102. package/build/src/types/response.d.ts +0 -45
  103. package/build/src/types/response.js +0 -9
  104. package/build/src/types/route.d.ts +0 -165
  105. package/build/src/types/route.js +0 -9
  106. package/build/src/types/server.d.ts +0 -72
  107. package/build/src/types/server.js +0 -9
@@ -1,865 +0,0 @@
1
- /*
2
- * @adonisjs/http-server
3
- *
4
- * (c) AdonisJS
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- import fresh from 'fresh';
10
- import typeIs from 'type-is';
11
- import accepts from 'accepts';
12
- import { isIP } from 'node:net';
13
- import is from '@sindresorhus/is';
14
- import proxyaddr from 'proxy-addr';
15
- import { safeEqual } from '@poppinss/utils';
16
- import Macroable from '@poppinss/macroable';
17
- import lodash from '@poppinss/utils/lodash';
18
- import { createId } from '@paralleldrive/cuid2';
19
- import { parse } from 'node:url';
20
- import { trustProxy } from './helpers.js';
21
- import { CookieParser } from './cookies/parser.js';
22
- /**
23
- * HTTP Request class exposes the interface to consistently read values
24
- * related to a given HTTP request. The class is wrapper over
25
- * [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
26
- * and has extended API.
27
- *
28
- * You can access the original [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
29
- * using `request.request` property.
30
- */
31
- export class Request extends Macroable {
32
- request;
33
- response;
34
- /**
35
- * Query string parser
36
- */
37
- #qsParser;
38
- /**
39
- * Encryption module to verify signed URLs and unsign/decrypt
40
- * cookies
41
- */
42
- #encryption;
43
- /**
44
- * Request config
45
- */
46
- #config;
47
- /**
48
- * Request body set using `setBody` method
49
- */
50
- #requestBody = {};
51
- /**
52
- * A merged copy of `request body` and `querystring`
53
- */
54
- #requestData = {};
55
- /**
56
- * Original merged copy of `request body` and `querystring`.
57
- * Further mutation to this object are not allowed
58
- */
59
- #originalRequestData = {};
60
- /**
61
- * Parsed query string
62
- */
63
- #requestQs = {};
64
- /**
65
- * Raw request body as text
66
- */
67
- #rawRequestBody;
68
- /**
69
- * Cached copy of `accepts` fn to do content
70
- * negotiation.
71
- */
72
- #lazyAccepts;
73
- /**
74
- * Copy of lazily parsed signed and plain cookies.
75
- */
76
- #cookieParser;
77
- /**
78
- * Parses copy of the URL with query string as a string and not
79
- * object. This is done to build URL's with query string without
80
- * stringifying the object
81
- */
82
- parsedUrl;
83
- /**
84
- * The ctx will be set by the context itself. It creates a circular
85
- * reference
86
- */
87
- ctx;
88
- constructor(request, response, encryption, config, qsParser) {
89
- super();
90
- this.request = request;
91
- this.response = response;
92
- this.#qsParser = qsParser;
93
- this.#config = config;
94
- this.#encryption = encryption;
95
- this.parsedUrl = parse(this.request.url, false);
96
- this.#parseQueryString();
97
- }
98
- /**
99
- * Parses the query string
100
- */
101
- #parseQueryString() {
102
- if (this.parsedUrl.query) {
103
- this.updateQs(this.#qsParser.parse(this.parsedUrl.query));
104
- this.#originalRequestData = { ...this.#requestData };
105
- }
106
- }
107
- /**
108
- * Initiates the cookie parser lazily
109
- */
110
- #initiateCookieParser() {
111
- if (!this.#cookieParser) {
112
- this.#cookieParser = new CookieParser(this.header('cookie'), this.#encryption);
113
- }
114
- }
115
- /**
116
- * Lazily initiates the `accepts` module to make sure to parse
117
- * the request headers only when one of the content-negotiation
118
- * methods are used.
119
- */
120
- #initiateAccepts() {
121
- this.#lazyAccepts = this.#lazyAccepts || accepts(this.request);
122
- }
123
- /**
124
- * Returns the request id from the `x-request-id` header. The
125
- * header is untouched, if it already exists.
126
- */
127
- id() {
128
- let requestId = this.header('x-request-id');
129
- if (!requestId && this.#config.generateRequestId) {
130
- requestId = createId();
131
- this.request.headers['x-request-id'] = requestId;
132
- }
133
- return requestId;
134
- }
135
- /**
136
- * Set initial request body. A copy of the input will be maintained as the original
137
- * request body. Since the request body and query string is subject to mutations, we
138
- * keep one original reference to flash old data (whenever required).
139
- *
140
- * This method is supposed to be invoked by the body parser and must be called only
141
- * once. For further mutations make use of `updateBody` method.
142
- */
143
- setInitialBody(body) {
144
- if (this.#originalRequestData && Object.isFrozen(this.#originalRequestData)) {
145
- throw new Error('Cannot re-set initial body. Use "request.updateBody" instead');
146
- }
147
- this.updateBody(body);
148
- /*
149
- * Freeze the original object
150
- */
151
- this.#originalRequestData = Object.freeze(lodash.cloneDeep(this.#requestData));
152
- }
153
- /**
154
- * Update the request body with new data object. The `all` property
155
- * will be re-computed by merging the query string and request
156
- * body.
157
- */
158
- updateBody(body) {
159
- this.#requestBody = body;
160
- this.#requestData = { ...this.#requestBody, ...this.#requestQs };
161
- }
162
- /**
163
- * Update the request raw body. Bodyparser sets this when unable to parse
164
- * the request body or when request is multipart/form-data.
165
- */
166
- updateRawBody(rawBody) {
167
- this.#rawRequestBody = rawBody;
168
- }
169
- /**
170
- * Update the query string with the new data object. The `all` property
171
- * will be re-computed by merging the query and the request body.
172
- */
173
- updateQs(data) {
174
- this.#requestQs = data;
175
- this.#requestData = { ...this.#requestBody, ...this.#requestQs };
176
- }
177
- /**
178
- * Returns route params
179
- */
180
- params() {
181
- return this.ctx?.params || {};
182
- }
183
- /**
184
- * Returns the query string object by reference
185
- */
186
- qs() {
187
- return this.#requestQs;
188
- }
189
- /**
190
- * Returns reference to the request body
191
- */
192
- body() {
193
- return this.#requestBody;
194
- }
195
- /**
196
- * Returns reference to the merged copy of request body
197
- * and query string
198
- */
199
- all() {
200
- return this.#requestData;
201
- }
202
- /**
203
- * Returns reference to the merged copy of original request
204
- * query string and body
205
- */
206
- original() {
207
- return this.#originalRequestData;
208
- }
209
- /**
210
- * Returns the request raw body (if exists), or returns `null`.
211
- *
212
- * Ideally you must be dealing with the parsed body accessed using [[input]], [[all]] or
213
- * [[post]] methods. The `raw` body is always a string.
214
- */
215
- raw() {
216
- return this.#rawRequestBody || null;
217
- }
218
- /**
219
- * Returns value for a given key from the request body or query string.
220
- * The `defaultValue` is used when original value is `undefined`.
221
- *
222
- * @example
223
- * ```js
224
- * request.input('username')
225
- *
226
- * // with default value
227
- * request.input('username', 'virk')
228
- * ```
229
- */
230
- input(key, defaultValue) {
231
- return lodash.get(this.#requestData, key, defaultValue);
232
- }
233
- /**
234
- * Returns value for a given key from route params
235
- *
236
- * @example
237
- * ```js
238
- * request.param('id')
239
- *
240
- * // with default value
241
- * request.param('id', 1)
242
- * ```
243
- */
244
- param(key, defaultValue) {
245
- return lodash.get(this.params(), key, defaultValue);
246
- }
247
- /**
248
- * Get everything from the request body except the given keys.
249
- *
250
- * @example
251
- * ```js
252
- * request.except(['_csrf'])
253
- * ```
254
- */
255
- except(keys) {
256
- return lodash.omit(this.#requestData, keys);
257
- }
258
- /**
259
- * Get value for specified keys.
260
- *
261
- * @example
262
- * ```js
263
- * request.only(['username', 'age'])
264
- * ```
265
- */
266
- only(keys) {
267
- return lodash.pick(this.#requestData, keys);
268
- }
269
- /**
270
- * Returns the HTTP request method. This is the original
271
- * request method. For spoofed request method, make
272
- * use of [[method]].
273
- *
274
- * @example
275
- * ```js
276
- * request.intended()
277
- * ```
278
- */
279
- intended() {
280
- return this.request.method;
281
- }
282
- /**
283
- * Returns the request HTTP method by taking method spoofing into account.
284
- *
285
- * Method spoofing works when all of the following are true.
286
- *
287
- * 1. `app.http.allowMethodSpoofing` config value is true.
288
- * 2. request query string has `_method`.
289
- * 3. The [[intended]] request method is `POST`.
290
- *
291
- * @example
292
- * ```js
293
- * request.method()
294
- * ```
295
- */
296
- method() {
297
- if (this.#config.allowMethodSpoofing && this.intended() === 'POST') {
298
- return this.input('_method', this.intended()).toUpperCase();
299
- }
300
- return this.intended();
301
- }
302
- /**
303
- * Returns a copy of headers as an object
304
- */
305
- headers() {
306
- return this.request.headers;
307
- }
308
- /**
309
- * Returns value for a given header key. The default value is
310
- * used when original value is `undefined`.
311
- */
312
- header(key, defaultValue) {
313
- key = key.toLowerCase();
314
- const headers = this.headers();
315
- switch (key) {
316
- case 'referer':
317
- case 'referrer':
318
- return headers.referrer || headers.referer || defaultValue;
319
- default:
320
- return headers[key] || defaultValue;
321
- }
322
- }
323
- /**
324
- * Returns the ip address of the user. This method is optimize to fetch
325
- * ip address even when running your AdonisJs app behind a proxy.
326
- *
327
- * You can also define your own custom function to compute the ip address by
328
- * defining `app.http.getIp` as a function inside the config file.
329
- *
330
- * ```js
331
- * {
332
- * http: {
333
- * getIp (request) {
334
- * // I am using nginx as a proxy server and want to trust 'x-real-ip'
335
- * return request.header('x-real-ip')
336
- * }
337
- * }
338
- * }
339
- * ```
340
- *
341
- * You can control the behavior of trusting the proxy values by defining it
342
- * inside the `config/app.js` file.
343
- *
344
- * ```js
345
- * {
346
- * http: {
347
- * trustProxy: '127.0.0.1'
348
- * }
349
- * }
350
- * ```
351
- *
352
- * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
353
- */
354
- ip() {
355
- const ipFn = this.#config.getIp;
356
- if (typeof ipFn === 'function') {
357
- return ipFn(this);
358
- }
359
- return proxyaddr(this.request, this.#config.trustProxy);
360
- }
361
- /**
362
- * Returns an array of ip addresses from most to least trusted one.
363
- * This method is optimize to fetch ip address even when running
364
- * your AdonisJs app behind a proxy.
365
- *
366
- * You can control the behavior of trusting the proxy values by defining it
367
- * inside the `config/app.js` file.
368
- *
369
- * ```js
370
- * {
371
- * http: {
372
- * trustProxy: '127.0.0.1'
373
- * }
374
- * }
375
- * ```
376
- *
377
- * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
378
- */
379
- ips() {
380
- return proxyaddr.all(this.request, this.#config.trustProxy);
381
- }
382
- /**
383
- * Returns the request protocol by checking for the URL protocol or
384
- * `X-Forwarded-Proto` header.
385
- *
386
- * If the `trust` is evaluated to `false`, then URL protocol is returned,
387
- * otherwise `X-Forwarded-Proto` header is used (if exists).
388
- *
389
- * You can control the behavior of trusting the proxy values by defining it
390
- * inside the `config/app.js` file.
391
- *
392
- * ```js
393
- * {
394
- * http: {
395
- * trustProxy: '127.0.0.1'
396
- * }
397
- * }
398
- * ```
399
- *
400
- * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
401
- */
402
- protocol() {
403
- if ('encrypted' in this.request.socket) {
404
- return 'https';
405
- }
406
- if (!trustProxy(this.request.socket.remoteAddress, this.#config.trustProxy)) {
407
- return this.parsedUrl.protocol || 'http';
408
- }
409
- const forwardedProtocol = this.header('X-Forwarded-Proto');
410
- return forwardedProtocol ? forwardedProtocol.split(/\s*,\s*/)[0] : 'http';
411
- }
412
- /**
413
- * Returns a boolean telling if request is served over `https`
414
- * or not. Check [[protocol]] method to know how protocol is
415
- * fetched.
416
- */
417
- secure() {
418
- return this.protocol() === 'https';
419
- }
420
- /**
421
- * Returns the request host. If proxy headers are trusted, then
422
- * `X-Forwarded-Host` is given priority over the `Host` header.
423
- *
424
- * You can control the behavior of trusting the proxy values by defining it
425
- * inside the `config/app.js` file.
426
- *
427
- * ```js
428
- * {
429
- * http: {
430
- * trustProxy: '127.0.0.1'
431
- * }
432
- * }
433
- * ```
434
- *
435
- * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
436
- */
437
- host() {
438
- let host = this.header('host');
439
- /*
440
- * Use X-Fowarded-Host when we trust the proxy header and it
441
- * exists
442
- */
443
- if (trustProxy(this.request.socket.remoteAddress, this.#config.trustProxy)) {
444
- host = this.header('X-Forwarded-Host') || host;
445
- }
446
- if (!host) {
447
- return null;
448
- }
449
- return host;
450
- }
451
- /**
452
- * Returns the request hostname. If proxy headers are trusted, then
453
- * `X-Forwarded-Host` is given priority over the `Host` header.
454
- *
455
- * You can control the behavior of trusting the proxy values by defining it
456
- * inside the `config/app.js` file.
457
- *
458
- * ```js
459
- * {
460
- * http: {
461
- * trustProxy: '127.0.0.1'
462
- * }
463
- * }
464
- * ```
465
- *
466
- * The value of trustProxy is passed directly to [proxy-addr](https://www.npmjs.com/package/proxy-addr)
467
- */
468
- hostname() {
469
- const host = this.host();
470
- if (!host) {
471
- return null;
472
- }
473
- /*
474
- * Support for IPv6
475
- * https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
476
- * https://github.com/nodejs/node/pull/5314
477
- */
478
- const offset = host[0] === '[' ? host.indexOf(']') + 1 : 0;
479
- const index = host.indexOf(':', offset);
480
- return index !== -1 ? host.substring(0, index) : host;
481
- }
482
- /**
483
- * Returns an array of subdomains for the given host. An empty array is
484
- * returned if [[hostname]] is `null` or is an IP address.
485
- *
486
- * Also `www` is not considered as a subdomain
487
- */
488
- subdomains() {
489
- const hostname = this.hostname();
490
- /*
491
- * Return empty array when hostname is missing or it's
492
- * an IP address
493
- */
494
- if (!hostname || isIP(hostname)) {
495
- return [];
496
- }
497
- const offset = this.#config.subdomainOffset;
498
- const subdomains = hostname.split('.').reverse().slice(offset);
499
- /*
500
- * Remove www from the subdomains list
501
- */
502
- if (subdomains[subdomains.length - 1] === 'www') {
503
- subdomains.splice(subdomains.length - 1, 1);
504
- }
505
- return subdomains;
506
- }
507
- /**
508
- * Returns a boolean telling, if request `X-Requested-With === 'xmlhttprequest'`
509
- * or not.
510
- */
511
- ajax() {
512
- const xRequestedWith = this.header('X-Requested-With', '');
513
- return xRequestedWith.toLowerCase() === 'xmlhttprequest';
514
- }
515
- /**
516
- * Returns a boolean telling, if request has `X-Pjax` header
517
- * set or not
518
- */
519
- pjax() {
520
- return !!this.header('X-Pjax');
521
- }
522
- /**
523
- * Returns the request relative URL.
524
- *
525
- * @example
526
- * ```js
527
- * request.url()
528
- *
529
- * // include query string
530
- * request.url(true)
531
- * ```
532
- */
533
- url(includeQueryString) {
534
- const pathname = this.parsedUrl.pathname;
535
- return includeQueryString && this.parsedUrl.query
536
- ? `${pathname}?${this.parsedUrl.query}`
537
- : pathname;
538
- }
539
- /**
540
- * Returns the complete HTTP url by combining
541
- * [[protocol]]://[[hostname]]/[[url]]
542
- *
543
- * @example
544
- * ```js
545
- * request.completeUrl()
546
- *
547
- * // include query string
548
- * request.completeUrl(true)
549
- * ```
550
- */
551
- completeUrl(includeQueryString) {
552
- const protocol = this.protocol();
553
- const hostname = this.host();
554
- return `${protocol}://${hostname}${this.url(includeQueryString)}`;
555
- }
556
- /**
557
- * Find if the current HTTP request is for the given route or the routes
558
- */
559
- matchesRoute(routeIdentifier) {
560
- /**
561
- * The context is missing inside the HTTP server hooks.
562
- */
563
- if (!this.ctx || !this.ctx.route) {
564
- return false;
565
- }
566
- const route = this.ctx.route;
567
- /**
568
- * Search the identifier(s) against the route "pattern", "name" and the route handler
569
- */
570
- return !!(Array.isArray(routeIdentifier) ? routeIdentifier : [routeIdentifier]).find((identifier) => {
571
- if (route.pattern === identifier || route.name === identifier) {
572
- return true;
573
- }
574
- if (typeof route.handler === 'function') {
575
- return false;
576
- }
577
- return route.handler.reference === identifier;
578
- });
579
- }
580
- /**
581
- * Returns the best matching content type of the request by
582
- * matching against the given types.
583
- *
584
- * The content type is picked from the `content-type` header and request
585
- * must have body.
586
- *
587
- * The method response highly depends upon the types array values. Described below:
588
- *
589
- * | Type(s) | Return value |
590
- * |----------|---------------|
591
- * | ['json'] | json |
592
- * | ['application/*'] | application/json |
593
- * | ['vnd+json'] | application/json |
594
- *
595
- * @example
596
- * ```js
597
- * const bodyType = request.is(['json', 'xml'])
598
- *
599
- * if (bodyType === 'json') {
600
- * // process JSON
601
- * }
602
- *
603
- * if (bodyType === 'xml') {
604
- * // process XML
605
- * }
606
- * ```
607
- */
608
- is(types) {
609
- return typeIs(this.request, types) || null;
610
- }
611
- /**
612
- * Returns the best type using `Accept` header and
613
- * by matching it against the given types.
614
- *
615
- * If nothing is matched, then `null` will be returned
616
- *
617
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
618
- * docs too.
619
- *
620
- * @example
621
- * ```js
622
- * switch (request.accepts(['json', 'html'])) {
623
- * case 'json':
624
- * return response.json(user)
625
- * case 'html':
626
- * return view.render('user', { user })
627
- * default:
628
- * // decide yourself
629
- * }
630
- * ```
631
- */
632
- accepts(types) {
633
- this.#initiateAccepts();
634
- return this.#lazyAccepts.type(types) || null;
635
- }
636
- /**
637
- * Return the types that the request accepts, in the order of the
638
- * client's preference (most preferred first).
639
- *
640
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
641
- * docs too.
642
- */
643
- types() {
644
- this.#initiateAccepts();
645
- return this.#lazyAccepts.types();
646
- }
647
- /**
648
- * Returns the best language using `Accept-language` header
649
- * and by matching it against the given languages.
650
- *
651
- * If nothing is matched, then `null` will be returned
652
- *
653
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
654
- * docs too.
655
- *
656
- * @example
657
- * ```js
658
- * switch (request.language(['fr', 'de'])) {
659
- * case 'fr':
660
- * return view.render('about', { lang: 'fr' })
661
- * case 'de':
662
- * return view.render('about', { lang: 'de' })
663
- * default:
664
- * return view.render('about', { lang: 'en' })
665
- * }
666
- * ```
667
- */
668
- language(languages) {
669
- this.#initiateAccepts();
670
- return this.#lazyAccepts.language(languages) || null;
671
- }
672
- /**
673
- * Return the languages that the request accepts, in the order of the
674
- * client's preference (most preferred first).
675
- *
676
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
677
- * docs too.
678
- */
679
- languages() {
680
- this.#initiateAccepts();
681
- return this.#lazyAccepts.languages();
682
- }
683
- /**
684
- * Returns the best charset using `Accept-charset` header
685
- * and by matching it against the given charsets.
686
- *
687
- * If nothing is matched, then `null` will be returned
688
- *
689
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
690
- * docs too.
691
- *
692
- * @example
693
- * ```js
694
- * switch (request.charset(['utf-8', 'ISO-8859-1'])) {
695
- * case 'utf-8':
696
- * // make utf-8 friendly response
697
- * case 'ISO-8859-1':
698
- * // make ISO-8859-1 friendly response
699
- * }
700
- * ```
701
- */
702
- charset(charsets) {
703
- this.#initiateAccepts();
704
- return this.#lazyAccepts.charset(charsets) || null;
705
- }
706
- /**
707
- * Return the charsets that the request accepts, in the order of the
708
- * client's preference (most preferred first).
709
- *
710
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
711
- * docs too.
712
- */
713
- charsets() {
714
- this.#initiateAccepts();
715
- return this.#lazyAccepts.charsets();
716
- }
717
- /**
718
- * Returns the best encoding using `Accept-encoding` header
719
- * and by matching it against the given encodings.
720
- *
721
- * If nothing is matched, then `null` will be returned
722
- *
723
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
724
- * docs too.
725
- */
726
- encoding(encodings) {
727
- this.#initiateAccepts();
728
- return this.#lazyAccepts.encoding(encodings) || null;
729
- }
730
- /**
731
- * Return the charsets that the request accepts, in the order of the
732
- * client's preference (most preferred first).
733
- *
734
- * Make sure to check [accepts](https://www.npmjs.com/package/accepts) package
735
- * docs too.
736
- */
737
- encodings() {
738
- this.#initiateAccepts();
739
- return this.#lazyAccepts.encodings();
740
- }
741
- /**
742
- * Returns a boolean telling if request has body
743
- */
744
- hasBody() {
745
- return typeIs.hasBody(this.request);
746
- }
747
- /**
748
- * Returns a boolean telling if the new response etag evaluates same
749
- * as the request header `if-none-match`. In case of `true`, the
750
- * server must return `304` response, telling the browser to
751
- * use the client cache.
752
- *
753
- * You won't have to deal with this method directly, since AdonisJs will
754
- * handle this for you when `http.etag = true` inside `config/app.js` file.
755
- *
756
- * However, this is how you can use it manually.
757
- *
758
- * ```js
759
- * const responseBody = view.render('some-view')
760
- *
761
- * // sets the HTTP etag header for response
762
- * response.setEtag(responseBody)
763
- *
764
- * if (request.fresh()) {
765
- * response.sendStatus(304)
766
- * } else {
767
- * response.send(responseBody)
768
- * }
769
- * ```
770
- */
771
- fresh() {
772
- if (['GET', 'HEAD'].indexOf(this.intended()) === -1) {
773
- return false;
774
- }
775
- const status = this.response.statusCode;
776
- if ((status >= 200 && status < 300) || status === 304) {
777
- return fresh(this.headers(), this.response.getHeaders());
778
- }
779
- return false;
780
- }
781
- /**
782
- * Opposite of [[fresh]]
783
- */
784
- stale() {
785
- return !this.fresh();
786
- }
787
- /**
788
- * Returns all parsed and signed cookies. Signed cookies ensures
789
- * that their value isn't tampered.
790
- */
791
- cookiesList() {
792
- this.#initiateCookieParser();
793
- return this.#cookieParser.list();
794
- }
795
- /**
796
- * Returns value for a given key from signed cookies. Optional
797
- * defaultValue is returned when actual value is undefined.
798
- */
799
- cookie(key, defaultValue) {
800
- this.#initiateCookieParser();
801
- return this.#cookieParser.unsign(key) || defaultValue;
802
- }
803
- /**
804
- * Returns value for a given key from signed cookies. Optional
805
- * defaultValue is returned when actual value is undefined.
806
- */
807
- encryptedCookie(key, defaultValue) {
808
- this.#initiateCookieParser();
809
- return this.#cookieParser.decrypt(key) || defaultValue;
810
- }
811
- plainCookie(key, defaultValueOrOptions, encoded) {
812
- this.#initiateCookieParser();
813
- if (is.object(defaultValueOrOptions)) {
814
- return (this.#cookieParser.decode(key, defaultValueOrOptions?.encoded) ||
815
- defaultValueOrOptions.defaultValue);
816
- }
817
- return this.#cookieParser.decode(key, encoded) || defaultValueOrOptions;
818
- }
819
- /**
820
- * Returns a boolean telling if a signed url as a valid signature
821
- * or not.
822
- */
823
- hasValidSignature(purpose) {
824
- const { signature, ...rest } = this.qs();
825
- if (!signature) {
826
- return false;
827
- }
828
- /*
829
- * Return false when signature fails
830
- */
831
- const signedUrl = this.#encryption.verifier.unsign(signature, purpose);
832
- if (!signedUrl) {
833
- return false;
834
- }
835
- const queryString = this.#qsParser.stringify(rest);
836
- return queryString
837
- ? safeEqual(signedUrl, `${this.url()}?${queryString}`)
838
- : safeEqual(signedUrl, this.url());
839
- }
840
- /**
841
- * Serializes request to JSON format
842
- */
843
- serialize() {
844
- return {
845
- id: this.id(),
846
- url: this.url(),
847
- query: this.parsedUrl.query,
848
- body: this.all(),
849
- params: this.params(),
850
- headers: this.headers(),
851
- method: this.method(),
852
- protocol: this.protocol(),
853
- cookies: this.cookiesList(),
854
- hostname: this.hostname(),
855
- ip: this.ip(),
856
- subdomains: this.ctx?.subdomains || {},
857
- };
858
- }
859
- /**
860
- * toJSON copy of the request
861
- */
862
- toJSON() {
863
- return this.serialize();
864
- }
865
- }