@johntalton/http-core 1.0.1 → 1.0.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 +2 -2
- package/src/epilogue.js +17 -14
- package/src/index.js +152 -28
- package/src/preamble.js +27 -21
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@johntalton/http-core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./src/index.js"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@johntalton/http-util": "^5.
|
|
18
|
+
"@johntalton/http-util": "^5.1.2",
|
|
19
19
|
"@johntalton/sse-util": "^1.0.0"
|
|
20
20
|
}
|
|
21
21
|
}
|
package/src/epilogue.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Response } from '@johntalton/http-util/response/object'
|
|
2
1
|
import { MIME_TYPE_JSON } from '@johntalton/http-util/headers'
|
|
2
|
+
import { Response } from '@johntalton/http-util/response/object'
|
|
3
3
|
import { ServerSentEvents } from '@johntalton/sse-util'
|
|
4
4
|
|
|
5
5
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
@@ -34,9 +34,10 @@ function addSSEPortHandler(stream, port, streamId, shutdownSignal) {
|
|
|
34
34
|
port.onmessage = message => {
|
|
35
35
|
const { data } = message
|
|
36
36
|
console.log('sending sse data', streamId, data)
|
|
37
|
-
|
|
38
|
-
ServerSentEvents.lineGen(data)
|
|
39
|
-
|
|
37
|
+
|
|
38
|
+
for(const line of ServerSentEvents.lineGen(data)) {
|
|
39
|
+
stream.write(line)
|
|
40
|
+
}
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -53,17 +54,18 @@ export function epilogue(state) {
|
|
|
53
54
|
case 'trace': { Response.trace(stream, state.method, state.url, state.headers, meta) } break
|
|
54
55
|
//
|
|
55
56
|
case 'preflight': { Response.preflight(stream, state.methods, state.supportedQueryTypes, undefined, meta) } break
|
|
56
|
-
|
|
57
|
+
case 'no-content': { Response.noContent(stream, state.etag, meta)} break
|
|
57
58
|
// case 'accepted': { Response.accepted(stream, meta) } break
|
|
58
59
|
case 'created': { Response.created(stream, new URL(state.location, meta.origin), state.etag, meta) } break
|
|
59
60
|
case 'not-modified': { Response.notModified(stream, state.etag, state.age, { priv: true, maxAge: 60 }, meta) } break
|
|
60
61
|
|
|
61
62
|
//
|
|
62
63
|
// case 'multiple-choices': { Response.multipleChoices(stream, meta) } break
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
case 'gone': { Response.gone(stream, meta) } break
|
|
65
|
+
case 'moved-permanently': { Response.movedPermanently(stream, state.location, meta) } break
|
|
66
|
+
case 'see-other': { Response.seeOther(stream, state.location, meta) } break
|
|
67
|
+
case 'temporary-redirect': { Response.temporaryRedirect(stream, state.location, meta) } break
|
|
68
|
+
case 'permanent-redirect': { Response.permanentRedirect(stream, state.location, meta) } break
|
|
67
69
|
|
|
68
70
|
//
|
|
69
71
|
case '404': { Response.notFound(stream, state.message, meta) } break
|
|
@@ -74,13 +76,14 @@ export function epilogue(state) {
|
|
|
74
76
|
case 'unprocessable': { Response.unprocessable(stream, meta) } break
|
|
75
77
|
case 'precondition-failed': { Response.preconditionFailed(stream, meta) } break
|
|
76
78
|
case 'not-satisfiable': { Response.rangeNotSatisfiable(stream, { size: state.contentLength }, meta) } break
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
case 'content-too-large': { Response.contentTooLarge(stream, meta) } break
|
|
80
|
+
case 'insufficient-storage': { Response.insufficientStorage(stream, meta) } break
|
|
81
|
+
case 'too-many-requests': { Response.tooManyRequests(stream, state.limit, state.policies, meta) } break
|
|
82
|
+
case 'unauthorized': { Response.unauthorized(stream, state.challenge, meta) } break
|
|
83
|
+
case 'forbidden': { Response.forbidden(stream, meta) } break
|
|
81
84
|
case 'unavailable': { Response.unavailable(stream, state.message, state.retryAfter, meta)} break
|
|
82
85
|
case 'not-implemented': { Response.notImplemented(stream, state.message, meta)} break
|
|
83
|
-
|
|
86
|
+
case 'timeout': { Response.timeout(stream, meta) } break
|
|
84
87
|
|
|
85
88
|
//
|
|
86
89
|
case 'sse': {
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
import fs from 'node:fs'
|
|
1
|
+
/** biome-ignore-all lint/nursery/noExcessiveLinesPerFile: legacy */
|
|
3
2
|
import crypto from 'node:crypto'
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import http2 from 'node:http2'
|
|
4
5
|
|
|
5
6
|
import { HTTP_METHOD_QUERY } from '@johntalton/http-util/response'
|
|
6
7
|
|
|
7
|
-
import { preamble } from './preamble.js'
|
|
8
8
|
import { epilogue } from './epilogue.js'
|
|
9
|
+
import { preamble } from './preamble.js'
|
|
9
10
|
|
|
10
11
|
const {
|
|
11
12
|
HTTP2_METHOD_GET,
|
|
@@ -18,6 +19,12 @@ const {
|
|
|
18
19
|
HTTP2_METHOD_TRACE
|
|
19
20
|
} = http2.constants
|
|
20
21
|
|
|
22
|
+
const {
|
|
23
|
+
SSL_OP_NO_TLSv1,
|
|
24
|
+
SSL_OP_NO_TLSv1_1,
|
|
25
|
+
SSL_OP_NO_TLSv1_2,
|
|
26
|
+
} = crypto.constants
|
|
27
|
+
|
|
21
28
|
export const KNOWN_METHODS = [
|
|
22
29
|
HTTP2_METHOD_GET,
|
|
23
30
|
HTTP2_METHOD_HEAD,
|
|
@@ -35,14 +42,46 @@ export const KNOWN_METHODS = [
|
|
|
35
42
|
|
|
36
43
|
/** @import { Metadata } from '@johntalton/http-util/response' */
|
|
37
44
|
/** @import { BodyFuture } from '@johntalton/http-util/body' */
|
|
38
|
-
/** @import { EtagItem, IMFFixDate, ContentRangeDirective } from '@johntalton/http-util/headers' */
|
|
45
|
+
/** @import { EtagItem, IMFFixDate, ContentRangeDirective, RateLimitPolicyInfo, RateLimitInfo, ChallengeItem } from '@johntalton/http-util/headers' */
|
|
39
46
|
/** @import { SendBody } from '@johntalton/http-util/response' */
|
|
40
47
|
|
|
41
48
|
/** @typedef {(state: RouteRequest|RouteAction) => Promise<RouteAction>} Router */
|
|
42
49
|
|
|
43
50
|
/** @typedef {'request'} RouteTypeRequest */
|
|
44
|
-
/** @typedef {
|
|
45
|
-
|
|
51
|
+
/** @typedef {
|
|
52
|
+
'partial-bytes' |
|
|
53
|
+
'bytes' |
|
|
54
|
+
'json' |
|
|
55
|
+
'404' |
|
|
56
|
+
'sse' |
|
|
57
|
+
'error' |
|
|
58
|
+
'preflight' |
|
|
59
|
+
'not-allowed' |
|
|
60
|
+
'trace' |
|
|
61
|
+
'created' |
|
|
62
|
+
'unsupported-media' |
|
|
63
|
+
'not-modified' |
|
|
64
|
+
'precondition-failed' |
|
|
65
|
+
'unprocessable' |
|
|
66
|
+
'not-acceptable' |
|
|
67
|
+
'conflict' |
|
|
68
|
+
'not-implemented' |
|
|
69
|
+
'unavailable' |
|
|
70
|
+
'not-satisfiable' |
|
|
71
|
+
'see-other' |
|
|
72
|
+
'temporary-redirect' |
|
|
73
|
+
'permanent-redirect' |
|
|
74
|
+
'moved-permanently' |
|
|
75
|
+
'gone' |
|
|
76
|
+
'no-content' |
|
|
77
|
+
'content-too-large' |
|
|
78
|
+
'insufficient-storage' |
|
|
79
|
+
'too-many-requests' |
|
|
80
|
+
'unauthorized' |
|
|
81
|
+
'forbidden' |
|
|
82
|
+
'timeout'
|
|
83
|
+
} RouteType */
|
|
84
|
+
/** @typedef {'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'OPTIONS'|'DELETE'|'TRACE'|'QUERY'} RouteMethod */
|
|
46
85
|
|
|
47
86
|
/** @typedef {string & { readonly _brand: 'sid' }} StreamID */
|
|
48
87
|
|
|
@@ -271,6 +310,85 @@ export const KNOWN_METHODS = [
|
|
|
271
310
|
*/
|
|
272
311
|
/** @typedef {RouteBase & RouteNotSatisfiableBase} RouteNotSatisfiable */
|
|
273
312
|
|
|
313
|
+
/**
|
|
314
|
+
* @typedef {Object} RouteSeeOtherBase
|
|
315
|
+
* @property {'see-other'} type
|
|
316
|
+
* @property {URL} location
|
|
317
|
+
*/
|
|
318
|
+
/** @typedef {RouteBase & RouteSeeOtherBase} RouteSeeOther */
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* @typedef {Object} RouteTemporaryRedirectBase
|
|
322
|
+
* @property {'temporary-redirect'} type
|
|
323
|
+
* @property {URL} location
|
|
324
|
+
*/
|
|
325
|
+
/** @typedef {RouteBase & RouteTemporaryRedirectBase} RouteTemporaryRedirect */
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* @typedef {Object} RoutePermanentRedirectBase
|
|
329
|
+
* @property {'permanent-redirect'} type
|
|
330
|
+
* @property {URL} location
|
|
331
|
+
*/
|
|
332
|
+
/** @typedef {RouteBase & RoutePermanentRedirectBase} RoutePermanentRedirect */
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* @typedef {Object} RouteMovedPermanentlyBase
|
|
336
|
+
* @property {'moved-permanently'} type
|
|
337
|
+
* @property {URL} location
|
|
338
|
+
*/
|
|
339
|
+
/** @typedef {RouteBase & RouteMovedPermanentlyBase} RouteMovedPermanently */
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* @typedef {Object} RouteNoContentBase
|
|
343
|
+
* @property {'no-content'} type
|
|
344
|
+
* @property {EtagItem|undefined} [etag]
|
|
345
|
+
*/
|
|
346
|
+
/** @typedef {RouteBase & RouteNoContentBase} RouteNoContent */
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* @typedef {Object} RouteGoneBase
|
|
350
|
+
* @property {'gone'} type
|
|
351
|
+
*/
|
|
352
|
+
/** @typedef {RouteBase & RouteGoneBase} RouteGone */
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* @typedef {Object} RouteContentTooLargeBase
|
|
356
|
+
* @property {'content-too-large'} type
|
|
357
|
+
*/
|
|
358
|
+
/** @typedef {RouteBase & RouteContentTooLargeBase} RouteContentTooLarge */
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @typedef {Object} RouteInsufficientStorageBase
|
|
362
|
+
* @property {'insufficient-storage'} type
|
|
363
|
+
*/
|
|
364
|
+
/** @typedef {RouteBase & RouteInsufficientStorageBase} RouteInsufficientStorage */
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @typedef {Object} RouteTooManyRequestsBase
|
|
368
|
+
* @property {'too-many-requests'} type
|
|
369
|
+
* @property {RateLimitInfo} limit
|
|
370
|
+
* @property {Array<RateLimitPolicyInfo>} policies
|
|
371
|
+
*/
|
|
372
|
+
/** @typedef {RouteBase & RouteTooManyRequestsBase} RouteTooManyRequests */
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @typedef {Object} RouteUnauthorizedBase
|
|
376
|
+
* @property {'unauthorized'} type
|
|
377
|
+
* @property {Array<ChallengeItem>} challenge
|
|
378
|
+
*/
|
|
379
|
+
/** @typedef {RouteBase & RouteUnauthorizedBase} RouteUnauthorized */
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* @typedef {Object} RouteForbiddenBase
|
|
383
|
+
* @property {'forbidden'} type
|
|
384
|
+
*/
|
|
385
|
+
/** @typedef {RouteBase & RouteForbiddenBase} RouteForbidden */
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* @typedef {Object} RouteTimeoutBase
|
|
389
|
+
* @property {'timeout'} type
|
|
390
|
+
*/
|
|
391
|
+
/** @typedef {RouteBase & RouteTimeoutBase} RouteTimeout */
|
|
274
392
|
|
|
275
393
|
/**
|
|
276
394
|
* @typedef {Object} RouteSSEBase
|
|
@@ -301,7 +419,19 @@ export const KNOWN_METHODS = [
|
|
|
301
419
|
RouteNotImplemented |
|
|
302
420
|
RouteUnavailable |
|
|
303
421
|
RoutePartialBytes |
|
|
304
|
-
RouteNotSatisfiable
|
|
422
|
+
RouteNotSatisfiable |
|
|
423
|
+
RouteSeeOther |
|
|
424
|
+
RouteTemporaryRedirect |
|
|
425
|
+
RoutePermanentRedirect |
|
|
426
|
+
RouteMovedPermanently |
|
|
427
|
+
RouteNoContent |
|
|
428
|
+
RouteGone |
|
|
429
|
+
RouteContentTooLarge |
|
|
430
|
+
RouteInsufficientStorage |
|
|
431
|
+
RouteTooManyRequests |
|
|
432
|
+
RouteUnauthorized |
|
|
433
|
+
RouteForbidden |
|
|
434
|
+
RouteTimeout
|
|
305
435
|
} RouteAction */
|
|
306
436
|
|
|
307
437
|
/** @typedef {Record<string, string|undefined>} RouteMatches */
|
|
@@ -311,7 +441,7 @@ export const KNOWN_METHODS = [
|
|
|
311
441
|
* @param {Http2Stream} stream
|
|
312
442
|
* @returns {stream is ServerHttp2Stream}
|
|
313
443
|
*/
|
|
314
|
-
function isServerStream(stream) {
|
|
444
|
+
export function isServerStream(stream) {
|
|
315
445
|
if(stream === null) { return false }
|
|
316
446
|
return true
|
|
317
447
|
}
|
|
@@ -347,19 +477,19 @@ export function isValidMethod(method) {
|
|
|
347
477
|
*/
|
|
348
478
|
export function closeCodeToString(rstCode) {
|
|
349
479
|
if(rstCode === http2.constants.NGHTTP2_NO_ERROR) { return '(No Error)' }
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
480
|
+
if(rstCode === http2.constants.NGHTTP2_PROTOCOL_ERROR) { return '(Protocol Error)' }
|
|
481
|
+
if(rstCode === http2.constants.NGHTTP2_INTERNAL_ERROR) { return '(Internal Error)' }
|
|
482
|
+
if(rstCode === http2.constants.NGHTTP2_FLOW_CONTROL_ERROR) { return '(Flow Control Error)' }
|
|
483
|
+
if(rstCode === http2.constants.NGHTTP2_SETTINGS_TIMEOUT) { return '(Settings Timeout)' }
|
|
484
|
+
if(rstCode === http2.constants.NGHTTP2_STREAM_CLOSED) { return '(Closed)' }
|
|
485
|
+
if(rstCode === http2.constants.NGHTTP2_FRAME_SIZE_ERROR) { return '(Frame Size Error)' }
|
|
486
|
+
if(rstCode === http2.constants.NGHTTP2_REFUSED_STREAM) { return '(Refused)' }
|
|
487
|
+
if(rstCode === http2.constants.NGHTTP2_CANCEL) { return '(Cancel)' }
|
|
488
|
+
if(rstCode === http2.constants.NGHTTP2_COMPRESSION_ERROR) { return '(Compression Error)' }
|
|
489
|
+
if(rstCode === http2.constants.NGHTTP2_CONNECT_ERROR) { return '(Connect Error)' }
|
|
490
|
+
if(rstCode === http2.constants.NGHTTP2_ENHANCE_YOUR_CALM) { return '(Chill)' }
|
|
491
|
+
if(rstCode === http2.constants.NGHTTP2_INADEQUATE_SECURITY) { return '(Inadequate Security)' }
|
|
492
|
+
if(rstCode === http2.constants.NGHTTP2_HTTP_1_1_REQUIRED) { return '(HTTP 1.1 Requested)' }
|
|
363
493
|
|
|
364
494
|
return `(${rstCode})`
|
|
365
495
|
}
|
|
@@ -372,16 +502,10 @@ export const REQUEST_ID_SIZE = 5
|
|
|
372
502
|
export function requestId() {
|
|
373
503
|
const buffer = new Uint8Array(REQUEST_ID_SIZE)
|
|
374
504
|
crypto.getRandomValues(buffer)
|
|
375
|
-
// @ts-
|
|
505
|
+
// @ts-expect-error
|
|
376
506
|
return buffer.toHex()
|
|
377
507
|
}
|
|
378
508
|
|
|
379
|
-
const {
|
|
380
|
-
SSL_OP_NO_TLSv1,
|
|
381
|
-
SSL_OP_NO_TLSv1_1,
|
|
382
|
-
SSL_OP_NO_TLSv1_2,
|
|
383
|
-
} = crypto.constants
|
|
384
|
-
|
|
385
509
|
/**
|
|
386
510
|
* @typedef {Object} H2CoreOptions
|
|
387
511
|
* @property {Config} config
|
package/src/preamble.js
CHANGED
|
@@ -3,24 +3,30 @@ import { TLSSocket } from 'node:tls'
|
|
|
3
3
|
|
|
4
4
|
import { requestBody } from '@johntalton/http-util/body'
|
|
5
5
|
import {
|
|
6
|
-
MIME_TYPE_JSON,
|
|
7
|
-
MIME_TYPE_TEXT,
|
|
8
|
-
MIME_TYPE_XML,
|
|
9
|
-
MIME_TYPE_EVENT_STREAM,
|
|
10
|
-
MIME_TYPE_MESSAGE_HTTP,
|
|
11
|
-
parseContentType,
|
|
12
|
-
|
|
13
6
|
Accept,
|
|
14
7
|
AcceptEncoding,
|
|
15
8
|
AcceptLanguage,
|
|
16
9
|
|
|
17
|
-
|
|
10
|
+
Conditional,
|
|
11
|
+
ETag,
|
|
12
|
+
|
|
18
13
|
FORWARDED_KEY_FOR,
|
|
14
|
+
Forwarded,
|
|
19
15
|
KNOWN_FORWARDED_KEYS,
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
|
|
17
|
+
MIME_TYPE_EVENT_STREAM,
|
|
18
|
+
MIME_TYPE_JSON,
|
|
19
|
+
MIME_TYPE_MESSAGE_HTTP,
|
|
20
|
+
MIME_TYPE_TEXT,
|
|
21
|
+
MIME_TYPE_XML,
|
|
22
|
+
parseContentType
|
|
22
23
|
} from '@johntalton/http-util/headers'
|
|
23
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
ENCODER_MAP,
|
|
26
|
+
HTTP_HEADER_FORWARDED,
|
|
27
|
+
HTTP_HEADER_ORIGIN
|
|
28
|
+
} from '@johntalton/http-util/response'
|
|
29
|
+
|
|
24
30
|
import { isValidHeader, isValidLikeHeader, isValidMethod } from './index.js'
|
|
25
31
|
|
|
26
32
|
/** @import { ServerHttp2Stream, IncomingHttpHeaders } from 'node:http2' */
|
|
@@ -29,8 +35,8 @@ import { isValidHeader, isValidLikeHeader, isValidMethod } from './index.js'
|
|
|
29
35
|
const { HTTP2_METHOD_OPTIONS, HTTP2_METHOD_TRACE } = http2.constants
|
|
30
36
|
|
|
31
37
|
const {
|
|
32
|
-
HTTP2_HEADER_METHOD,
|
|
33
38
|
HTTP2_HEADER_AUTHORITY,
|
|
39
|
+
HTTP2_HEADER_METHOD,
|
|
34
40
|
HTTP2_HEADER_SCHEME,
|
|
35
41
|
HTTP2_HEADER_PATH,
|
|
36
42
|
HTTP2_HEADER_AUTHORIZATION,
|
|
@@ -73,8 +79,10 @@ const ALLOWED_ORIGINS = (process.env['ALLOWED_ORIGINS'] ?? '').split(',').map(s
|
|
|
73
79
|
|
|
74
80
|
const ALLOW_TRACE = process.env['ALLOW_TRACE'] === 'true'
|
|
75
81
|
|
|
76
|
-
const
|
|
77
|
-
const
|
|
82
|
+
const MSEC_PER_SEC = 1000
|
|
83
|
+
const BODY_TIMEOUT_MSEC = 2 * MSEC_PER_SEC
|
|
84
|
+
const BYTE_PER_K = 1024
|
|
85
|
+
const BODY_BYTE_LENGTH = BYTE_PER_K * BYTE_PER_K
|
|
78
86
|
|
|
79
87
|
// const ipRateLimitStore = new Map()
|
|
80
88
|
// const ipRateLimitPolicy = {
|
|
@@ -139,10 +147,8 @@ export function preamble(config, streamId, stream, headers, servername, shutdown
|
|
|
139
147
|
// const secFetchDest = header[HTTP_HEADER_SEC_FETCH_DEST]
|
|
140
148
|
|
|
141
149
|
//
|
|
142
|
-
const allowedOrigin = (origin !== undefined) ?
|
|
143
|
-
|
|
144
|
-
(URL.canParse(origin) ?
|
|
145
|
-
origin : undefined) : undefined) : undefined
|
|
150
|
+
const allowedOrigin = (ALLOWED_ORIGINS.includes('*') || ((origin !== undefined) && URL.canParse(origin) && ALLOWED_ORIGINS.includes(origin))) ? origin : undefined
|
|
151
|
+
|
|
146
152
|
|
|
147
153
|
/** @type {RouteRequest|RouteAction} */
|
|
148
154
|
const state = {
|
|
@@ -249,7 +255,7 @@ export function preamble(config, streamId, stream, headers, servername, shutdown
|
|
|
249
255
|
//
|
|
250
256
|
if(method === HTTP2_METHOD_TRACE) {
|
|
251
257
|
if(!ALLOW_TRACE) { return { ...state, type: 'not-allowed', method, methods: [], url: requestUrl }}
|
|
252
|
-
const maxForwardsValue = maxForwards !== undefined ? parseInt(maxForwards) : 0
|
|
258
|
+
const maxForwardsValue = maxForwards !== undefined ? Number.parseInt(maxForwards) : 0
|
|
253
259
|
const preambleEnd = performance.now()
|
|
254
260
|
state.meta.performance.push({ name: 'preamble-trace', duration: preambleEnd - preambleStart })
|
|
255
261
|
if(acceptObject.type !== MIME_TYPE_MESSAGE_HTTP) { return { ...state, type: 'not-acceptable', acceptableMediaTypes: [ MIME_TYPE_MESSAGE_HTTP ] } }
|
|
@@ -259,14 +265,14 @@ export function preamble(config, streamId, stream, headers, servername, shutdown
|
|
|
259
265
|
//
|
|
260
266
|
// setup future body
|
|
261
267
|
//
|
|
262
|
-
const contentLength = fullContentLength === undefined ? undefined : parseInt(fullContentLength, 10)
|
|
268
|
+
const contentLength = fullContentLength === undefined ? undefined : Number.parseInt(fullContentLength, 10)
|
|
263
269
|
const body = requestBody(stream, {
|
|
264
270
|
byteLimit: BODY_BYTE_LENGTH,
|
|
265
271
|
contentLength,
|
|
266
272
|
contentType,
|
|
267
273
|
signal: AbortSignal.any([
|
|
268
274
|
shutdownSignal,
|
|
269
|
-
AbortSignal.timeout(
|
|
275
|
+
AbortSignal.timeout(BODY_TIMEOUT_MSEC)
|
|
270
276
|
])
|
|
271
277
|
})
|
|
272
278
|
|