undici 7.14.0 → 7.15.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.
- package/docs/docs/api/Dispatcher.md +59 -0
- package/index.js +2 -1
- package/lib/core/util.js +13 -1
- package/lib/dispatcher/agent.js +25 -16
- package/lib/dispatcher/client-h1.js +1 -1
- package/lib/interceptor/decompress.js +253 -0
- package/lib/llhttp/constants.d.ts +99 -1
- package/lib/llhttp/constants.js +34 -1
- package/lib/llhttp/llhttp-wasm.js +1 -1
- package/lib/llhttp/llhttp_simd-wasm.js +1 -1
- package/lib/llhttp/utils.d.ts +2 -2
- package/lib/llhttp/utils.js +3 -6
- package/lib/util/cache.js +6 -7
- package/lib/web/cookies/parse.js +2 -2
- package/lib/web/fetch/body.js +4 -4
- package/lib/web/fetch/index.js +1 -1
- package/lib/web/fetch/util.js +0 -216
- package/lib/web/subresource-integrity/Readme.md +9 -0
- package/lib/web/subresource-integrity/subresource-integrity.js +306 -0
- package/package.json +4 -3
- package/types/diagnostics-channel.d.ts +0 -1
- package/types/interceptors.d.ts +5 -0
- package/types/snapshot-agent.d.ts +5 -3
- package/lib/api/util.js +0 -95
- package/lib/llhttp/constants.js.map +0 -1
- package/lib/llhttp/utils.js.map +0 -1
|
@@ -1094,6 +1094,65 @@ await client.request({
|
|
|
1094
1094
|
});
|
|
1095
1095
|
```
|
|
1096
1096
|
|
|
1097
|
+
##### `decompress`
|
|
1098
|
+
|
|
1099
|
+
⚠️ The decompress interceptor is experimental and subject to change.
|
|
1100
|
+
|
|
1101
|
+
The `decompress` interceptor automatically decompresses response bodies that are compressed with gzip, deflate, brotli, or zstd compression. It removes the `content-encoding` and `content-length` headers from decompressed responses and supports RFC-9110 compliant multiple encodings.
|
|
1102
|
+
|
|
1103
|
+
**Options**
|
|
1104
|
+
|
|
1105
|
+
- `skipErrorResponses` - Whether to skip decompression for error responses (status codes >= 400). Default: `true`.
|
|
1106
|
+
- `skipStatusCodes` - Array of status codes to skip decompression for. Default: `[204, 304]`.
|
|
1107
|
+
|
|
1108
|
+
**Example - Basic Decompress Interceptor**
|
|
1109
|
+
|
|
1110
|
+
```js
|
|
1111
|
+
const { Client, interceptors } = require("undici");
|
|
1112
|
+
const { decompress } = interceptors;
|
|
1113
|
+
|
|
1114
|
+
const client = new Client("http://example.com").compose(
|
|
1115
|
+
decompress()
|
|
1116
|
+
);
|
|
1117
|
+
|
|
1118
|
+
// Automatically decompresses gzip/deflate/brotli/zstd responses
|
|
1119
|
+
const response = await client.request({
|
|
1120
|
+
method: "GET",
|
|
1121
|
+
path: "/"
|
|
1122
|
+
});
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
**Example - Custom Options**
|
|
1126
|
+
|
|
1127
|
+
```js
|
|
1128
|
+
const { Client, interceptors } = require("undici");
|
|
1129
|
+
const { decompress } = interceptors;
|
|
1130
|
+
|
|
1131
|
+
const client = new Client("http://example.com").compose(
|
|
1132
|
+
decompress({
|
|
1133
|
+
skipErrorResponses: false, // Decompress 5xx responses
|
|
1134
|
+
skipStatusCodes: [204, 304, 201] // Skip these status codes
|
|
1135
|
+
})
|
|
1136
|
+
);
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
**Supported Encodings**
|
|
1140
|
+
|
|
1141
|
+
- `gzip` / `x-gzip` - GZIP compression
|
|
1142
|
+
- `deflate` / `x-compress` - DEFLATE compression
|
|
1143
|
+
- `br` - Brotli compression
|
|
1144
|
+
- `zstd` - Zstandard compression
|
|
1145
|
+
- Multiple encodings (e.g., `gzip, deflate`) are supported per RFC-9110
|
|
1146
|
+
|
|
1147
|
+
**Behavior**
|
|
1148
|
+
|
|
1149
|
+
- Skips decompression for status codes < 200 or >= 400 (configurable)
|
|
1150
|
+
- Skips decompression for 204 No Content and 304 Not Modified by default
|
|
1151
|
+
- Removes `content-encoding` and `content-length` headers when decompressing
|
|
1152
|
+
- Passes through unsupported encodings unchanged
|
|
1153
|
+
- Handles case-insensitive encoding names
|
|
1154
|
+
- Supports streaming decompression without buffering
|
|
1155
|
+
|
|
1097
1156
|
##### `Cache Interceptor`
|
|
1098
1157
|
|
|
1099
1158
|
The `cache` interceptor implements client-side response caching as described in
|
package/index.js
CHANGED
|
@@ -46,7 +46,8 @@ module.exports.interceptors = {
|
|
|
46
46
|
retry: require('./lib/interceptor/retry'),
|
|
47
47
|
dump: require('./lib/interceptor/dump'),
|
|
48
48
|
dns: require('./lib/interceptor/dns'),
|
|
49
|
-
cache: require('./lib/interceptor/cache')
|
|
49
|
+
cache: require('./lib/interceptor/cache'),
|
|
50
|
+
decompress: require('./lib/interceptor/decompress')
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
module.exports.cacheStores = {
|
package/lib/core/util.js
CHANGED
|
@@ -102,13 +102,24 @@ function isBlobLike (object) {
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* @param {string} url The path to check for query strings or fragments.
|
|
107
|
+
* @returns {boolean} Returns true if the path contains a query string or fragment.
|
|
108
|
+
*/
|
|
109
|
+
function pathHasQueryOrFragment (url) {
|
|
110
|
+
return (
|
|
111
|
+
url.includes('?') ||
|
|
112
|
+
url.includes('#')
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
|
|
105
116
|
/**
|
|
106
117
|
* @param {string} url The URL to add the query params to
|
|
107
118
|
* @param {import('node:querystring').ParsedUrlQueryInput} queryParams The object to serialize into a URL query string
|
|
108
119
|
* @returns {string} The URL with the query params added
|
|
109
120
|
*/
|
|
110
121
|
function serializePathWithQuery (url, queryParams) {
|
|
111
|
-
if (
|
|
122
|
+
if (pathHasQueryOrFragment(url)) {
|
|
112
123
|
throw new Error('Query params cannot be passed when url already contains "?" or "#".')
|
|
113
124
|
}
|
|
114
125
|
|
|
@@ -924,6 +935,7 @@ module.exports = {
|
|
|
924
935
|
assertRequestHandler,
|
|
925
936
|
getSocketInfo,
|
|
926
937
|
isFormDataLike,
|
|
938
|
+
pathHasQueryOrFragment,
|
|
927
939
|
serializePathWithQuery,
|
|
928
940
|
addAbortListener,
|
|
929
941
|
isValidHTTPToken,
|
package/lib/dispatcher/agent.js
CHANGED
|
@@ -45,27 +45,14 @@ class Agent extends DispatcherBase {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
this[kOnConnect] = (origin, targets) => {
|
|
48
|
-
const result = this[kClients].get(origin)
|
|
49
|
-
if (result) {
|
|
50
|
-
result.count += 1
|
|
51
|
-
}
|
|
52
48
|
this.emit('connect', origin, [this, ...targets])
|
|
53
49
|
}
|
|
54
50
|
|
|
55
51
|
this[kOnDisconnect] = (origin, targets, err) => {
|
|
56
|
-
const result = this[kClients].get(origin)
|
|
57
|
-
if (result) {
|
|
58
|
-
result.count -= 1
|
|
59
|
-
if (result.count <= 0) {
|
|
60
|
-
this[kClients].delete(origin)
|
|
61
|
-
result.dispatcher.destroy()
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
52
|
this.emit('disconnect', origin, [this, ...targets], err)
|
|
65
53
|
}
|
|
66
54
|
|
|
67
55
|
this[kOnConnectionError] = (origin, targets, err) => {
|
|
68
|
-
// TODO: should this decrement result.count here?
|
|
69
56
|
this.emit('connectionError', origin, [this, ...targets], err)
|
|
70
57
|
}
|
|
71
58
|
}
|
|
@@ -89,11 +76,33 @@ class Agent extends DispatcherBase {
|
|
|
89
76
|
const result = this[kClients].get(key)
|
|
90
77
|
let dispatcher = result && result.dispatcher
|
|
91
78
|
if (!dispatcher) {
|
|
79
|
+
const closeClientIfUnused = (connected) => {
|
|
80
|
+
const result = this[kClients].get(key)
|
|
81
|
+
if (result) {
|
|
82
|
+
if (connected) result.count -= 1
|
|
83
|
+
if (result.count <= 0) {
|
|
84
|
+
this[kClients].delete(key)
|
|
85
|
+
result.dispatcher.close()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
92
89
|
dispatcher = this[kFactory](opts.origin, this[kOptions])
|
|
93
90
|
.on('drain', this[kOnDrain])
|
|
94
|
-
.on('connect',
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
.on('connect', (origin, targets) => {
|
|
92
|
+
const result = this[kClients].get(key)
|
|
93
|
+
if (result) {
|
|
94
|
+
result.count += 1
|
|
95
|
+
}
|
|
96
|
+
this[kOnConnect](origin, targets)
|
|
97
|
+
})
|
|
98
|
+
.on('disconnect', (origin, targets, err) => {
|
|
99
|
+
closeClientIfUnused(true)
|
|
100
|
+
this[kOnDisconnect](origin, targets, err)
|
|
101
|
+
})
|
|
102
|
+
.on('connectionError', (origin, targets, err) => {
|
|
103
|
+
closeClientIfUnused(false)
|
|
104
|
+
this[kOnConnectionError](origin, targets, err)
|
|
105
|
+
})
|
|
97
106
|
|
|
98
107
|
this[kClients].set(key, { count: 0, dispatcher })
|
|
99
108
|
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { createInflate, createGunzip, createBrotliDecompress, createZstdDecompress } = require('node:zlib')
|
|
4
|
+
const { pipeline } = require('node:stream')
|
|
5
|
+
const DecoratorHandler = require('../handler/decorator-handler')
|
|
6
|
+
|
|
7
|
+
/** @typedef {import('node:stream').Transform} Transform */
|
|
8
|
+
/** @typedef {import('node:stream').Transform} Controller */
|
|
9
|
+
/** @typedef {Transform&import('node:zlib').Zlib} DecompressorStream */
|
|
10
|
+
|
|
11
|
+
/** @type {Record<string, () => DecompressorStream>} */
|
|
12
|
+
const supportedEncodings = {
|
|
13
|
+
gzip: createGunzip,
|
|
14
|
+
'x-gzip': createGunzip,
|
|
15
|
+
br: createBrotliDecompress,
|
|
16
|
+
deflate: createInflate,
|
|
17
|
+
compress: createInflate,
|
|
18
|
+
'x-compress': createInflate,
|
|
19
|
+
...(createZstdDecompress ? { zstd: createZstdDecompress } : {})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const defaultSkipStatusCodes = /** @type {const} */ ([204, 304])
|
|
23
|
+
|
|
24
|
+
let warningEmitted = /** @type {boolean} */ (false)
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {Object} DecompressHandlerOptions
|
|
28
|
+
* @property {number[]|Readonly<number[]>} [skipStatusCodes=[204, 304]] - List of status codes to skip decompression for
|
|
29
|
+
* @property {boolean} [skipErrorResponses] - Whether to skip decompression for error responses (status codes >= 400)
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
class DecompressHandler extends DecoratorHandler {
|
|
33
|
+
/** @type {Transform[]} */
|
|
34
|
+
#decompressors = []
|
|
35
|
+
/** @type {NodeJS.WritableStream&NodeJS.ReadableStream|null} */
|
|
36
|
+
#pipelineStream
|
|
37
|
+
/** @type {Readonly<number[]>} */
|
|
38
|
+
#skipStatusCodes
|
|
39
|
+
/** @type {boolean} */
|
|
40
|
+
#skipErrorResponses
|
|
41
|
+
|
|
42
|
+
constructor (handler, { skipStatusCodes = defaultSkipStatusCodes, skipErrorResponses = true } = {}) {
|
|
43
|
+
super(handler)
|
|
44
|
+
this.#skipStatusCodes = skipStatusCodes
|
|
45
|
+
this.#skipErrorResponses = skipErrorResponses
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Determines if decompression should be skipped based on encoding and status code
|
|
50
|
+
* @param {string} contentEncoding - Content-Encoding header value
|
|
51
|
+
* @param {number} statusCode - HTTP status code of the response
|
|
52
|
+
* @returns {boolean} - True if decompression should be skipped
|
|
53
|
+
*/
|
|
54
|
+
#shouldSkipDecompression (contentEncoding, statusCode) {
|
|
55
|
+
if (!contentEncoding || statusCode < 200) return true
|
|
56
|
+
if (this.#skipStatusCodes.includes(statusCode)) return true
|
|
57
|
+
if (this.#skipErrorResponses && statusCode >= 400) return true
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates a chain of decompressors for multiple content encodings
|
|
63
|
+
*
|
|
64
|
+
* @param {string} encodings - Comma-separated list of content encodings
|
|
65
|
+
* @returns {Array<DecompressorStream>} - Array of decompressor streams
|
|
66
|
+
*/
|
|
67
|
+
#createDecompressionChain (encodings) {
|
|
68
|
+
const parts = encodings.split(',')
|
|
69
|
+
|
|
70
|
+
/** @type {DecompressorStream[]} */
|
|
71
|
+
const decompressors = []
|
|
72
|
+
|
|
73
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
74
|
+
const encoding = parts[i].trim()
|
|
75
|
+
if (!encoding) continue
|
|
76
|
+
|
|
77
|
+
if (!supportedEncodings[encoding]) {
|
|
78
|
+
decompressors.length = 0 // Clear if unsupported encoding
|
|
79
|
+
return decompressors // Unsupported encoding
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
decompressors.push(supportedEncodings[encoding]())
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return decompressors
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Sets up event handlers for a decompressor stream using readable events
|
|
90
|
+
* @param {DecompressorStream} decompressor - The decompressor stream
|
|
91
|
+
* @param {Controller} controller - The controller to coordinate with
|
|
92
|
+
* @returns {void}
|
|
93
|
+
*/
|
|
94
|
+
#setupDecompressorEvents (decompressor, controller) {
|
|
95
|
+
decompressor.on('readable', () => {
|
|
96
|
+
let chunk
|
|
97
|
+
while ((chunk = decompressor.read()) !== null) {
|
|
98
|
+
const result = super.onResponseData(controller, chunk)
|
|
99
|
+
if (result === false) {
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
decompressor.on('error', (error) => {
|
|
106
|
+
super.onResponseError(controller, error)
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Sets up event handling for a single decompressor
|
|
112
|
+
* @param {Controller} controller - The controller to handle events
|
|
113
|
+
* @returns {void}
|
|
114
|
+
*/
|
|
115
|
+
#setupSingleDecompressor (controller) {
|
|
116
|
+
const decompressor = this.#decompressors[0]
|
|
117
|
+
this.#setupDecompressorEvents(decompressor, controller)
|
|
118
|
+
|
|
119
|
+
decompressor.on('end', () => {
|
|
120
|
+
super.onResponseEnd(controller, {})
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Sets up event handling for multiple chained decompressors using pipeline
|
|
126
|
+
* @param {Controller} controller - The controller to handle events
|
|
127
|
+
* @returns {void}
|
|
128
|
+
*/
|
|
129
|
+
#setupMultipleDecompressors (controller) {
|
|
130
|
+
const lastDecompressor = this.#decompressors[this.#decompressors.length - 1]
|
|
131
|
+
this.#setupDecompressorEvents(lastDecompressor, controller)
|
|
132
|
+
|
|
133
|
+
this.#pipelineStream = pipeline(this.#decompressors, (err) => {
|
|
134
|
+
if (err) {
|
|
135
|
+
super.onResponseError(controller, err)
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
super.onResponseEnd(controller, {})
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Cleans up decompressor references to prevent memory leaks
|
|
144
|
+
* @returns {void}
|
|
145
|
+
*/
|
|
146
|
+
#cleanupDecompressors () {
|
|
147
|
+
this.#decompressors.length = 0
|
|
148
|
+
this.#pipelineStream = null
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @param {Controller} controller
|
|
153
|
+
* @param {number} statusCode
|
|
154
|
+
* @param {Record<string, string | string[] | undefined>} headers
|
|
155
|
+
* @param {string} statusMessage
|
|
156
|
+
* @returns {void}
|
|
157
|
+
*/
|
|
158
|
+
onResponseStart (controller, statusCode, headers, statusMessage) {
|
|
159
|
+
const contentEncoding = headers['content-encoding']
|
|
160
|
+
|
|
161
|
+
// If content encoding is not supported or status code is in skip list
|
|
162
|
+
if (this.#shouldSkipDecompression(contentEncoding, statusCode)) {
|
|
163
|
+
return super.onResponseStart(controller, statusCode, headers, statusMessage)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const decompressors = this.#createDecompressionChain(contentEncoding.toLowerCase())
|
|
167
|
+
|
|
168
|
+
if (decompressors.length === 0) {
|
|
169
|
+
this.#cleanupDecompressors()
|
|
170
|
+
return super.onResponseStart(controller, statusCode, headers, statusMessage)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this.#decompressors = decompressors
|
|
174
|
+
|
|
175
|
+
// Remove compression headers since we're decompressing
|
|
176
|
+
const { 'content-encoding': _, 'content-length': __, ...newHeaders } = headers
|
|
177
|
+
|
|
178
|
+
if (this.#decompressors.length === 1) {
|
|
179
|
+
this.#setupSingleDecompressor(controller)
|
|
180
|
+
} else {
|
|
181
|
+
this.#setupMultipleDecompressors(controller)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
super.onResponseStart(controller, statusCode, newHeaders, statusMessage)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @param {Controller} controller
|
|
189
|
+
* @param {Buffer} chunk
|
|
190
|
+
* @returns {void}
|
|
191
|
+
*/
|
|
192
|
+
onResponseData (controller, chunk) {
|
|
193
|
+
if (this.#decompressors.length > 0) {
|
|
194
|
+
this.#decompressors[0].write(chunk)
|
|
195
|
+
return
|
|
196
|
+
}
|
|
197
|
+
super.onResponseData(controller, chunk)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @param {Controller} controller
|
|
202
|
+
* @param {Record<string, string | string[]> | undefined} trailers
|
|
203
|
+
* @returns {void}
|
|
204
|
+
*/
|
|
205
|
+
onResponseEnd (controller, trailers) {
|
|
206
|
+
if (this.#decompressors.length > 0) {
|
|
207
|
+
this.#decompressors[0].end()
|
|
208
|
+
this.#cleanupDecompressors()
|
|
209
|
+
return
|
|
210
|
+
}
|
|
211
|
+
super.onResponseEnd(controller, trailers)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param {Controller} controller
|
|
216
|
+
* @param {Error} err
|
|
217
|
+
* @returns {void}
|
|
218
|
+
*/
|
|
219
|
+
onResponseError (controller, err) {
|
|
220
|
+
if (this.#decompressors.length > 0) {
|
|
221
|
+
for (const decompressor of this.#decompressors) {
|
|
222
|
+
decompressor.destroy(err)
|
|
223
|
+
}
|
|
224
|
+
this.#cleanupDecompressors()
|
|
225
|
+
}
|
|
226
|
+
super.onResponseError(controller, err)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Creates a decompression interceptor for HTTP responses
|
|
232
|
+
* @param {DecompressHandlerOptions} [options] - Options for the interceptor
|
|
233
|
+
* @returns {Function} - Interceptor function
|
|
234
|
+
*/
|
|
235
|
+
function createDecompressInterceptor (options = {}) {
|
|
236
|
+
// Emit experimental warning only once
|
|
237
|
+
if (!warningEmitted) {
|
|
238
|
+
process.emitWarning(
|
|
239
|
+
'DecompressInterceptor is experimental and subject to change',
|
|
240
|
+
'ExperimentalWarning'
|
|
241
|
+
)
|
|
242
|
+
warningEmitted = true
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return (dispatch) => {
|
|
246
|
+
return (opts, handler) => {
|
|
247
|
+
const decompressHandler = new DecompressHandler(handler, options)
|
|
248
|
+
return dispatch(opts, decompressHandler)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
module.exports = createDecompressInterceptor
|
|
@@ -15,7 +15,7 @@ export declare const H_METHOD_MAP: {
|
|
|
15
15
|
[k: string]: number;
|
|
16
16
|
};
|
|
17
17
|
export declare const STATUSES_HTTP: number[];
|
|
18
|
-
export type CharList =
|
|
18
|
+
export type CharList = (string | number)[];
|
|
19
19
|
export declare const ALPHA: CharList;
|
|
20
20
|
export declare const NUM_MAP: {
|
|
21
21
|
0: number;
|
|
@@ -95,3 +95,101 @@ export declare const SPECIAL_HEADERS: {
|
|
|
95
95
|
'transfer-encoding': number;
|
|
96
96
|
upgrade: number;
|
|
97
97
|
};
|
|
98
|
+
declare const _default: {
|
|
99
|
+
ERROR: IntDict;
|
|
100
|
+
TYPE: IntDict;
|
|
101
|
+
FLAGS: IntDict;
|
|
102
|
+
LENIENT_FLAGS: IntDict;
|
|
103
|
+
METHODS: IntDict;
|
|
104
|
+
STATUSES: IntDict;
|
|
105
|
+
FINISH: IntDict;
|
|
106
|
+
HEADER_STATE: IntDict;
|
|
107
|
+
ALPHA: CharList;
|
|
108
|
+
NUM_MAP: {
|
|
109
|
+
0: number;
|
|
110
|
+
1: number;
|
|
111
|
+
2: number;
|
|
112
|
+
3: number;
|
|
113
|
+
4: number;
|
|
114
|
+
5: number;
|
|
115
|
+
6: number;
|
|
116
|
+
7: number;
|
|
117
|
+
8: number;
|
|
118
|
+
9: number;
|
|
119
|
+
};
|
|
120
|
+
HEX_MAP: {
|
|
121
|
+
0: number;
|
|
122
|
+
1: number;
|
|
123
|
+
2: number;
|
|
124
|
+
3: number;
|
|
125
|
+
4: number;
|
|
126
|
+
5: number;
|
|
127
|
+
6: number;
|
|
128
|
+
7: number;
|
|
129
|
+
8: number;
|
|
130
|
+
9: number;
|
|
131
|
+
A: number;
|
|
132
|
+
B: number;
|
|
133
|
+
C: number;
|
|
134
|
+
D: number;
|
|
135
|
+
E: number;
|
|
136
|
+
F: number;
|
|
137
|
+
a: number;
|
|
138
|
+
b: number;
|
|
139
|
+
c: number;
|
|
140
|
+
d: number;
|
|
141
|
+
e: number;
|
|
142
|
+
f: number;
|
|
143
|
+
};
|
|
144
|
+
NUM: CharList;
|
|
145
|
+
ALPHANUM: CharList;
|
|
146
|
+
MARK: CharList;
|
|
147
|
+
USERINFO_CHARS: CharList;
|
|
148
|
+
URL_CHAR: CharList;
|
|
149
|
+
HEX: CharList;
|
|
150
|
+
TOKEN: CharList;
|
|
151
|
+
HEADER_CHARS: CharList;
|
|
152
|
+
CONNECTION_TOKEN_CHARS: CharList;
|
|
153
|
+
QUOTED_STRING: CharList;
|
|
154
|
+
HTAB_SP_VCHAR_OBS_TEXT: CharList;
|
|
155
|
+
MAJOR: {
|
|
156
|
+
0: number;
|
|
157
|
+
1: number;
|
|
158
|
+
2: number;
|
|
159
|
+
3: number;
|
|
160
|
+
4: number;
|
|
161
|
+
5: number;
|
|
162
|
+
6: number;
|
|
163
|
+
7: number;
|
|
164
|
+
8: number;
|
|
165
|
+
9: number;
|
|
166
|
+
};
|
|
167
|
+
MINOR: {
|
|
168
|
+
0: number;
|
|
169
|
+
1: number;
|
|
170
|
+
2: number;
|
|
171
|
+
3: number;
|
|
172
|
+
4: number;
|
|
173
|
+
5: number;
|
|
174
|
+
6: number;
|
|
175
|
+
7: number;
|
|
176
|
+
8: number;
|
|
177
|
+
9: number;
|
|
178
|
+
};
|
|
179
|
+
SPECIAL_HEADERS: {
|
|
180
|
+
connection: number;
|
|
181
|
+
'content-length': number;
|
|
182
|
+
'proxy-connection': number;
|
|
183
|
+
'transfer-encoding': number;
|
|
184
|
+
upgrade: number;
|
|
185
|
+
};
|
|
186
|
+
METHODS_HTTP: number[];
|
|
187
|
+
METHODS_ICE: number[];
|
|
188
|
+
METHODS_RTSP: number[];
|
|
189
|
+
METHOD_MAP: IntDict;
|
|
190
|
+
H_METHOD_MAP: {
|
|
191
|
+
[k: string]: number;
|
|
192
|
+
};
|
|
193
|
+
STATUSES_HTTP: number[];
|
|
194
|
+
};
|
|
195
|
+
export default _default;
|
package/lib/llhttp/constants.js
CHANGED
|
@@ -40,6 +40,7 @@ exports.ERROR = {
|
|
|
40
40
|
CB_CHUNK_EXTENSION_NAME_COMPLETE: 34,
|
|
41
41
|
CB_CHUNK_EXTENSION_VALUE_COMPLETE: 35,
|
|
42
42
|
CB_RESET: 31,
|
|
43
|
+
CB_PROTOCOL_COMPLETE: 38,
|
|
43
44
|
};
|
|
44
45
|
exports.TYPE = {
|
|
45
46
|
BOTH: 0, // default
|
|
@@ -495,4 +496,36 @@ exports.SPECIAL_HEADERS = {
|
|
|
495
496
|
'transfer-encoding': exports.HEADER_STATE.TRANSFER_ENCODING,
|
|
496
497
|
'upgrade': exports.HEADER_STATE.UPGRADE,
|
|
497
498
|
};
|
|
498
|
-
|
|
499
|
+
exports.default = {
|
|
500
|
+
ERROR: exports.ERROR,
|
|
501
|
+
TYPE: exports.TYPE,
|
|
502
|
+
FLAGS: exports.FLAGS,
|
|
503
|
+
LENIENT_FLAGS: exports.LENIENT_FLAGS,
|
|
504
|
+
METHODS: exports.METHODS,
|
|
505
|
+
STATUSES: exports.STATUSES,
|
|
506
|
+
FINISH: exports.FINISH,
|
|
507
|
+
HEADER_STATE: exports.HEADER_STATE,
|
|
508
|
+
ALPHA: exports.ALPHA,
|
|
509
|
+
NUM_MAP: exports.NUM_MAP,
|
|
510
|
+
HEX_MAP: exports.HEX_MAP,
|
|
511
|
+
NUM: exports.NUM,
|
|
512
|
+
ALPHANUM: exports.ALPHANUM,
|
|
513
|
+
MARK: exports.MARK,
|
|
514
|
+
USERINFO_CHARS: exports.USERINFO_CHARS,
|
|
515
|
+
URL_CHAR: exports.URL_CHAR,
|
|
516
|
+
HEX: exports.HEX,
|
|
517
|
+
TOKEN: exports.TOKEN,
|
|
518
|
+
HEADER_CHARS: exports.HEADER_CHARS,
|
|
519
|
+
CONNECTION_TOKEN_CHARS: exports.CONNECTION_TOKEN_CHARS,
|
|
520
|
+
QUOTED_STRING: exports.QUOTED_STRING,
|
|
521
|
+
HTAB_SP_VCHAR_OBS_TEXT: exports.HTAB_SP_VCHAR_OBS_TEXT,
|
|
522
|
+
MAJOR: exports.MAJOR,
|
|
523
|
+
MINOR: exports.MINOR,
|
|
524
|
+
SPECIAL_HEADERS: exports.SPECIAL_HEADERS,
|
|
525
|
+
METHODS_HTTP: exports.METHODS_HTTP,
|
|
526
|
+
METHODS_ICE: exports.METHODS_ICE,
|
|
527
|
+
METHODS_RTSP: exports.METHODS_RTSP,
|
|
528
|
+
METHOD_MAP: exports.METHOD_MAP,
|
|
529
|
+
H_METHOD_MAP: exports.H_METHOD_MAP,
|
|
530
|
+
STATUSES_HTTP: exports.STATUSES_HTTP,
|
|
531
|
+
};
|