@johntalton/http-util 2.0.4 → 2.0.5
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 +1 -1
- package/src/content-type.js +1 -0
- package/src/response/accepted.js +4 -28
- package/src/response/conflict.js +4 -28
- package/src/response/created.js +6 -26
- package/src/response/error.js +6 -36
- package/src/response/header-util.js +42 -0
- package/src/response/index.js +2 -1
- package/src/response/json.js +15 -26
- package/src/response/no-content.js +7 -22
- package/src/response/not-acceptable.js +9 -30
- package/src/response/not-allowed.js +7 -15
- package/src/response/not-found.js +4 -24
- package/src/response/not-modified.js +9 -24
- package/src/response/precondition-failed.js +15 -0
- package/src/response/preflight.js +9 -17
- package/src/response/response.js +6 -4
- package/src/response/send-util.js +39 -0
- package/src/response/sse.js +10 -27
- package/src/response/timeout.js +6 -26
- package/src/response/too-many-requests.js +11 -23
- package/src/response/trace.js +4 -28
- package/src/response/unauthorized.js +5 -18
- package/src/response/unprocessable.js +4 -28
- package/src/response/unsupported-media.js +6 -25
package/package.json
CHANGED
package/src/content-type.js
CHANGED
|
@@ -65,6 +65,7 @@ export const CHARSET = 'charset'
|
|
|
65
65
|
export const PARAMETER_CHARSET_UTF8 = `${CHARSET}${CONTENT_TYPE_SEPARATOR.KVP}${CHARSET_UTF8}`
|
|
66
66
|
export const CONTENT_TYPE_JSON = `${MIME_TYPE_JSON}${CONTENT_TYPE_SEPARATOR.PARAMETER}${PARAMETER_CHARSET_UTF8}`
|
|
67
67
|
export const CONTENT_TYPE_TEXT = `${MIME_TYPE_TEXT}${CONTENT_TYPE_SEPARATOR.PARAMETER}${PARAMETER_CHARSET_UTF8}`
|
|
68
|
+
export const CONTENT_TYPE_MESSAGE_HTTP = `${MIME_TYPE_MESSAGE_HTTP}${CONTENT_TYPE_SEPARATOR.PARAMETER}${PARAMETER_CHARSET_UTF8}`
|
|
68
69
|
|
|
69
70
|
/** @type {ContentType} */
|
|
70
71
|
export const WELL_KNOWN_JSON = {
|
package/src/response/accepted.js
CHANGED
|
@@ -1,39 +1,15 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
5
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
6
|
-
ServerTiming
|
|
7
|
-
} from '../server-timing.js'
|
|
2
|
+
import { send } from './send-util.js'
|
|
8
3
|
|
|
9
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
5
|
/** @import { Metadata } from './defs.js' */
|
|
11
6
|
|
|
12
|
-
const {
|
|
13
|
-
HTTP_STATUS_ACCEPTED
|
|
14
|
-
} = http2.constants
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
HTTP2_HEADER_STATUS,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN
|
|
20
|
-
} = http2.constants
|
|
7
|
+
const { HTTP_STATUS_ACCEPTED } = http2.constants
|
|
21
8
|
|
|
22
9
|
/**
|
|
23
10
|
* @param {ServerHttp2Stream} stream
|
|
24
11
|
* @param {Metadata} meta
|
|
25
12
|
*/
|
|
26
13
|
export function sendAccepted(stream, meta) {
|
|
27
|
-
stream
|
|
28
|
-
|
|
29
|
-
[HTTP2_HEADER_STATUS]: HTTP_STATUS_ACCEPTED,
|
|
30
|
-
// [HTTP2_HEADER_CONTENT_TYPE]: CONTENT_TYPE_JSON,
|
|
31
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
32
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
33
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
// stream.write(JSON.stringify( ... ))
|
|
37
|
-
|
|
38
|
-
stream.end()
|
|
39
|
-
}
|
|
14
|
+
send(stream, HTTP_STATUS_ACCEPTED, {}, undefined, undefined, meta)
|
|
15
|
+
}
|
package/src/response/conflict.js
CHANGED
|
@@ -1,39 +1,15 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
5
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
6
|
-
ServerTiming
|
|
7
|
-
} from '../server-timing.js'
|
|
2
|
+
import { send } from './send-util.js'
|
|
8
3
|
|
|
9
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
5
|
/** @import { Metadata } from './defs.js' */
|
|
11
6
|
|
|
12
|
-
const {
|
|
13
|
-
HTTP_STATUS_CONFLICT
|
|
14
|
-
} = http2.constants
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
HTTP2_HEADER_STATUS,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN
|
|
20
|
-
} = http2.constants
|
|
7
|
+
const { HTTP_STATUS_CONFLICT } = http2.constants
|
|
21
8
|
|
|
22
9
|
/**
|
|
23
10
|
* @param {ServerHttp2Stream} stream
|
|
24
11
|
* @param {Metadata} meta
|
|
25
12
|
*/
|
|
26
13
|
export function sendConflict(stream, meta) {
|
|
27
|
-
stream
|
|
28
|
-
|
|
29
|
-
[HTTP2_HEADER_STATUS]: HTTP_STATUS_CONFLICT,
|
|
30
|
-
// [HTTP2_HEADER_CONTENT_TYPE]: CONTENT_TYPE_JSON,
|
|
31
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
32
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
33
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
// stream.write(JSON.stringify( ... ))
|
|
37
|
-
|
|
38
|
-
stream.end()
|
|
39
|
-
}
|
|
14
|
+
send(stream, HTTP_STATUS_CONFLICT, {}, undefined, undefined, meta)
|
|
15
|
+
}
|
package/src/response/created.js
CHANGED
|
@@ -1,42 +1,22 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
5
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
6
|
-
ServerTiming
|
|
7
|
-
} from '../server-timing.js'
|
|
2
|
+
import { send } from './send-util.js'
|
|
8
3
|
|
|
9
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
5
|
/** @import { Metadata } from './defs.js' */
|
|
11
6
|
|
|
12
7
|
const {
|
|
13
|
-
HTTP_STATUS_CREATED
|
|
14
|
-
} = http2.constants
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
HTTP2_HEADER_STATUS,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
20
8
|
HTTP2_HEADER_LOCATION
|
|
21
9
|
} = http2.constants
|
|
22
10
|
|
|
11
|
+
const { HTTP_STATUS_CREATED } = http2.constants
|
|
12
|
+
|
|
23
13
|
/**
|
|
24
14
|
* @param {ServerHttp2Stream} stream
|
|
25
15
|
* @param {URL} location
|
|
26
16
|
* @param {Metadata} meta
|
|
27
17
|
*/
|
|
28
18
|
export function sendCreated(stream, location, meta) {
|
|
29
|
-
stream
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// [HTTP2_HEADER_CONTENT_TYPE]: CONTENT_TYPE_JSON,
|
|
33
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
34
|
-
[HTTP2_HEADER_LOCATION]: location.href,
|
|
35
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
36
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
// stream.write(JSON.stringify( ... ))
|
|
40
|
-
|
|
41
|
-
stream.end()
|
|
19
|
+
send(stream, HTTP_STATUS_CREATED, {
|
|
20
|
+
[HTTP2_HEADER_LOCATION]: location.href
|
|
21
|
+
}, undefined, undefined, meta)
|
|
42
22
|
}
|
package/src/response/error.js
CHANGED
|
@@ -1,47 +1,17 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from '../content-type.js'
|
|
5
|
-
|
|
6
|
-
const {
|
|
7
|
-
HTTP2_HEADER_STATUS,
|
|
8
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
9
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
10
|
-
HTTP2_HEADER_SERVER
|
|
11
|
-
} = http2.constants
|
|
12
|
-
|
|
13
|
-
const {
|
|
14
|
-
HTTP_STATUS_INTERNAL_SERVER_ERROR
|
|
15
|
-
} = http2.constants
|
|
2
|
+
import { CONTENT_TYPE_TEXT } from '../content-type.js'
|
|
3
|
+
import { send } from './send-util.js'
|
|
16
4
|
|
|
17
5
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
18
6
|
/** @import { Metadata } from './defs.js' */
|
|
19
7
|
|
|
8
|
+
const { HTTP_STATUS_INTERNAL_SERVER_ERROR } = http2.constants
|
|
9
|
+
|
|
20
10
|
/**
|
|
21
11
|
* @param {ServerHttp2Stream} stream
|
|
22
12
|
* @param {string} message
|
|
23
13
|
* @param {Metadata} meta
|
|
24
14
|
*/
|
|
25
15
|
export function sendError(stream, message, meta) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if(stream === undefined) { return }
|
|
29
|
-
if(stream.closed) { return }
|
|
30
|
-
|
|
31
|
-
if(!stream.headersSent) {
|
|
32
|
-
stream.respond({
|
|
33
|
-
[HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN]: meta.origin,
|
|
34
|
-
[HTTP2_HEADER_STATUS]: HTTP_STATUS_INTERNAL_SERVER_ERROR,
|
|
35
|
-
[HTTP2_HEADER_CONTENT_TYPE]: CONTENT_TYPE_TEXT,
|
|
36
|
-
[HTTP2_HEADER_SERVER]: meta.servername
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// protect against HEAD calls
|
|
41
|
-
if(stream.writable) {
|
|
42
|
-
if(message !== undefined) { stream.write(message) }
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
stream.end()
|
|
46
|
-
if(!stream.closed) { stream.close() }
|
|
47
|
-
}
|
|
16
|
+
send(stream, HTTP_STATUS_INTERNAL_SERVER_ERROR, {}, CONTENT_TYPE_TEXT, message, meta)
|
|
17
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import http2 from 'node:http2'
|
|
2
|
+
import {
|
|
3
|
+
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
4
|
+
HTTP_HEADER_SERVER_TIMING,
|
|
5
|
+
ServerTiming
|
|
6
|
+
} from '../server-timing.js'
|
|
7
|
+
|
|
8
|
+
/** @import { OutgoingHttpHeaders } from 'node:http2' */
|
|
9
|
+
/** @import { Metadata } from './defs.js' */
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
HTTP2_HEADER_STATUS,
|
|
13
|
+
HTTP2_HEADER_SERVER,
|
|
14
|
+
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
15
|
+
HTTP2_HEADER_CONTENT_TYPE
|
|
16
|
+
} = http2.constants
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {number} status
|
|
20
|
+
* @param {string|undefined} contentType
|
|
21
|
+
* @param {Metadata} meta
|
|
22
|
+
* @returns {OutgoingHttpHeaders}
|
|
23
|
+
*/
|
|
24
|
+
export function coreHeaders(status, contentType, meta) {
|
|
25
|
+
return {
|
|
26
|
+
[HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN]: meta.origin,
|
|
27
|
+
[HTTP2_HEADER_STATUS]: status,
|
|
28
|
+
[HTTP2_HEADER_CONTENT_TYPE]: contentType,
|
|
29
|
+
[HTTP2_HEADER_SERVER]: meta.servername
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {Metadata} meta
|
|
35
|
+
* @returns {OutgoingHttpHeaders}
|
|
36
|
+
*/
|
|
37
|
+
export function performanceHeaders(meta) {
|
|
38
|
+
return {
|
|
39
|
+
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
40
|
+
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance)
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/response/index.js
CHANGED
|
@@ -10,11 +10,12 @@ export * from './not-acceptable.js'
|
|
|
10
10
|
export * from './not-allowed.js'
|
|
11
11
|
export * from './not-found.js'
|
|
12
12
|
export * from './not-modified.js'
|
|
13
|
+
export * from './precondition-failed.js'
|
|
13
14
|
export * from './preflight.js'
|
|
14
15
|
export * from './sse.js'
|
|
15
16
|
export * from './timeout.js'
|
|
16
17
|
export * from './too-many-requests.js'
|
|
17
18
|
export * from './trace.js'
|
|
18
19
|
export * from './unauthorized.js'
|
|
19
|
-
export * from './unsupported-media.js'
|
|
20
20
|
export * from './unprocessable.js'
|
|
21
|
+
export * from './unsupported-media.js'
|
package/src/response/json.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
brotliCompressSync,
|
|
4
|
+
deflateSync,
|
|
5
|
+
gzipSync,
|
|
6
|
+
zstdCompressSync
|
|
7
|
+
} from 'node:zlib'
|
|
4
8
|
import {
|
|
5
9
|
CHARSET_UTF8,
|
|
6
10
|
CONTENT_TYPE_JSON
|
|
7
11
|
} from '../content-type.js'
|
|
12
|
+
import { send } from './send-util.js'
|
|
8
13
|
|
|
9
14
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
15
|
/** @import { Metadata } from './defs.js' */
|
|
@@ -12,19 +17,13 @@ import {
|
|
|
12
17
|
/** @typedef { (data: string, charset: BufferEncoding) => Buffer } EncoderFun */
|
|
13
18
|
|
|
14
19
|
const {
|
|
15
|
-
HTTP2_HEADER_STATUS,
|
|
16
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
17
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
20
|
HTTP2_HEADER_CONTENT_ENCODING,
|
|
20
21
|
HTTP2_HEADER_VARY,
|
|
21
22
|
HTTP2_HEADER_CACHE_CONTROL,
|
|
22
23
|
HTTP2_HEADER_ETAG
|
|
23
24
|
} = http2.constants
|
|
24
25
|
|
|
25
|
-
const {
|
|
26
|
-
HTTP_STATUS_OK
|
|
27
|
-
} = http2.constants
|
|
26
|
+
const { HTTP_STATUS_OK } = http2.constants
|
|
28
27
|
|
|
29
28
|
/** @type {Map<string, EncoderFun>} */
|
|
30
29
|
export const ENCODER_MAP = new Map([
|
|
@@ -58,21 +57,11 @@ export function sendJSON_Encoded(stream, obj, encoding, meta) {
|
|
|
58
57
|
{ name: 'encode', duration: encodeEnd - encodeStart }
|
|
59
58
|
)
|
|
60
59
|
|
|
61
|
-
stream
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
69
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
70
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
71
|
-
[HTTP2_HEADER_ETAG]: `"${meta.etag}"`
|
|
72
|
-
// [HTTP2_HEADER_AGE]: age
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
// stream.write(encodedData)
|
|
76
|
-
stream.end(encodedData)
|
|
60
|
+
send(stream, HTTP_STATUS_OK, {
|
|
61
|
+
[HTTP2_HEADER_CONTENT_ENCODING]: actualEncoding,
|
|
62
|
+
[HTTP2_HEADER_VARY]: 'Accept, Accept-Encoding',
|
|
63
|
+
[HTTP2_HEADER_CACHE_CONTROL]: 'private',
|
|
64
|
+
[HTTP2_HEADER_ETAG]: `"${meta.etag}"`
|
|
65
|
+
// [HTTP2_HEADER_AGE]: age
|
|
66
|
+
}, CONTENT_TYPE_JSON, encodedData, meta)
|
|
77
67
|
}
|
|
78
|
-
|
|
@@ -1,36 +1,21 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
4
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
5
|
-
ServerTiming
|
|
6
|
-
} from '../server-timing.js'
|
|
2
|
+
import { send } from './send-util.js'
|
|
7
3
|
|
|
8
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
9
5
|
/** @import { Metadata } from './defs.js' */
|
|
10
6
|
|
|
11
7
|
const {
|
|
12
|
-
HTTP_STATUS_NO_CONTENT
|
|
13
|
-
} = http2.constants
|
|
14
|
-
|
|
15
|
-
const {
|
|
16
|
-
HTTP2_HEADER_STATUS,
|
|
17
|
-
HTTP2_HEADER_SERVER,
|
|
18
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
19
8
|
HTTP2_HEADER_ETAG
|
|
20
9
|
} = http2.constants
|
|
21
10
|
|
|
11
|
+
const { HTTP_STATUS_NO_CONTENT } = http2.constants
|
|
12
|
+
|
|
22
13
|
/**
|
|
23
14
|
* @param {ServerHttp2Stream} stream
|
|
24
15
|
* @param {Metadata} meta
|
|
25
16
|
*/
|
|
26
17
|
export function sendNoContent(stream, meta) {
|
|
27
|
-
stream
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
32
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
33
|
-
[HTTP2_HEADER_ETAG]: `"${meta.etag}"`
|
|
34
|
-
})
|
|
35
|
-
stream.end()
|
|
36
|
-
}
|
|
18
|
+
send(stream, HTTP_STATUS_NO_CONTENT, {
|
|
19
|
+
[HTTP2_HEADER_ETAG]: `"${meta.etag}"`
|
|
20
|
+
}, undefined, undefined, meta)
|
|
21
|
+
}
|
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
5
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
6
|
-
ServerTiming
|
|
7
|
-
} from '../server-timing.js'
|
|
2
|
+
import { CONTENT_TYPE_JSON } from '../content-type.js'
|
|
3
|
+
import { send } from './send-util.js'
|
|
8
4
|
|
|
9
5
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
6
|
/** @import { Metadata } from './defs.js' */
|
|
11
7
|
|
|
12
|
-
const {
|
|
13
|
-
HTTP_STATUS_NOT_ACCEPTABLE
|
|
14
|
-
} = http2.constants
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
HTTP2_HEADER_STATUS,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
20
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN
|
|
21
|
-
} = http2.constants
|
|
8
|
+
const { HTTP_STATUS_NOT_ACCEPTABLE } = http2.constants
|
|
22
9
|
|
|
23
10
|
/**
|
|
24
11
|
* @param {ServerHttp2Stream} stream
|
|
@@ -29,18 +16,10 @@ export function sendNotAcceptable(stream, supportedTypes, meta) {
|
|
|
29
16
|
const supportedTypesList = Array.isArray(supportedTypes) ? supportedTypes : [ supportedTypes ]
|
|
30
17
|
const has = supportedTypesList.length !== 0
|
|
31
18
|
|
|
32
|
-
stream
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
if(has) {
|
|
42
|
-
stream.write(JSON.stringify(supportedTypes))
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
stream.end()
|
|
19
|
+
send(stream,
|
|
20
|
+
HTTP_STATUS_NOT_ACCEPTABLE,
|
|
21
|
+
{},
|
|
22
|
+
has ? CONTENT_TYPE_JSON : undefined,
|
|
23
|
+
has ? JSON.stringify(supportedTypes) : undefined,
|
|
24
|
+
meta)
|
|
46
25
|
}
|
|
@@ -1,30 +1,22 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
+
import { send } from './send-util.js'
|
|
2
3
|
|
|
3
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
4
5
|
/** @import { Metadata } from './defs.js' */
|
|
5
6
|
|
|
6
|
-
const {
|
|
7
|
-
HTTP2_HEADER_STATUS,
|
|
8
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
9
|
-
HTTP2_HEADER_SERVER,
|
|
10
|
-
HTTP2_HEADER_ALLOW
|
|
11
|
-
} = http2.constants
|
|
12
|
-
|
|
13
7
|
const {
|
|
14
8
|
HTTP_STATUS_METHOD_NOT_ALLOWED
|
|
15
9
|
} = http2.constants
|
|
16
10
|
|
|
11
|
+
const { HTTP2_HEADER_ALLOW } = http2.constants
|
|
12
|
+
|
|
17
13
|
/**
|
|
18
14
|
* @param {ServerHttp2Stream} stream
|
|
19
15
|
* @param {Array<string>} methods
|
|
20
16
|
* @param {Metadata} meta
|
|
21
17
|
*/
|
|
22
18
|
export function sendNotAllowed(stream, methods, meta) {
|
|
23
|
-
stream
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
[HTTP2_HEADER_SERVER]: meta.servername
|
|
28
|
-
})
|
|
29
|
-
stream.end()
|
|
30
|
-
}
|
|
19
|
+
send(stream, HTTP_STATUS_METHOD_NOT_ALLOWED, {
|
|
20
|
+
[HTTP2_HEADER_ALLOW]: methods.join(',')
|
|
21
|
+
}, undefined, undefined, meta)
|
|
22
|
+
}
|
|
@@ -1,21 +1,11 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from '../content-type.js'
|
|
2
|
+
import { CONTENT_TYPE_TEXT } from '../content-type.js'
|
|
3
|
+
import { send } from './send-util.js'
|
|
5
4
|
|
|
6
5
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
7
6
|
/** @import { Metadata } from './defs.js' */
|
|
8
7
|
|
|
9
|
-
const {
|
|
10
|
-
HTTP2_HEADER_STATUS,
|
|
11
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
12
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
13
|
-
HTTP2_HEADER_SERVER
|
|
14
|
-
} = http2.constants
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
HTTP_STATUS_NOT_FOUND
|
|
18
|
-
} = http2.constants
|
|
8
|
+
const { HTTP_STATUS_NOT_FOUND } = http2.constants
|
|
19
9
|
|
|
20
10
|
/**
|
|
21
11
|
* @param {ServerHttp2Stream} stream
|
|
@@ -23,15 +13,5 @@ const {
|
|
|
23
13
|
* @param {Metadata} meta
|
|
24
14
|
*/
|
|
25
15
|
export function sendNotFound(stream, message, meta) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
stream.respond({
|
|
29
|
-
[HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN]: meta.origin,
|
|
30
|
-
[HTTP2_HEADER_STATUS]: HTTP_STATUS_NOT_FOUND,
|
|
31
|
-
[HTTP2_HEADER_CONTENT_TYPE]: CONTENT_TYPE_TEXT,
|
|
32
|
-
[HTTP2_HEADER_SERVER]: meta.servername
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
if(message !== undefined) { stream.write(message) }
|
|
36
|
-
stream.end()
|
|
16
|
+
send(stream, HTTP_STATUS_NOT_FOUND, {}, CONTENT_TYPE_TEXT, message, meta)
|
|
37
17
|
}
|
|
@@ -1,43 +1,28 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
4
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
5
|
-
ServerTiming
|
|
6
|
-
} from '../server-timing.js'
|
|
2
|
+
import { send } from './send-util.js'
|
|
7
3
|
|
|
8
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
9
5
|
/** @import { Metadata } from './defs.js' */
|
|
10
6
|
|
|
11
7
|
const {
|
|
12
|
-
HTTP_STATUS_NOT_MODIFIED
|
|
13
|
-
} = http2.constants
|
|
14
|
-
|
|
15
|
-
const {
|
|
16
|
-
HTTP2_HEADER_STATUS,
|
|
17
|
-
HTTP2_HEADER_SERVER,
|
|
18
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
19
8
|
HTTP2_HEADER_AGE,
|
|
20
9
|
HTTP2_HEADER_ETAG,
|
|
21
10
|
HTTP2_HEADER_VARY,
|
|
22
11
|
HTTP2_HEADER_CACHE_CONTROL
|
|
23
12
|
} = http2.constants
|
|
24
13
|
|
|
14
|
+
const { HTTP_STATUS_NOT_MODIFIED } = http2.constants
|
|
15
|
+
|
|
25
16
|
/**
|
|
26
17
|
* @param {ServerHttp2Stream} stream
|
|
27
18
|
* @param {number} age
|
|
28
19
|
* @param {Metadata} meta
|
|
29
20
|
*/
|
|
30
21
|
export function sendNotModified(stream, age, meta) {
|
|
31
|
-
stream
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
38
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
39
|
-
[HTTP2_HEADER_ETAG]: `"${meta.etag}"`,
|
|
40
|
-
[HTTP2_HEADER_AGE]: age
|
|
41
|
-
})
|
|
42
|
-
stream.end()
|
|
22
|
+
send(stream, HTTP_STATUS_NOT_MODIFIED, {
|
|
23
|
+
[HTTP2_HEADER_VARY]: 'Accept, Accept-Encoding',
|
|
24
|
+
[HTTP2_HEADER_CACHE_CONTROL]: 'private',
|
|
25
|
+
[HTTP2_HEADER_ETAG]: `"${meta.etag}"`,
|
|
26
|
+
[HTTP2_HEADER_AGE]: `${age}`
|
|
27
|
+
}, undefined, undefined, meta)
|
|
43
28
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import http2 from 'node:http2'
|
|
2
|
+
import { send } from './send-util.js'
|
|
3
|
+
|
|
4
|
+
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
5
|
+
/** @import { Metadata } from './defs.js' */
|
|
6
|
+
|
|
7
|
+
const { HTTP_STATUS_PRECONDITION_FAILED } = http2.constants
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {ServerHttp2Stream} stream
|
|
11
|
+
* @param {Metadata} meta
|
|
12
|
+
*/
|
|
13
|
+
export function sendPreconditionFailed(stream, meta) {
|
|
14
|
+
send(stream, HTTP_STATUS_PRECONDITION_FAILED, {}, undefined, undefined, meta)
|
|
15
|
+
}
|
|
@@ -3,22 +3,18 @@ import {
|
|
|
3
3
|
HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE,
|
|
4
4
|
PREFLIGHT_AGE_SECONDS
|
|
5
5
|
} from './defs.js'
|
|
6
|
+
import { send } from './send-util.js'
|
|
6
7
|
|
|
7
8
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
8
9
|
/** @import { Metadata } from './defs.js' */
|
|
9
10
|
|
|
10
11
|
const {
|
|
11
|
-
HTTP2_HEADER_STATUS,
|
|
12
12
|
HTTP2_HEADER_CONTENT_TYPE,
|
|
13
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
14
13
|
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_METHODS,
|
|
15
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS
|
|
16
|
-
HTTP2_HEADER_SERVER
|
|
14
|
+
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS
|
|
17
15
|
} = http2.constants
|
|
18
16
|
|
|
19
|
-
const {
|
|
20
|
-
HTTP_STATUS_OK
|
|
21
|
-
} = http2.constants
|
|
17
|
+
const { HTTP_STATUS_OK } = http2.constants
|
|
22
18
|
|
|
23
19
|
/**
|
|
24
20
|
* @param {ServerHttp2Stream} stream
|
|
@@ -26,13 +22,9 @@ const {
|
|
|
26
22
|
* @param {Metadata} meta
|
|
27
23
|
*/
|
|
28
24
|
export function sendPreflight(stream, methods, meta) {
|
|
29
|
-
stream
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
[HTTP2_HEADER_SERVER]: meta.servername
|
|
36
|
-
})
|
|
37
|
-
stream.end()
|
|
38
|
-
}
|
|
25
|
+
send(stream, HTTP_STATUS_OK, {
|
|
26
|
+
[HTTP2_HEADER_ACCESS_CONTROL_ALLOW_METHODS]: methods.join(','),
|
|
27
|
+
[HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS]: ['Authorization', HTTP2_HEADER_CONTENT_TYPE].join(','),
|
|
28
|
+
[HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE]: PREFLIGHT_AGE_SECONDS
|
|
29
|
+
}, undefined, undefined, meta)
|
|
30
|
+
}
|
package/src/response/response.js
CHANGED
|
@@ -8,32 +8,34 @@ import { sendNotAcceptable } from './not-acceptable.js'
|
|
|
8
8
|
import { sendNotAllowed } from './not-allowed.js'
|
|
9
9
|
import { sendNotFound } from './not-found.js'
|
|
10
10
|
import { sendNotModified } from './not-modified.js'
|
|
11
|
+
import { sendPreconditionFailed } from './precondition-failed.js'
|
|
11
12
|
import { sendPreflight } from './preflight.js'
|
|
12
13
|
import { sendSSE } from './sse.js'
|
|
13
14
|
import { sendTimeout } from './timeout.js'
|
|
14
15
|
import { sendTooManyRequests } from './too-many-requests.js'
|
|
15
16
|
import { sendTrace } from './trace.js'
|
|
16
17
|
import { sendUnauthorized } from './unauthorized.js'
|
|
17
|
-
import { sendUnsupportedMediaType } from './unsupported-media.js'
|
|
18
18
|
import { sendUnprocessable } from './unprocessable.js'
|
|
19
|
+
import { sendUnsupportedMediaType } from './unsupported-media.js'
|
|
19
20
|
|
|
20
21
|
export const Response = {
|
|
21
22
|
accepted: sendAccepted,
|
|
22
23
|
conflict: sendConflict,
|
|
23
24
|
created: sendCreated,
|
|
24
25
|
error: sendError,
|
|
25
|
-
noContent: sendNoContent,
|
|
26
26
|
json: sendJSON_Encoded,
|
|
27
|
+
noContent: sendNoContent,
|
|
27
28
|
notAcceptable: sendNotAcceptable,
|
|
28
29
|
notAllowed: sendNotAllowed,
|
|
29
30
|
notFound: sendNotFound,
|
|
30
31
|
notModified: sendNotModified,
|
|
32
|
+
preconditionFailed: sendPreconditionFailed,
|
|
31
33
|
preflight: sendPreflight,
|
|
32
34
|
sse: sendSSE,
|
|
33
35
|
timeout: sendTimeout,
|
|
34
36
|
tooManyRequests: sendTooManyRequests,
|
|
35
37
|
trace: sendTrace,
|
|
36
38
|
unauthorized: sendUnauthorized,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
unprocessable: sendUnprocessable,
|
|
40
|
+
unsupportedMediaType: sendUnsupportedMediaType
|
|
39
41
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { coreHeaders, performanceHeaders } from './header-util.js'
|
|
2
|
+
|
|
3
|
+
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
4
|
+
/** @import { IncomingHttpHeaders } from 'node:http2' */
|
|
5
|
+
/** @import { Metadata } from './defs.js' */
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {ServerHttp2Stream} stream
|
|
9
|
+
* @param {number} status
|
|
10
|
+
* @param {IncomingHttpHeaders} headers
|
|
11
|
+
* @param {string|undefined} contentType
|
|
12
|
+
* @param {ArrayBufferLike|ArrayBufferView|string|undefined} body
|
|
13
|
+
* @param {Metadata} meta
|
|
14
|
+
*/
|
|
15
|
+
export function send(stream, status, headers, contentType, body, meta) {
|
|
16
|
+
// if(status >= 400) { console.warn(status, body) }
|
|
17
|
+
if(status === 401) { console.warn(status, body) }
|
|
18
|
+
if(status === 404) { console.warn(status, body) }
|
|
19
|
+
if(status === 500) { console.warn(status, body) }
|
|
20
|
+
|
|
21
|
+
if(stream === undefined) { return }
|
|
22
|
+
if(stream.closed) { return }
|
|
23
|
+
|
|
24
|
+
if(!stream.headersSent) {
|
|
25
|
+
stream.respond({
|
|
26
|
+
...coreHeaders(status, contentType, meta),
|
|
27
|
+
...performanceHeaders(meta),
|
|
28
|
+
...headers
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if(stream.writable && body !== undefined) {
|
|
33
|
+
stream.end(body)
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
stream.end()
|
|
38
|
+
// if(!stream.closed) { stream.close() }
|
|
39
|
+
}
|
package/src/response/sse.js
CHANGED
|
@@ -5,51 +5,34 @@ import {
|
|
|
5
5
|
SSE_BOM,
|
|
6
6
|
ENDING,
|
|
7
7
|
} from '@johntalton/sse-util'
|
|
8
|
+
import { coreHeaders, performanceHeaders } from './header-util.js'
|
|
8
9
|
|
|
9
10
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
11
|
/** @import { Metadata, SSEOptions } from './defs.js' */
|
|
11
12
|
|
|
12
|
-
const {
|
|
13
|
-
HTTP2_HEADER_STATUS,
|
|
14
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
15
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
16
|
-
HTTP2_HEADER_SERVER
|
|
17
|
-
} = http2.constants
|
|
18
|
-
|
|
19
|
-
const {
|
|
20
|
-
HTTP_STATUS_OK,
|
|
21
|
-
HTTP_STATUS_NO_CONTENT
|
|
22
|
-
} = http2.constants
|
|
13
|
+
const { HTTP_STATUS_OK } = http2.constants
|
|
23
14
|
|
|
24
15
|
/**
|
|
25
16
|
* @param {ServerHttp2Stream} stream
|
|
26
17
|
* @param {SSEOptions & Metadata} meta
|
|
27
18
|
*/
|
|
28
19
|
export function sendSSE(stream, meta) {
|
|
29
|
-
// stream.setTimeout(0)
|
|
30
|
-
// stream.session?.setTimeout(0)
|
|
31
|
-
// stream.session?.socket.setTimeout(0)
|
|
32
|
-
// stream.session.socket.setNoDelay(true)
|
|
33
|
-
// stream.session.socket.setKeepAlive(true)
|
|
34
|
-
|
|
35
|
-
// stream.on('close', () => console.log('SSE stream closed'))
|
|
36
|
-
// stream.on('aborted', () => console.log('SSE stream aborted'))
|
|
37
|
-
|
|
38
20
|
const activeStream = meta.active ?? true
|
|
39
21
|
const sendBOM = meta.bom ?? true
|
|
40
22
|
|
|
23
|
+
const status = activeStream ? HTTP_STATUS_OK : SSE_INACTIVE_STATUS_CODE
|
|
24
|
+
|
|
41
25
|
stream.respond({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
26
|
+
...coreHeaders(status, SSE_MIME, meta),
|
|
27
|
+
...performanceHeaders(meta)
|
|
28
|
+
|
|
45
29
|
// [HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS]: 'true'
|
|
46
|
-
|
|
47
|
-
})
|
|
30
|
+
})
|
|
48
31
|
|
|
49
|
-
|
|
32
|
+
if(!activeStream) {
|
|
50
33
|
stream.end()
|
|
51
34
|
return
|
|
52
|
-
|
|
35
|
+
}
|
|
53
36
|
|
|
54
37
|
if(sendBOM) {
|
|
55
38
|
stream.write(SSE_BOM + ENDING.CRLF)
|
package/src/response/timeout.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
5
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
6
|
-
ServerTiming
|
|
7
|
-
} from '../server-timing.js'
|
|
2
|
+
import { send } from './send-util.js'
|
|
8
3
|
|
|
9
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
5
|
/** @import { Metadata } from './defs.js' */
|
|
@@ -13,29 +8,14 @@ const {
|
|
|
13
8
|
HTTP_STATUS_REQUEST_TIMEOUT
|
|
14
9
|
} = http2.constants
|
|
15
10
|
|
|
16
|
-
const {
|
|
17
|
-
HTTP2_HEADER_STATUS,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
20
|
-
HTTP2_HEADER_CONNECTION
|
|
21
|
-
} = http2.constants
|
|
11
|
+
const { HTTP2_HEADER_CONNECTION } = http2.constants
|
|
22
12
|
|
|
23
13
|
/**
|
|
24
14
|
* @param {ServerHttp2Stream} stream
|
|
25
15
|
* @param {Metadata} meta
|
|
26
16
|
*/
|
|
27
17
|
export function sendTimeout(stream, meta) {
|
|
28
|
-
stream
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
33
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
34
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
35
|
-
[HTTP2_HEADER_CONNECTION]: 'close'
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
// stream.write(JSON.stringify( ... ))
|
|
39
|
-
|
|
40
|
-
stream.end()
|
|
41
|
-
}
|
|
18
|
+
send(stream, HTTP_STATUS_REQUEST_TIMEOUT, {
|
|
19
|
+
[HTTP2_HEADER_CONNECTION]: 'close'
|
|
20
|
+
}, undefined, undefined, meta)
|
|
21
|
+
}
|
|
@@ -6,22 +6,16 @@ import {
|
|
|
6
6
|
RateLimit,
|
|
7
7
|
RateLimitPolicy
|
|
8
8
|
} from '../rate-limit.js'
|
|
9
|
-
|
|
9
|
+
import { send } from './send-util.js'
|
|
10
10
|
|
|
11
11
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
12
12
|
/** @import { Metadata } from './defs.js' */
|
|
13
13
|
|
|
14
14
|
const {
|
|
15
|
-
|
|
16
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
17
|
-
HTTP2_HEADER_SERVER,
|
|
18
|
-
HTTP2_HEADER_RETRY_AFTER,
|
|
19
|
-
HTTP2_HEADER_CONTENT_TYPE
|
|
15
|
+
HTTP2_HEADER_RETRY_AFTER
|
|
20
16
|
} = http2.constants
|
|
21
17
|
|
|
22
|
-
const {
|
|
23
|
-
HTTP_STATUS_TOO_MANY_REQUESTS
|
|
24
|
-
} = http2.constants
|
|
18
|
+
const { HTTP_STATUS_TOO_MANY_REQUESTS } = http2.constants
|
|
25
19
|
|
|
26
20
|
/**
|
|
27
21
|
* @param {ServerHttp2Stream} stream
|
|
@@ -30,18 +24,12 @@ const {
|
|
|
30
24
|
* @param {Metadata} meta
|
|
31
25
|
*/
|
|
32
26
|
export function sendTooManyRequests(stream, limitInfo, policies, meta) {
|
|
33
|
-
stream
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
stream.write(`Retry After ${limitInfo.retryAfterS} Seconds`)
|
|
44
|
-
|
|
45
|
-
stream.end()
|
|
27
|
+
send(stream, HTTP_STATUS_TOO_MANY_REQUESTS, {
|
|
28
|
+
[HTTP2_HEADER_RETRY_AFTER]: limitInfo.retryAfterS,
|
|
29
|
+
[HTTP_HEADER_RATE_LIMIT]: RateLimit.from(limitInfo),
|
|
30
|
+
[HTTP_HEADER_RATE_LIMIT_POLICY]: RateLimitPolicy.from(...policies)
|
|
31
|
+
},
|
|
32
|
+
CONTENT_TYPE_TEXT,
|
|
33
|
+
`Retry After ${limitInfo.retryAfterS} Seconds`,
|
|
34
|
+
meta)
|
|
46
35
|
}
|
|
47
|
-
|
package/src/response/trace.js
CHANGED
|
@@ -1,26 +1,12 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from '../content-type.js'
|
|
5
|
-
import {
|
|
6
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
7
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
8
|
-
ServerTiming
|
|
9
|
-
} from '../server-timing.js'
|
|
2
|
+
import { CONTENT_TYPE_MESSAGE_HTTP } from '../content-type.js'
|
|
3
|
+
import { send } from './send-util.js'
|
|
10
4
|
|
|
11
5
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
12
6
|
/** @import { IncomingHttpHeaders } from 'node:http2' */
|
|
13
7
|
/** @import { Metadata } from './defs.js' */
|
|
14
8
|
|
|
15
|
-
const {
|
|
16
|
-
HTTP2_HEADER_STATUS,
|
|
17
|
-
HTTP2_HEADER_CONTENT_TYPE,
|
|
18
|
-
HTTP2_HEADER_SERVER
|
|
19
|
-
} = http2.constants
|
|
20
|
-
|
|
21
|
-
const {
|
|
22
|
-
HTTP_STATUS_OK
|
|
23
|
-
} = http2.constants
|
|
9
|
+
const { HTTP_STATUS_OK } = http2.constants
|
|
24
10
|
|
|
25
11
|
/**
|
|
26
12
|
* @param {ServerHttp2Stream} stream
|
|
@@ -38,15 +24,6 @@ export function sendTrace(stream, method, url, headers, meta) {
|
|
|
38
24
|
])
|
|
39
25
|
|
|
40
26
|
const version = HTTP_VERSION.get(stream.session?.alpnProtocol ?? 'h2')
|
|
41
|
-
|
|
42
|
-
stream.respond({
|
|
43
|
-
[HTTP2_HEADER_CONTENT_TYPE]: MIME_TYPE_MESSAGE_HTTP,
|
|
44
|
-
[HTTP2_HEADER_STATUS]: HTTP_STATUS_OK,
|
|
45
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
46
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
47
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
48
|
-
})
|
|
49
|
-
|
|
50
27
|
const reconstructed = [
|
|
51
28
|
`${method} ${url.pathname}${url.search} ${version}`,
|
|
52
29
|
Object.entries(headers)
|
|
@@ -58,6 +35,5 @@ export function sendTrace(stream, method, url, headers, meta) {
|
|
|
58
35
|
]
|
|
59
36
|
.join('\n')
|
|
60
37
|
|
|
61
|
-
stream
|
|
38
|
+
send(stream, HTTP_STATUS_OK, {}, CONTENT_TYPE_MESSAGE_HTTP, reconstructed, meta)
|
|
62
39
|
}
|
|
63
|
-
|
|
@@ -1,30 +1,17 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
+
import { send } from './send-util.js'
|
|
2
3
|
|
|
3
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
4
5
|
/** @import { Metadata } from './defs.js' */
|
|
5
6
|
|
|
6
|
-
const {
|
|
7
|
-
HTTP2_HEADER_STATUS,
|
|
8
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
9
|
-
HTTP2_HEADER_SERVER
|
|
10
|
-
} = http2.constants
|
|
11
|
-
|
|
12
|
-
const {
|
|
13
|
-
HTTP_STATUS_UNAUTHORIZED
|
|
14
|
-
} = http2.constants
|
|
7
|
+
const { HTTP_STATUS_UNAUTHORIZED } = http2.constants
|
|
15
8
|
|
|
16
9
|
/**
|
|
17
10
|
* @param {ServerHttp2Stream} stream
|
|
18
11
|
* @param {Metadata} meta
|
|
19
12
|
*/
|
|
20
13
|
export function sendUnauthorized(stream, meta) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
[HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN]: meta.origin,
|
|
25
|
-
[HTTP2_HEADER_STATUS]: HTTP_STATUS_UNAUTHORIZED,
|
|
26
|
-
[HTTP2_HEADER_SERVER]: meta.servername
|
|
27
|
-
// WWW-Authenticate
|
|
28
|
-
})
|
|
29
|
-
stream.end()
|
|
14
|
+
send(stream, HTTP_STATUS_UNAUTHORIZED, {
|
|
15
|
+
// WWW-Authenticate
|
|
16
|
+
}, undefined, undefined, meta)
|
|
30
17
|
}
|
|
@@ -1,39 +1,15 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
5
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
6
|
-
ServerTiming
|
|
7
|
-
} from '../server-timing.js'
|
|
2
|
+
import { send } from './send-util.js'
|
|
8
3
|
|
|
9
4
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
5
|
/** @import { Metadata } from './defs.js' */
|
|
11
6
|
|
|
12
|
-
const {
|
|
13
|
-
HTTP_STATUS_UNPROCESSABLE_ENTITY
|
|
14
|
-
} = http2.constants
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
HTTP2_HEADER_STATUS,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN
|
|
20
|
-
} = http2.constants
|
|
7
|
+
const { HTTP_STATUS_UNPROCESSABLE_ENTITY } = http2.constants
|
|
21
8
|
|
|
22
9
|
/**
|
|
23
10
|
* @param {ServerHttp2Stream} stream
|
|
24
11
|
* @param {Metadata} meta
|
|
25
12
|
*/
|
|
26
13
|
export function sendUnprocessable(stream, meta) {
|
|
27
|
-
stream
|
|
28
|
-
|
|
29
|
-
[HTTP2_HEADER_STATUS]: HTTP_STATUS_UNPROCESSABLE_ENTITY,
|
|
30
|
-
// [HTTP2_HEADER_CONTENT_TYPE]: CONTENT_TYPE_JSON,
|
|
31
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
32
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
33
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
// stream.write(JSON.stringify( ... ))
|
|
37
|
-
|
|
38
|
-
stream.end()
|
|
39
|
-
}
|
|
14
|
+
send(stream, HTTP_STATUS_UNPROCESSABLE_ENTITY, {}, undefined, undefined, meta)
|
|
15
|
+
}
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
import http2 from 'node:http2'
|
|
2
2
|
import { HTTP_HEADER_ACCEPT_POST } from './defs.js'
|
|
3
|
-
import {
|
|
4
|
-
HTTP_HEADER_TIMING_ALLOW_ORIGIN,
|
|
5
|
-
HTTP_HEADER_SERVER_TIMING,
|
|
6
|
-
ServerTiming
|
|
7
|
-
} from '../server-timing.js'
|
|
3
|
+
import { send } from './send-util.js'
|
|
8
4
|
|
|
9
5
|
/** @import { ServerHttp2Stream } from 'node:http2' */
|
|
10
6
|
/** @import { Metadata } from './defs.js' */
|
|
11
7
|
|
|
12
|
-
const {
|
|
13
|
-
HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE
|
|
14
|
-
} = http2.constants
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
HTTP2_HEADER_STATUS,
|
|
18
|
-
HTTP2_HEADER_SERVER,
|
|
19
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN
|
|
20
|
-
} = http2.constants
|
|
8
|
+
const { HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE } = http2.constants
|
|
21
9
|
|
|
22
10
|
/**
|
|
23
11
|
* @param {ServerHttp2Stream} stream
|
|
@@ -27,14 +15,7 @@ const {
|
|
|
27
15
|
export function sendUnsupportedMediaType(stream, acceptableMediaType, meta) {
|
|
28
16
|
const acceptable = Array.isArray(acceptableMediaType) ? acceptableMediaType : [ acceptableMediaType ]
|
|
29
17
|
|
|
30
|
-
stream
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
[HTTP2_HEADER_SERVER]: meta.servername,
|
|
35
|
-
[HTTP_HEADER_TIMING_ALLOW_ORIGIN]: meta.origin,
|
|
36
|
-
[HTTP_HEADER_SERVER_TIMING]: ServerTiming.encode(meta.performance),
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
stream.end()
|
|
40
|
-
}
|
|
18
|
+
send(stream, HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, {
|
|
19
|
+
[HTTP_HEADER_ACCEPT_POST]: acceptable.join(',')
|
|
20
|
+
}, undefined, undefined, meta)
|
|
21
|
+
}
|