@gjsify/http2 0.1.15 → 0.2.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/lib/esm/client-session.js +280 -0
- package/lib/esm/index.js +62 -543
- package/lib/esm/protocol.js +317 -0
- package/lib/esm/server.js +620 -0
- package/lib/types/client-session.d.ts +100 -0
- package/lib/types/http2.gjs.spec.d.ts +2 -0
- package/lib/types/index.d.ts +14 -366
- package/lib/types/protocol.d.ts +265 -0
- package/lib/types/server.d.ts +186 -0
- package/package.json +11 -6
- package/src/client-session.ts +352 -0
- package/src/http2.gjs.spec.ts +303 -0
- package/src/index.ts +85 -592
- package/src/protocol.ts +347 -0
- package/src/server.ts +754 -0
- package/src/test.mts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/index.ts
CHANGED
|
@@ -1,615 +1,107 @@
|
|
|
1
|
-
// Reference: Node.js lib/http2.js, lib/internal/http2/core.js, lib/internal/http2/
|
|
2
|
-
// Reimplemented for GJS
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
NGHTTP2_CONNECT_ERROR: 0x0a,
|
|
21
|
-
NGHTTP2_ENHANCE_YOUR_CALM: 0x0b,
|
|
22
|
-
NGHTTP2_INADEQUATE_SECURITY: 0x0c,
|
|
23
|
-
NGHTTP2_HTTP_1_1_REQUIRED: 0x0d,
|
|
24
|
-
NGHTTP2_ERR_FRAME_SIZE_ERROR: -522,
|
|
25
|
-
NGHTTP2_ERR_DEFERRED: -508,
|
|
26
|
-
NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE: -509,
|
|
27
|
-
NGHTTP2_ERR_INVALID_ARGUMENT: -501,
|
|
28
|
-
NGHTTP2_ERR_STREAM_CLOSED: -510,
|
|
29
|
-
NGHTTP2_ERR_NOMEM: -901,
|
|
30
|
-
NGHTTP2_SESSION_SERVER: 0,
|
|
31
|
-
NGHTTP2_SESSION_CLIENT: 1,
|
|
32
|
-
|
|
33
|
-
NGHTTP2_STREAM_STATE_IDLE: 1,
|
|
34
|
-
NGHTTP2_STREAM_STATE_OPEN: 2,
|
|
35
|
-
NGHTTP2_STREAM_STATE_RESERVED_LOCAL: 3,
|
|
36
|
-
NGHTTP2_STREAM_STATE_RESERVED_REMOTE: 4,
|
|
37
|
-
NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL: 5,
|
|
38
|
-
NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE: 6,
|
|
39
|
-
NGHTTP2_STREAM_STATE_CLOSED: 7,
|
|
40
|
-
|
|
41
|
-
NGHTTP2_FLAG_NONE: 0,
|
|
42
|
-
NGHTTP2_FLAG_END_STREAM: 0x01,
|
|
43
|
-
NGHTTP2_FLAG_END_HEADERS: 0x04,
|
|
44
|
-
NGHTTP2_FLAG_ACK: 0x01,
|
|
45
|
-
NGHTTP2_FLAG_PADDED: 0x08,
|
|
46
|
-
NGHTTP2_FLAG_PRIORITY: 0x20,
|
|
47
|
-
|
|
48
|
-
NGHTTP2_HCAT_REQUEST: 0,
|
|
49
|
-
NGHTTP2_HCAT_RESPONSE: 1,
|
|
50
|
-
NGHTTP2_HCAT_PUSH_RESPONSE: 2,
|
|
51
|
-
NGHTTP2_HCAT_HEADERS: 3,
|
|
52
|
-
|
|
53
|
-
NGHTTP2_NV_FLAG_NONE: 0,
|
|
54
|
-
NGHTTP2_NV_FLAG_NO_INDEX: 0x01,
|
|
55
|
-
|
|
56
|
-
NGHTTP2_SETTINGS_HEADER_TABLE_SIZE: 0x01,
|
|
57
|
-
NGHTTP2_SETTINGS_ENABLE_PUSH: 0x02,
|
|
58
|
-
NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: 0x03,
|
|
59
|
-
NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: 0x04,
|
|
60
|
-
NGHTTP2_SETTINGS_MAX_FRAME_SIZE: 0x05,
|
|
61
|
-
NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: 0x06,
|
|
62
|
-
NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL: 0x08,
|
|
63
|
-
|
|
64
|
-
DEFAULT_SETTINGS_HEADER_TABLE_SIZE: 4096,
|
|
65
|
-
DEFAULT_SETTINGS_ENABLE_PUSH: 1,
|
|
66
|
-
DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS: 0xffffffff,
|
|
67
|
-
DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE: 65535,
|
|
68
|
-
DEFAULT_SETTINGS_MAX_FRAME_SIZE: 16384,
|
|
69
|
-
DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE: 65535,
|
|
70
|
-
DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL: 0,
|
|
71
|
-
|
|
72
|
-
MAX_MAX_FRAME_SIZE: 16777215,
|
|
73
|
-
MIN_MAX_FRAME_SIZE: 16384,
|
|
74
|
-
MAX_INITIAL_WINDOW_SIZE: 2147483647,
|
|
75
|
-
NGHTTP2_DEFAULT_WEIGHT: 16,
|
|
76
|
-
|
|
77
|
-
PADDING_STRATEGY_NONE: 0,
|
|
78
|
-
PADDING_STRATEGY_ALIGNED: 1,
|
|
79
|
-
PADDING_STRATEGY_MAX: 2,
|
|
80
|
-
PADDING_STRATEGY_CALLBACK: 1,
|
|
81
|
-
|
|
82
|
-
HTTP2_HEADER_STATUS: ':status',
|
|
83
|
-
HTTP2_HEADER_METHOD: ':method',
|
|
84
|
-
HTTP2_HEADER_AUTHORITY: ':authority',
|
|
85
|
-
HTTP2_HEADER_SCHEME: ':scheme',
|
|
86
|
-
HTTP2_HEADER_PATH: ':path',
|
|
87
|
-
HTTP2_HEADER_PROTOCOL: ':protocol',
|
|
88
|
-
|
|
89
|
-
HTTP2_HEADER_ACCEPT: 'accept',
|
|
90
|
-
HTTP2_HEADER_ACCEPT_CHARSET: 'accept-charset',
|
|
91
|
-
HTTP2_HEADER_ACCEPT_ENCODING: 'accept-encoding',
|
|
92
|
-
HTTP2_HEADER_ACCEPT_LANGUAGE: 'accept-language',
|
|
93
|
-
HTTP2_HEADER_ACCEPT_RANGES: 'accept-ranges',
|
|
94
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS: 'access-control-allow-credentials',
|
|
95
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_HEADERS: 'access-control-allow-headers',
|
|
96
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_METHODS: 'access-control-allow-methods',
|
|
97
|
-
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN: 'access-control-allow-origin',
|
|
98
|
-
HTTP2_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS: 'access-control-expose-headers',
|
|
99
|
-
HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE: 'access-control-max-age',
|
|
100
|
-
HTTP2_HEADER_ACCESS_CONTROL_REQUEST_HEADERS: 'access-control-request-headers',
|
|
101
|
-
HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD: 'access-control-request-method',
|
|
102
|
-
HTTP2_HEADER_AGE: 'age',
|
|
103
|
-
HTTP2_HEADER_ALLOW: 'allow',
|
|
104
|
-
HTTP2_HEADER_ALT_SVC: 'alt-svc',
|
|
105
|
-
HTTP2_HEADER_AUTHORIZATION: 'authorization',
|
|
106
|
-
HTTP2_HEADER_CACHE_CONTROL: 'cache-control',
|
|
107
|
-
HTTP2_HEADER_CONNECTION: 'connection',
|
|
108
|
-
HTTP2_HEADER_CONTENT_DISPOSITION: 'content-disposition',
|
|
109
|
-
HTTP2_HEADER_CONTENT_ENCODING: 'content-encoding',
|
|
110
|
-
HTTP2_HEADER_CONTENT_LANGUAGE: 'content-language',
|
|
111
|
-
HTTP2_HEADER_CONTENT_LENGTH: 'content-length',
|
|
112
|
-
HTTP2_HEADER_CONTENT_LOCATION: 'content-location',
|
|
113
|
-
HTTP2_HEADER_CONTENT_MD5: 'content-md5',
|
|
114
|
-
HTTP2_HEADER_CONTENT_RANGE: 'content-range',
|
|
115
|
-
HTTP2_HEADER_CONTENT_SECURITY_POLICY: 'content-security-policy',
|
|
116
|
-
HTTP2_HEADER_CONTENT_TYPE: 'content-type',
|
|
117
|
-
HTTP2_HEADER_COOKIE: 'cookie',
|
|
118
|
-
HTTP2_HEADER_DATE: 'date',
|
|
119
|
-
HTTP2_HEADER_DNT: 'dnt',
|
|
120
|
-
HTTP2_HEADER_EARLY_DATA: 'early-data',
|
|
121
|
-
HTTP2_HEADER_ETAG: 'etag',
|
|
122
|
-
HTTP2_HEADER_EXPECT: 'expect',
|
|
123
|
-
HTTP2_HEADER_EXPECT_CT: 'expect-ct',
|
|
124
|
-
HTTP2_HEADER_EXPIRES: 'expires',
|
|
125
|
-
HTTP2_HEADER_FORWARDED: 'forwarded',
|
|
126
|
-
HTTP2_HEADER_FROM: 'from',
|
|
127
|
-
HTTP2_HEADER_HOST: 'host',
|
|
128
|
-
HTTP2_HEADER_HTTP2_SETTINGS: 'http2-settings',
|
|
129
|
-
HTTP2_HEADER_IF_MATCH: 'if-match',
|
|
130
|
-
HTTP2_HEADER_IF_MODIFIED_SINCE: 'if-modified-since',
|
|
131
|
-
HTTP2_HEADER_IF_NONE_MATCH: 'if-none-match',
|
|
132
|
-
HTTP2_HEADER_IF_RANGE: 'if-range',
|
|
133
|
-
HTTP2_HEADER_IF_UNMODIFIED_SINCE: 'if-unmodified-since',
|
|
134
|
-
HTTP2_HEADER_KEEP_ALIVE: 'keep-alive',
|
|
135
|
-
HTTP2_HEADER_LAST_MODIFIED: 'last-modified',
|
|
136
|
-
HTTP2_HEADER_LINK: 'link',
|
|
137
|
-
HTTP2_HEADER_LOCATION: 'location',
|
|
138
|
-
HTTP2_HEADER_MAX_FORWARDS: 'max-forwards',
|
|
139
|
-
HTTP2_HEADER_ORIGIN: 'origin',
|
|
140
|
-
HTTP2_HEADER_PREFER: 'prefer',
|
|
141
|
-
HTTP2_HEADER_PRIORITY: 'priority',
|
|
142
|
-
HTTP2_HEADER_PROXY_AUTHENTICATE: 'proxy-authenticate',
|
|
143
|
-
HTTP2_HEADER_PROXY_AUTHORIZATION: 'proxy-authorization',
|
|
144
|
-
HTTP2_HEADER_PROXY_CONNECTION: 'proxy-connection',
|
|
145
|
-
HTTP2_HEADER_RANGE: 'range',
|
|
146
|
-
HTTP2_HEADER_REFERER: 'referer',
|
|
147
|
-
HTTP2_HEADER_REFRESH: 'refresh',
|
|
148
|
-
HTTP2_HEADER_RETRY_AFTER: 'retry-after',
|
|
149
|
-
HTTP2_HEADER_SERVER: 'server',
|
|
150
|
-
HTTP2_HEADER_SET_COOKIE: 'set-cookie',
|
|
151
|
-
HTTP2_HEADER_STRICT_TRANSPORT_SECURITY: 'strict-transport-security',
|
|
152
|
-
HTTP2_HEADER_TE: 'te',
|
|
153
|
-
HTTP2_HEADER_TIMING_ALLOW_ORIGIN: 'timing-allow-origin',
|
|
154
|
-
HTTP2_HEADER_TRAILER: 'trailer',
|
|
155
|
-
HTTP2_HEADER_TRANSFER_ENCODING: 'transfer-encoding',
|
|
156
|
-
HTTP2_HEADER_TK: 'tk',
|
|
157
|
-
HTTP2_HEADER_UPGRADE: 'upgrade',
|
|
158
|
-
HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS: 'upgrade-insecure-requests',
|
|
159
|
-
HTTP2_HEADER_USER_AGENT: 'user-agent',
|
|
160
|
-
HTTP2_HEADER_VARY: 'vary',
|
|
161
|
-
HTTP2_HEADER_VIA: 'via',
|
|
162
|
-
HTTP2_HEADER_WARNING: 'warning',
|
|
163
|
-
HTTP2_HEADER_WWW_AUTHENTICATE: 'www-authenticate',
|
|
164
|
-
HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS: 'x-content-type-options',
|
|
165
|
-
HTTP2_HEADER_X_FORWARDED_FOR: 'x-forwarded-for',
|
|
166
|
-
HTTP2_HEADER_X_FRAME_OPTIONS: 'x-frame-options',
|
|
167
|
-
HTTP2_HEADER_X_XSS_PROTECTION: 'x-xss-protection',
|
|
168
|
-
HTTP2_HEADER_PURPOSE: 'purpose',
|
|
169
|
-
|
|
170
|
-
HTTP2_METHOD_ACL: 'ACL',
|
|
171
|
-
HTTP2_METHOD_BASELINE_CONTROL: 'BASELINE-CONTROL',
|
|
172
|
-
HTTP2_METHOD_BIND: 'BIND',
|
|
173
|
-
HTTP2_METHOD_CHECKIN: 'CHECKIN',
|
|
174
|
-
HTTP2_METHOD_CHECKOUT: 'CHECKOUT',
|
|
175
|
-
HTTP2_METHOD_CONNECT: 'CONNECT',
|
|
176
|
-
HTTP2_METHOD_COPY: 'COPY',
|
|
177
|
-
HTTP2_METHOD_DELETE: 'DELETE',
|
|
178
|
-
HTTP2_METHOD_GET: 'GET',
|
|
179
|
-
HTTP2_METHOD_HEAD: 'HEAD',
|
|
180
|
-
HTTP2_METHOD_LABEL: 'LABEL',
|
|
181
|
-
HTTP2_METHOD_LINK: 'LINK',
|
|
182
|
-
HTTP2_METHOD_LOCK: 'LOCK',
|
|
183
|
-
HTTP2_METHOD_MERGE: 'MERGE',
|
|
184
|
-
HTTP2_METHOD_MKACTIVITY: 'MKACTIVITY',
|
|
185
|
-
HTTP2_METHOD_MKCALENDAR: 'MKCALENDAR',
|
|
186
|
-
HTTP2_METHOD_MKCOL: 'MKCOL',
|
|
187
|
-
HTTP2_METHOD_MKREDIRECTREF: 'MKREDIRECTREF',
|
|
188
|
-
HTTP2_METHOD_MKWORKSPACE: 'MKWORKSPACE',
|
|
189
|
-
HTTP2_METHOD_MOVE: 'MOVE',
|
|
190
|
-
HTTP2_METHOD_OPTIONS: 'OPTIONS',
|
|
191
|
-
HTTP2_METHOD_ORDERPATCH: 'ORDERPATCH',
|
|
192
|
-
HTTP2_METHOD_PATCH: 'PATCH',
|
|
193
|
-
HTTP2_METHOD_POST: 'POST',
|
|
194
|
-
HTTP2_METHOD_PRI: 'PRI',
|
|
195
|
-
HTTP2_METHOD_PROPFIND: 'PROPFIND',
|
|
196
|
-
HTTP2_METHOD_PROPPATCH: 'PROPPATCH',
|
|
197
|
-
HTTP2_METHOD_PUT: 'PUT',
|
|
198
|
-
HTTP2_METHOD_REBIND: 'REBIND',
|
|
199
|
-
HTTP2_METHOD_REPORT: 'REPORT',
|
|
200
|
-
HTTP2_METHOD_SEARCH: 'SEARCH',
|
|
201
|
-
HTTP2_METHOD_TRACE: 'TRACE',
|
|
202
|
-
HTTP2_METHOD_UNBIND: 'UNBIND',
|
|
203
|
-
HTTP2_METHOD_UNCHECKOUT: 'UNCHECKOUT',
|
|
204
|
-
HTTP2_METHOD_UNLINK: 'UNLINK',
|
|
205
|
-
HTTP2_METHOD_UNLOCK: 'UNLOCK',
|
|
206
|
-
HTTP2_METHOD_UPDATE: 'UPDATE',
|
|
207
|
-
HTTP2_METHOD_UPDATEREDIRECTREF: 'UPDATEREDIRECTREF',
|
|
208
|
-
HTTP2_METHOD_VERSION_CONTROL: 'VERSION-CONTROL',
|
|
209
|
-
|
|
210
|
-
HTTP_STATUS_CONTINUE: 100,
|
|
211
|
-
HTTP_STATUS_SWITCHING_PROTOCOLS: 101,
|
|
212
|
-
HTTP_STATUS_PROCESSING: 102,
|
|
213
|
-
HTTP_STATUS_EARLY_HINTS: 103,
|
|
214
|
-
HTTP_STATUS_OK: 200,
|
|
215
|
-
HTTP_STATUS_CREATED: 201,
|
|
216
|
-
HTTP_STATUS_ACCEPTED: 202,
|
|
217
|
-
HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION: 203,
|
|
218
|
-
HTTP_STATUS_NO_CONTENT: 204,
|
|
219
|
-
HTTP_STATUS_RESET_CONTENT: 205,
|
|
220
|
-
HTTP_STATUS_PARTIAL_CONTENT: 206,
|
|
221
|
-
HTTP_STATUS_MULTI_STATUS: 207,
|
|
222
|
-
HTTP_STATUS_ALREADY_REPORTED: 208,
|
|
223
|
-
HTTP_STATUS_IM_USED: 226,
|
|
224
|
-
HTTP_STATUS_MULTIPLE_CHOICES: 300,
|
|
225
|
-
HTTP_STATUS_MOVED_PERMANENTLY: 301,
|
|
226
|
-
HTTP_STATUS_FOUND: 302,
|
|
227
|
-
HTTP_STATUS_SEE_OTHER: 303,
|
|
228
|
-
HTTP_STATUS_NOT_MODIFIED: 304,
|
|
229
|
-
HTTP_STATUS_USE_PROXY: 305,
|
|
230
|
-
HTTP_STATUS_TEMPORARY_REDIRECT: 307,
|
|
231
|
-
HTTP_STATUS_PERMANENT_REDIRECT: 308,
|
|
232
|
-
HTTP_STATUS_BAD_REQUEST: 400,
|
|
233
|
-
HTTP_STATUS_UNAUTHORIZED: 401,
|
|
234
|
-
HTTP_STATUS_PAYMENT_REQUIRED: 402,
|
|
235
|
-
HTTP_STATUS_FORBIDDEN: 403,
|
|
236
|
-
HTTP_STATUS_NOT_FOUND: 404,
|
|
237
|
-
HTTP_STATUS_METHOD_NOT_ALLOWED: 405,
|
|
238
|
-
HTTP_STATUS_NOT_ACCEPTABLE: 406,
|
|
239
|
-
HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED: 407,
|
|
240
|
-
HTTP_STATUS_REQUEST_TIMEOUT: 408,
|
|
241
|
-
HTTP_STATUS_CONFLICT: 409,
|
|
242
|
-
HTTP_STATUS_GONE: 410,
|
|
243
|
-
HTTP_STATUS_LENGTH_REQUIRED: 411,
|
|
244
|
-
HTTP_STATUS_PRECONDITION_FAILED: 412,
|
|
245
|
-
HTTP_STATUS_PAYLOAD_TOO_LARGE: 413,
|
|
246
|
-
HTTP_STATUS_URI_TOO_LONG: 414,
|
|
247
|
-
HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE: 415,
|
|
248
|
-
HTTP_STATUS_RANGE_NOT_SATISFIABLE: 416,
|
|
249
|
-
HTTP_STATUS_EXPECTATION_FAILED: 417,
|
|
250
|
-
HTTP_STATUS_TEAPOT: 418,
|
|
251
|
-
HTTP_STATUS_MISDIRECTED_REQUEST: 421,
|
|
252
|
-
HTTP_STATUS_UNPROCESSABLE_ENTITY: 422,
|
|
253
|
-
HTTP_STATUS_LOCKED: 423,
|
|
254
|
-
HTTP_STATUS_FAILED_DEPENDENCY: 424,
|
|
255
|
-
HTTP_STATUS_TOO_EARLY: 425,
|
|
256
|
-
HTTP_STATUS_UPGRADE_REQUIRED: 426,
|
|
257
|
-
HTTP_STATUS_PRECONDITION_REQUIRED: 428,
|
|
258
|
-
HTTP_STATUS_TOO_MANY_REQUESTS: 429,
|
|
259
|
-
HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
|
|
260
|
-
HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS: 451,
|
|
261
|
-
HTTP_STATUS_INTERNAL_SERVER_ERROR: 500,
|
|
262
|
-
HTTP_STATUS_NOT_IMPLEMENTED: 501,
|
|
263
|
-
HTTP_STATUS_BAD_GATEWAY: 502,
|
|
264
|
-
HTTP_STATUS_SERVICE_UNAVAILABLE: 503,
|
|
265
|
-
HTTP_STATUS_GATEWAY_TIMEOUT: 504,
|
|
266
|
-
HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED: 505,
|
|
267
|
-
HTTP_STATUS_VARIANT_ALSO_NEGOTIATES: 506,
|
|
268
|
-
HTTP_STATUS_INSUFFICIENT_STORAGE: 507,
|
|
269
|
-
HTTP_STATUS_LOOP_DETECTED: 508,
|
|
270
|
-
HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED: 509,
|
|
271
|
-
HTTP_STATUS_NOT_EXTENDED: 510,
|
|
272
|
-
HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED: 511,
|
|
273
|
-
} as const;
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
export interface Http2Settings {
|
|
277
|
-
headerTableSize?: number;
|
|
278
|
-
enablePush?: boolean;
|
|
279
|
-
maxConcurrentStreams?: number;
|
|
280
|
-
initialWindowSize?: number;
|
|
281
|
-
maxFrameSize?: number;
|
|
282
|
-
maxHeaderListSize?: number;
|
|
283
|
-
enableConnectProtocol?: boolean;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const SETTINGS_MAP: [number, keyof Http2Settings, boolean][] = [
|
|
287
|
-
[0x01, 'headerTableSize', false],
|
|
288
|
-
[0x02, 'enablePush', true],
|
|
289
|
-
[0x03, 'maxConcurrentStreams', false],
|
|
290
|
-
[0x04, 'initialWindowSize', false],
|
|
291
|
-
[0x05, 'maxFrameSize', false],
|
|
292
|
-
[0x06, 'maxHeaderListSize', false],
|
|
293
|
-
[0x08, 'enableConnectProtocol', true],
|
|
294
|
-
];
|
|
295
|
-
|
|
296
|
-
// RFC 7540 §6.5
|
|
297
|
-
export function getDefaultSettings(): Http2Settings {
|
|
298
|
-
return {
|
|
299
|
-
headerTableSize: 4096,
|
|
300
|
-
enablePush: true,
|
|
301
|
-
maxConcurrentStreams: 0xffffffff,
|
|
302
|
-
initialWindowSize: 65535,
|
|
303
|
-
maxFrameSize: 16384,
|
|
304
|
-
maxHeaderListSize: 65535,
|
|
305
|
-
enableConnectProtocol: false,
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// RFC 7540 §6.5.1 — each setting: 2-byte ID + 4-byte value (big-endian)
|
|
310
|
-
export function getPackedSettings(settings?: Http2Settings): Uint8Array {
|
|
311
|
-
if (!settings) return new Uint8Array(0);
|
|
312
|
-
|
|
313
|
-
const pairs: [number, number][] = [];
|
|
314
|
-
for (const [id, key, isBool] of SETTINGS_MAP) {
|
|
315
|
-
const val = settings[key];
|
|
316
|
-
if (val !== undefined) {
|
|
317
|
-
pairs.push([id, isBool ? (val ? 1 : 0) : val as number]);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const buf = new Uint8Array(pairs.length * 6);
|
|
322
|
-
const view = new DataView(buf.buffer);
|
|
323
|
-
for (let i = 0; i < pairs.length; i++) {
|
|
324
|
-
const offset = i * 6;
|
|
325
|
-
view.setUint16(offset, pairs[i][0], false);
|
|
326
|
-
view.setUint32(offset + 2, pairs[i][1], false);
|
|
327
|
-
}
|
|
328
|
-
return buf;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
export function getUnpackedSettings(buf: Uint8Array | ArrayBuffer): Http2Settings {
|
|
332
|
-
const data = buf instanceof ArrayBuffer ? new Uint8Array(buf) : buf;
|
|
333
|
-
if (data.byteLength % 6 !== 0) {
|
|
334
|
-
throw new RangeError('Invalid packed settings length');
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const result: Http2Settings = {};
|
|
338
|
-
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
339
|
-
|
|
340
|
-
for (let i = 0; i < data.byteLength; i += 6) {
|
|
341
|
-
const id = view.getUint16(i, false);
|
|
342
|
-
const value = view.getUint32(i + 2, false);
|
|
343
|
-
|
|
344
|
-
for (const [settingId, key, isBool] of SETTINGS_MAP) {
|
|
345
|
-
if (id === settingId) {
|
|
346
|
-
(result as Record<string, unknown>)[key] = isBool ? value !== 0 : value;
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return result;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Stub — Soup 3.0 handles HTTP/2 transparently but lacks multiplexed stream API
|
|
355
|
-
export class Http2Session extends EventEmitter {
|
|
356
|
-
readonly alpnProtocol: string | undefined = undefined;
|
|
357
|
-
readonly encrypted: boolean = false;
|
|
358
|
-
readonly type: number = constants.NGHTTP2_SESSION_CLIENT;
|
|
359
|
-
|
|
360
|
-
private _closed = false;
|
|
361
|
-
private _destroyed = false;
|
|
362
|
-
private _settings: Http2Settings;
|
|
363
|
-
|
|
364
|
-
constructor() {
|
|
365
|
-
super();
|
|
366
|
-
this._settings = getDefaultSettings();
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
get closed(): boolean { return this._closed; }
|
|
370
|
-
get destroyed(): boolean { return this._destroyed; }
|
|
371
|
-
get connecting(): boolean { return false; }
|
|
372
|
-
get pendingSettingsAck(): boolean { return false; }
|
|
373
|
-
|
|
374
|
-
get localSettings(): Http2Settings { return { ...this._settings }; }
|
|
375
|
-
get remoteSettings(): Http2Settings { return getDefaultSettings(); }
|
|
376
|
-
|
|
377
|
-
settings(settings: Http2Settings, callback?: () => void): void {
|
|
378
|
-
Object.assign(this._settings, settings);
|
|
379
|
-
if (callback) Promise.resolve().then(callback);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
goaway(code?: number, _lastStreamId?: number, _data?: Uint8Array): void {
|
|
383
|
-
this.emit('goaway', code ?? constants.NGHTTP2_NO_ERROR);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
ping(payload?: Uint8Array, callback?: (err: Error | null, duration: number, payload: Uint8Array) => void): boolean {
|
|
387
|
-
const buf = payload || new Uint8Array(8);
|
|
388
|
-
if (callback) Promise.resolve().then(() => callback(null, 0, buf));
|
|
389
|
-
return true;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
close(callback?: () => void): void {
|
|
393
|
-
if (this._closed) return;
|
|
394
|
-
this._closed = true;
|
|
395
|
-
this.emit('close');
|
|
396
|
-
if (callback) callback();
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
destroy(error?: Error, code?: number): void {
|
|
400
|
-
if (this._destroyed) return;
|
|
401
|
-
this._destroyed = true;
|
|
402
|
-
this._closed = true;
|
|
403
|
-
if (error) this.emit('error', error);
|
|
404
|
-
this.emit('close');
|
|
405
|
-
if (code !== undefined) {
|
|
406
|
-
this.goaway(code);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
ref(): void {}
|
|
411
|
-
unref(): void {}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
export class ServerHttp2Session extends Http2Session {
|
|
415
|
-
readonly type = constants.NGHTTP2_SESSION_SERVER;
|
|
416
|
-
|
|
417
|
-
altsvc(_alt: string, _originOrStream: string | number): void {}
|
|
418
|
-
|
|
419
|
-
origin(..._origins: string[]): void {}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
export class ClientHttp2Session extends Http2Session {
|
|
423
|
-
request(_headers?: Record<string, string | string[]>, _options?: unknown): Http2Stream {
|
|
424
|
-
throw new Error('http2 client requests are not yet implemented in GJS');
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
export class Http2Stream extends EventEmitter {
|
|
429
|
-
readonly id: number = 0;
|
|
430
|
-
readonly session: Http2Session | null = null;
|
|
431
|
-
readonly sentHeaders: Record<string, string | string[]> = {};
|
|
432
|
-
readonly sentInfoHeaders: Record<string, string | string[]>[] = [];
|
|
433
|
-
|
|
434
|
-
private _closed = false;
|
|
435
|
-
private _destroyed = false;
|
|
436
|
-
private _state: number = constants.NGHTTP2_STREAM_STATE_IDLE;
|
|
437
|
-
|
|
438
|
-
get closed(): boolean { return this._closed; }
|
|
439
|
-
get destroyed(): boolean { return this._destroyed; }
|
|
440
|
-
get pending(): boolean { return this.id === 0; }
|
|
441
|
-
get state(): number { return this._state; }
|
|
442
|
-
get endAfterHeaders(): boolean { return false; }
|
|
443
|
-
get bufferSize(): number { return 0; }
|
|
444
|
-
|
|
445
|
-
get rstCode(): number { return constants.NGHTTP2_NO_ERROR; }
|
|
446
|
-
|
|
447
|
-
close(code?: number, callback?: () => void): void {
|
|
448
|
-
if (this._closed) return;
|
|
449
|
-
this._closed = true;
|
|
450
|
-
this._state = constants.NGHTTP2_STREAM_STATE_CLOSED;
|
|
451
|
-
this.emit('close', code ?? constants.NGHTTP2_NO_ERROR);
|
|
452
|
-
if (callback) callback();
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
destroy(error?: Error): void {
|
|
456
|
-
if (this._destroyed) return;
|
|
457
|
-
this._destroyed = true;
|
|
458
|
-
this._closed = true;
|
|
459
|
-
this._state = constants.NGHTTP2_STREAM_STATE_CLOSED;
|
|
460
|
-
if (error) this.emit('error', error);
|
|
461
|
-
this.emit('close');
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
priority(_options: { exclusive?: boolean; parent?: number; weight?: number; silent?: boolean }): void {}
|
|
465
|
-
|
|
466
|
-
setTimeout(msecs: number, callback?: () => void): void {
|
|
467
|
-
if (callback) setTimeout(callback, msecs);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
export class ServerHttp2Stream extends Http2Stream {
|
|
472
|
-
readonly headersSent: boolean = false;
|
|
473
|
-
readonly pushAllowed: boolean = false;
|
|
474
|
-
|
|
475
|
-
respond(_headers?: Record<string, string | string[] | number>, _options?: unknown): void {
|
|
476
|
-
throw new Error('http2 server respond is not yet implemented in GJS');
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
respondWithFD(_fd: number | unknown, _headers?: Record<string, string | string[]>, _options?: unknown): void {
|
|
480
|
-
throw new Error('http2 respondWithFD is not yet implemented in GJS');
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
respondWithFile(_path: string, _headers?: Record<string, string | string[]>, _options?: unknown): void {
|
|
484
|
-
throw new Error('http2 respondWithFile is not yet implemented in GJS');
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
pushStream(
|
|
488
|
-
_headers: Record<string, string | string[]>,
|
|
489
|
-
_options: unknown,
|
|
490
|
-
_callback: (err: Error | null, pushStream: ServerHttp2Stream, headers: Record<string, string | string[]>) => void,
|
|
491
|
-
): void {
|
|
492
|
-
throw new Error('http2 server push is not yet implemented in GJS');
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
additionalHeaders(_headers: Record<string, string | string[]>): void {}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
export class ClientHttp2Stream extends Http2Stream {}
|
|
499
|
-
|
|
500
|
-
export class Http2ServerRequest extends EventEmitter {
|
|
501
|
-
readonly headers: Record<string, string | string[] | undefined> = {};
|
|
502
|
-
readonly httpVersion: string = '2.0';
|
|
503
|
-
readonly method: string = 'GET';
|
|
504
|
-
readonly url: string = '/';
|
|
505
|
-
readonly stream: Http2Stream | null = null;
|
|
506
|
-
readonly authority: string = '';
|
|
507
|
-
readonly scheme: string = 'https';
|
|
508
|
-
|
|
509
|
-
get complete(): boolean { return true; }
|
|
510
|
-
|
|
511
|
-
setTimeout(msecs: number, callback?: () => void): this {
|
|
512
|
-
if (callback) setTimeout(callback, msecs);
|
|
513
|
-
return this;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
export class Http2ServerResponse extends EventEmitter {
|
|
518
|
-
statusCode: number = 200;
|
|
519
|
-
readonly stream: Http2Stream | null = null;
|
|
520
|
-
readonly headersSent: boolean = false;
|
|
521
|
-
|
|
522
|
-
private _headers: Record<string, string | string[] | number> = {};
|
|
523
|
-
|
|
524
|
-
setHeader(name: string, value: string | string[] | number): this {
|
|
525
|
-
this._headers[name.toLowerCase()] = value;
|
|
526
|
-
return this;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
getHeader(name: string): string | string[] | number | undefined {
|
|
530
|
-
return this._headers[name.toLowerCase()];
|
|
531
|
-
}
|
|
1
|
+
// Reference: Node.js lib/http2.js, lib/internal/http2/core.js, lib/internal/http2/compat.js
|
|
2
|
+
// Reimplemented for GJS using Soup 3.0 (HTTP/2 transparently via ALPN when TLS is active)
|
|
3
|
+
//
|
|
4
|
+
// Phase 1: Compat layer backed by Soup.Server + Soup.Session.
|
|
5
|
+
// createServer() → HTTP/1.1 only (Soup does not support h2c/cleartext HTTP/2)
|
|
6
|
+
// createSecureServer() → HTTP/2 via ALPN when TLS cert is provided, else HTTP/1.1
|
|
7
|
+
// connect() → HTTP/2 over HTTPS automatically, HTTP/1.1 over plain HTTP
|
|
8
|
+
//
|
|
9
|
+
// Phase 2 (future, requires Vala/nghttp2): pushStream, stream IDs, flow control, GOAWAY
|
|
10
|
+
|
|
11
|
+
// ─── Protocol constants & settings ───────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
constants,
|
|
15
|
+
getDefaultSettings,
|
|
16
|
+
getPackedSettings,
|
|
17
|
+
getUnpackedSettings,
|
|
18
|
+
type Http2Settings,
|
|
19
|
+
} from './protocol.js';
|
|
532
20
|
|
|
533
|
-
|
|
534
|
-
return { ...this._headers };
|
|
535
|
-
}
|
|
21
|
+
import { constants, getDefaultSettings, getPackedSettings, getUnpackedSettings, type Http2Settings } from './protocol.js';
|
|
536
22
|
|
|
537
|
-
|
|
538
|
-
delete this._headers[name.toLowerCase()];
|
|
539
|
-
}
|
|
23
|
+
// ─── Server-side classes ──────────────────────────────────────────────────────
|
|
540
24
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
25
|
+
export {
|
|
26
|
+
Http2ServerRequest,
|
|
27
|
+
Http2ServerResponse,
|
|
28
|
+
ServerHttp2Stream,
|
|
29
|
+
ServerHttp2Session,
|
|
30
|
+
Http2Server,
|
|
31
|
+
Http2SecureServer,
|
|
32
|
+
type ServerOptions,
|
|
33
|
+
type SecureServerOptions,
|
|
34
|
+
} from './server.js';
|
|
544
35
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
36
|
+
import {
|
|
37
|
+
Http2ServerRequest,
|
|
38
|
+
Http2ServerResponse,
|
|
39
|
+
ServerHttp2Stream,
|
|
40
|
+
ServerHttp2Session,
|
|
41
|
+
Http2Server,
|
|
42
|
+
Http2SecureServer,
|
|
43
|
+
type ServerOptions,
|
|
44
|
+
type SecureServerOptions,
|
|
45
|
+
} from './server.js';
|
|
554
46
|
|
|
555
|
-
|
|
556
|
-
this.emit('finish');
|
|
557
|
-
return this;
|
|
558
|
-
}
|
|
47
|
+
// ─── Client-side classes ──────────────────────────────────────────────────────
|
|
559
48
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
49
|
+
export {
|
|
50
|
+
Http2Session,
|
|
51
|
+
ClientHttp2Session,
|
|
52
|
+
ClientHttp2Stream,
|
|
53
|
+
type ClientSessionOptions,
|
|
54
|
+
type ClientStreamOptions,
|
|
55
|
+
} from './client-session.js';
|
|
563
56
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
57
|
+
import {
|
|
58
|
+
Http2Session,
|
|
59
|
+
ClientHttp2Session,
|
|
60
|
+
ClientHttp2Stream,
|
|
61
|
+
type ClientSessionOptions,
|
|
62
|
+
} from './client-session.js';
|
|
567
63
|
|
|
568
|
-
|
|
569
|
-
if (callback) setTimeout(callback, msecs);
|
|
570
|
-
return this;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
64
|
+
// ─── Factory functions ────────────────────────────────────────────────────────
|
|
573
65
|
|
|
574
66
|
export function createServer(
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
):
|
|
578
|
-
|
|
579
|
-
'http2.createServer() is not yet implemented in GJS. ' +
|
|
580
|
-
'Soup 3.0 handles HTTP/2 transparently but does not expose multiplexed streams. ' +
|
|
581
|
-
'Use http.createServer() for HTTP/1.1 or consider a future nghttp2-based implementation.'
|
|
582
|
-
);
|
|
67
|
+
options?: ServerOptions | ((req: Http2ServerRequest, res: Http2ServerResponse) => void),
|
|
68
|
+
handler?: (req: Http2ServerRequest, res: Http2ServerResponse) => void,
|
|
69
|
+
): Http2Server {
|
|
70
|
+
return new Http2Server(options, handler);
|
|
583
71
|
}
|
|
584
72
|
|
|
585
73
|
export function createSecureServer(
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
):
|
|
589
|
-
|
|
590
|
-
'http2.createSecureServer() is not yet implemented in GJS. ' +
|
|
591
|
-
'Requires TLS server support combined with HTTP/2 multiplexing.'
|
|
592
|
-
);
|
|
74
|
+
options: SecureServerOptions,
|
|
75
|
+
handler?: (req: Http2ServerRequest, res: Http2ServerResponse) => void,
|
|
76
|
+
): Http2SecureServer {
|
|
77
|
+
return new Http2SecureServer(options, handler);
|
|
593
78
|
}
|
|
594
79
|
|
|
595
80
|
export function connect(
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
81
|
+
authority: string | URL,
|
|
82
|
+
options?: ClientSessionOptions | ((session: ClientHttp2Session, socket: any) => void),
|
|
83
|
+
listener?: (session: ClientHttp2Session, socket: any) => void,
|
|
599
84
|
): ClientHttp2Session {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
85
|
+
const authorityStr = typeof authority === 'string' ? authority : authority.toString();
|
|
86
|
+
if (typeof options === 'function') {
|
|
87
|
+
listener = options;
|
|
88
|
+
options = {};
|
|
89
|
+
}
|
|
90
|
+
const session = new ClientHttp2Session(authorityStr, (options ?? {}) as ClientSessionOptions);
|
|
91
|
+
if (listener) session.once('connect', listener);
|
|
92
|
+
return session;
|
|
605
93
|
}
|
|
606
94
|
|
|
607
|
-
|
|
95
|
+
// ─── Misc ─────────────────────────────────────────────────────────────────────
|
|
96
|
+
|
|
97
|
+
export const sensitiveHeaders = Symbol.for('nodejs.http2.sensitiveHeaders');
|
|
608
98
|
|
|
609
99
|
export function performServerHandshake(_socket: unknown): unknown {
|
|
610
100
|
throw new Error('http2.performServerHandshake() is not yet implemented in GJS');
|
|
611
101
|
}
|
|
612
102
|
|
|
103
|
+
// ─── Default export ───────────────────────────────────────────────────────────
|
|
104
|
+
|
|
613
105
|
export default {
|
|
614
106
|
constants,
|
|
615
107
|
createServer,
|
|
@@ -621,11 +113,12 @@ export default {
|
|
|
621
113
|
sensitiveHeaders,
|
|
622
114
|
performServerHandshake,
|
|
623
115
|
Http2Session,
|
|
624
|
-
|
|
116
|
+
Http2Server,
|
|
117
|
+
Http2SecureServer,
|
|
118
|
+
Http2ServerRequest,
|
|
119
|
+
Http2ServerResponse,
|
|
625
120
|
ServerHttp2Session,
|
|
626
|
-
ClientHttp2Session,
|
|
627
121
|
ServerHttp2Stream,
|
|
122
|
+
ClientHttp2Session,
|
|
628
123
|
ClientHttp2Stream,
|
|
629
|
-
Http2ServerRequest,
|
|
630
|
-
Http2ServerResponse,
|
|
631
124
|
};
|