@bytecodealliance/preview2-shim 0.0.16 → 0.0.17
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/browser/filesystem.js +4 -2
- package/lib/browser/index.js +2 -4
- package/lib/browser/io.js +8 -99
- package/lib/common/io.js +119 -0
- package/lib/http/wasi-http.js +346 -334
- package/lib/nodejs/cli.js +2 -12
- package/lib/nodejs/filesystem.js +419 -340
- package/lib/nodejs/http.js +4 -129
- package/lib/nodejs/index.js +3 -4
- package/lib/nodejs/io.js +11 -155
- package/package.json +1 -1
- package/lib/http/error.js +0 -11
package/lib/http/wasi-http.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
// Based on:
|
|
2
|
-
// https://github.com/bytecodealliance/wasmtime/blob/8efcb9851602287fd07a1a1e91501f51f2653d7e/crates/wasi-http/
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
* @typedef {import("../../types/interfaces/wasi-http-types").Fields} Fields
|
|
6
3
|
* @typedef {import("../../types/interfaces/wasi-http-types").FutureIncomingResponse} FutureIncomingResponse
|
|
7
4
|
* @typedef {import("../../types/interfaces/wasi-http-types").Headers} Headers
|
|
8
|
-
* @typedef {import("../../types/interfaces/wasi-http-types").IncomingResponse} IncomingResponse
|
|
9
5
|
* @typedef {import("../../types/interfaces/wasi-http-types").IncomingStream} IncomingStream
|
|
10
6
|
* @typedef {import("../../types/interfaces/wasi-http-types").Method} Method
|
|
11
|
-
* @typedef {import("../../types/interfaces/wasi-http-types").OutgoingRequest} OutgoingRequest
|
|
12
7
|
* @typedef {import("../../types/interfaces/wasi-http-types").RequestOptions} RequestOptions
|
|
13
8
|
* @typedef {import("../../types/interfaces/wasi-http-types").Result} Result
|
|
14
9
|
* @typedef {import("../../types/interfaces/wasi-http-types").Scheme} Scheme
|
|
@@ -16,355 +11,372 @@
|
|
|
16
11
|
* @typedef {import("../../types/interfaces/wasi-io-streams").StreamStatus} StreamStatus
|
|
17
12
|
*/
|
|
18
13
|
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import { UnexpectedError } from './error.js';
|
|
22
|
-
|
|
23
|
-
export class WasiHttp {
|
|
24
|
-
requestIdBase = 1;
|
|
25
|
-
responseIdBase = 1;
|
|
26
|
-
fieldsIdBase = 1;
|
|
27
|
-
streamIdBase = 3;
|
|
28
|
-
futureIdBase = 1;
|
|
29
|
-
/** @type {Map<number,ActiveRequest>} */ requests = new Map();
|
|
30
|
-
/** @type {Map<number,ActiveResponse>} */ responses = new Map();
|
|
31
|
-
/** @type {Map<number,ActiveFields>} */ fields = new Map();
|
|
32
|
-
/** @type {Map<number,Uint8Array>} */ streams = new Map();
|
|
33
|
-
/** @type {Map<number,ActiveFuture>} */ futures = new Map();
|
|
34
|
-
|
|
35
|
-
constructor() {}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @param {OutgoingRequest} requestId
|
|
39
|
-
* @param {RequestOptions | null} options
|
|
40
|
-
* @returns {FutureIncomingResponse}
|
|
41
|
-
*/
|
|
42
|
-
handle = (requestId, _options) => {
|
|
43
|
-
const request = this.requests.get(requestId);
|
|
44
|
-
if (!request) throw Error("not found!");
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { createSyncFn } from './synckit/index.js';
|
|
45
16
|
|
|
46
|
-
|
|
47
|
-
this.responseIdBase += 1;
|
|
48
|
-
const response = new ActiveResponse(responseId);
|
|
17
|
+
const workerPath = fileURLToPath(new URL('./make-request.js', import.meta.url));
|
|
49
18
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
19
|
+
function send(req) {
|
|
20
|
+
const syncFn = createSyncFn(workerPath);
|
|
21
|
+
let rawResponse = syncFn(req);
|
|
22
|
+
let response = JSON.parse(rawResponse);
|
|
23
|
+
if (response.status) {
|
|
24
|
+
return {
|
|
25
|
+
...response,
|
|
26
|
+
body: response.body ? Buffer.from(response.body, 'base64') : undefined,
|
|
55
27
|
};
|
|
56
|
-
if (request.headers) {
|
|
57
|
-
const requestHeaders = this.fields.get(request.headers);
|
|
58
|
-
const decoder = new TextDecoder();
|
|
59
|
-
for (const [key, value] of requestHeaders.fields.entries()) {
|
|
60
|
-
headers[key] = decoder.decode(value);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
const body = this.streams.get(request.body);
|
|
64
|
-
|
|
65
|
-
const res = http.send({
|
|
66
|
-
method: request.method.tag,
|
|
67
|
-
uri: url,
|
|
68
|
-
headers: headers,
|
|
69
|
-
params: [],
|
|
70
|
-
body: body && body.length > 0 ? body : undefined,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
response.status = res.status;
|
|
74
|
-
if (res.headers && res.headers.length > 0) {
|
|
75
|
-
response.headers = this.newFields(res.headers);
|
|
76
|
-
}
|
|
77
|
-
const buf = res.body;
|
|
78
|
-
response.body = this.streamIdBase;
|
|
79
|
-
this.streamIdBase += 1;
|
|
80
|
-
this.streams.set(response.body, buf);
|
|
81
|
-
this.responses.set(responseId, response);
|
|
82
|
-
|
|
83
|
-
const futureId = this.futureIdBase;
|
|
84
|
-
this.futureIdBase += 1;
|
|
85
|
-
const future = new ActiveFuture(futureId, responseId);
|
|
86
|
-
this.futures.set(futureId, future);
|
|
87
|
-
return futureId;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
read = (stream, len) => {
|
|
91
|
-
return this.blockingRead(stream, len);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @param {InputStream} stream
|
|
96
|
-
* @param {bigint} len
|
|
97
|
-
* @returns {[Uint8Array | ArrayBuffer, StreamStatus]}
|
|
98
|
-
*/
|
|
99
|
-
blockingRead = (stream, len) => {
|
|
100
|
-
if (stream < 3) {
|
|
101
|
-
return io.streams.blockingRead(stream);
|
|
102
|
-
}
|
|
103
|
-
const s = this.streams.get(stream);
|
|
104
|
-
if (!s) throw Error(`stream not found: ${stream}`);
|
|
105
|
-
const position = Number(len);
|
|
106
|
-
if (position === 0) {
|
|
107
|
-
return [new Uint8Array(), s.byteLength > 0 ? 'open' : 'ended'];
|
|
108
|
-
} else if (s.byteLength > position) {
|
|
109
|
-
this.streams.set(stream, s.slice(position, s.byteLength));
|
|
110
|
-
return [s.slice(0, position), 'open'];
|
|
111
|
-
} else {
|
|
112
|
-
return [s.slice(0, position), 'ended'];
|
|
113
|
-
}
|
|
114
28
|
}
|
|
29
|
+
throw new UnexpectedError(response.message);
|
|
30
|
+
}
|
|
115
31
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
32
|
+
class UnexpectedError extends Error {
|
|
33
|
+
payload;
|
|
34
|
+
constructor(message = "unexpected-error") {
|
|
35
|
+
super(message);
|
|
36
|
+
this.payload = {
|
|
37
|
+
tag: "unexpected-error",
|
|
38
|
+
val: message,
|
|
39
|
+
};
|
|
123
40
|
}
|
|
41
|
+
}
|
|
124
42
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
43
|
+
function combineChunks (chunks) {
|
|
44
|
+
if (chunks.length === 0)
|
|
45
|
+
return new Uint8Array();
|
|
46
|
+
if (chunks.length === 1)
|
|
47
|
+
return chunks[0];
|
|
48
|
+
const totalLen = chunks.reduce((total, chunk) => total + chunk.byteLength);
|
|
49
|
+
const out = new Uint8Array(totalLen);
|
|
50
|
+
let idx = 0;
|
|
51
|
+
for (const chunk of chunks) {
|
|
52
|
+
out.set(chunk, idx);
|
|
53
|
+
idx += chunk.byteLength;
|
|
132
54
|
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
133
57
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
58
|
+
export class WasiHttp {
|
|
59
|
+
requestCnt = 1;
|
|
60
|
+
responseCnt = 1;
|
|
61
|
+
fieldsCnt = 1;
|
|
62
|
+
futureCnt = 1;
|
|
63
|
+
/** @type {Map<number,OutgoingRequest>} */ requests = new Map();
|
|
64
|
+
/** @type {Map<number,IncomingResponse>} */ responses = new Map();
|
|
65
|
+
/** @type {Map<number,Fields>} */ fields = new Map();
|
|
66
|
+
/** @type {Map<number,Future>} */ futures = new Map();
|
|
138
67
|
|
|
139
68
|
/**
|
|
140
|
-
*
|
|
141
|
-
* @param {
|
|
69
|
+
*
|
|
70
|
+
* @param {import('../common/io.js').Io} io
|
|
71
|
+
* @returns
|
|
142
72
|
*/
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
73
|
+
constructor(io) {
|
|
74
|
+
const http = this;
|
|
75
|
+
|
|
76
|
+
class OutgoingRequest {
|
|
77
|
+
/** @type {number} */ id;
|
|
78
|
+
bodyFinished = false;
|
|
79
|
+
/** @type {Method} */ method = { tag: 'get' };
|
|
80
|
+
/** @type {Scheme | undefined} */ scheme = { tag: 'HTTP' };
|
|
81
|
+
pathWithQuery = undefined;
|
|
82
|
+
authority = undefined;
|
|
83
|
+
/** @type {number | undefined} */ headers = undefined;
|
|
84
|
+
chunks = [];
|
|
85
|
+
body = io.createStream(this);
|
|
86
|
+
constructor() {
|
|
87
|
+
http.requests.set(this.id = http.requestCnt++, this);
|
|
88
|
+
}
|
|
89
|
+
write (bytes) {
|
|
90
|
+
this.chunks.push(bytes);
|
|
91
|
+
}
|
|
153
92
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
93
|
+
class IncomingResponse {
|
|
94
|
+
/** @type {number} */ id;
|
|
95
|
+
bodyFinished = false;
|
|
96
|
+
status = 0;
|
|
97
|
+
chunks = [];
|
|
98
|
+
body = io.createStream(this);
|
|
99
|
+
/** @type {number | undefined} */ headers = undefined;
|
|
100
|
+
constructor() {
|
|
101
|
+
http.responses.set(this.id = http.responseCnt++, this);
|
|
102
|
+
}
|
|
103
|
+
read (_len) {
|
|
104
|
+
if (this.chunks.length === 0)
|
|
105
|
+
return [new Uint8Array([]), this.bodyFinished ? 'ended' : 'open'];
|
|
106
|
+
if (this.chunks.length === 1)
|
|
107
|
+
return [this.chunks[0], this.bodyFinished ? 'ended' : 'open'];
|
|
108
|
+
return [this.chunks.shift(), 'open'];
|
|
109
|
+
}
|
|
164
110
|
}
|
|
165
|
-
// TODO: implement
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* @param {OutputStream} stream
|
|
170
|
-
* @returns {Pollable}
|
|
171
|
-
*/
|
|
172
|
-
subscribeToOutputStream = (stream) => {
|
|
173
|
-
// TODO: not implemented yet
|
|
174
|
-
console.log(`[streams] Subscribe to output stream ${stream}`);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* @param {OutputStream} stream
|
|
179
|
-
*/
|
|
180
|
-
dropOutputStream = (stream) => {
|
|
181
|
-
const s = this.streams.get(stream);
|
|
182
|
-
if (!s) throw Error(`no such output stream ${stream}`);
|
|
183
|
-
s.set([]);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* @param {Fields} fields
|
|
188
|
-
*/
|
|
189
|
-
dropFields = (fields) => {
|
|
190
|
-
this.fields.delete(fields);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* @param {[string, string][]} entries
|
|
195
|
-
* @returns {Fields}
|
|
196
|
-
*/
|
|
197
|
-
newFields = (entries) => {
|
|
198
|
-
const id = this.fieldsIdBase;
|
|
199
|
-
this.fieldsIdBase += 1;
|
|
200
|
-
this.fields.set(id, new ActiveFields(id, entries));
|
|
201
|
-
|
|
202
|
-
return id;
|
|
203
|
-
}
|
|
204
111
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* @param {OutgoingRequest} request
|
|
216
|
-
*/
|
|
217
|
-
dropOutgoingRequest = (request) => {
|
|
218
|
-
this.requests.delete(request);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* @param {Method} method
|
|
223
|
-
* @param {string | null} pathWithQuery
|
|
224
|
-
* @param {Scheme | null} scheme
|
|
225
|
-
* @param {string | null} authority
|
|
226
|
-
* @param {Headers} headers
|
|
227
|
-
* @returns {number}
|
|
228
|
-
*/
|
|
229
|
-
newOutgoingRequest = (method, pathWithQuery, scheme, authority, headers) => {
|
|
230
|
-
const id = this.requestIdBase;
|
|
231
|
-
this.requestIdBase += 1;
|
|
232
|
-
|
|
233
|
-
const req = new ActiveRequest(id);
|
|
234
|
-
req.pathWithQuery = pathWithQuery;
|
|
235
|
-
req.authority = authority;
|
|
236
|
-
req.method = method;
|
|
237
|
-
req.headers = headers;
|
|
238
|
-
req.scheme = scheme;
|
|
239
|
-
this.requests.set(id, req);
|
|
240
|
-
return id;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* @param {OutgoingRequest} request
|
|
245
|
-
* @returns {OutgoingStream}
|
|
246
|
-
*/
|
|
247
|
-
outgoingRequestWrite = (request) => {
|
|
248
|
-
const req = this.requests.get(request);
|
|
249
|
-
req.body = this.streamIdBase;
|
|
250
|
-
this.streamIdBase += 1;
|
|
251
|
-
return req.body;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* @param {IncomingResponse} response
|
|
256
|
-
*/
|
|
257
|
-
dropIncomingResponse = (response) => {
|
|
258
|
-
this.responses.delete(response);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* @param {IncomingResponse} response
|
|
263
|
-
* @returns {StatusCode}
|
|
264
|
-
*/
|
|
265
|
-
incomingResponseStatus = (response) => {
|
|
266
|
-
const r = this.responses.get(response);
|
|
267
|
-
return r.status;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* @param {IncomingResponse} response
|
|
272
|
-
* @returns {Headers}
|
|
273
|
-
*/
|
|
274
|
-
incomingResponseHeaders = (response) => {
|
|
275
|
-
const r = this.responses.get(response);
|
|
276
|
-
return r.headers ?? 0;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* @param {IncomingResponse} response
|
|
281
|
-
* @returns {IncomingStream}
|
|
282
|
-
*/
|
|
283
|
-
incomingResponseConsume = (response) => {
|
|
284
|
-
const r = this.responses.get(response);
|
|
285
|
-
return r.body;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* @param {FutureIncomingResponse} future
|
|
290
|
-
*/
|
|
291
|
-
dropFutureIncomingResponse = (future) => {
|
|
292
|
-
return this.futures.delete(future);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* @param {FutureIncomingResponse} future
|
|
297
|
-
* @returns {Result<IncomingResponse, Error> | null}
|
|
298
|
-
*/
|
|
299
|
-
futureIncomingResponseGet = (future) => {
|
|
300
|
-
const f = this.futures.get(future);
|
|
301
|
-
if (!f) {
|
|
302
|
-
return {
|
|
303
|
-
tag: "err",
|
|
304
|
-
val: UnexpectedError(`no such future ${f}`),
|
|
305
|
-
};
|
|
112
|
+
class Future {
|
|
113
|
+
/** @type {number} */ id;
|
|
114
|
+
/** @type {number} */ responseId;
|
|
115
|
+
|
|
116
|
+
constructor(responseId) {
|
|
117
|
+
http.futures.set(this.id = http.futureCnt++, this);
|
|
118
|
+
this.responseId = responseId;
|
|
119
|
+
}
|
|
306
120
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
121
|
+
|
|
122
|
+
class Fields {
|
|
123
|
+
/** @type {number} */ id;
|
|
124
|
+
/** @type {Map<string, Uint8Array[]>} */ fields;
|
|
125
|
+
|
|
126
|
+
constructor(fields) {
|
|
127
|
+
http.fields.set(this.id = http.fieldsCnt++, this);
|
|
128
|
+
const encoder = new TextEncoder();
|
|
129
|
+
this.fields = new Map(fields.map(([k, v]) => [k, encoder.encode(v)]));
|
|
130
|
+
}
|
|
316
131
|
}
|
|
317
|
-
return {
|
|
318
|
-
tag: "ok",
|
|
319
|
-
val: response,
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
132
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
/** @type {Method} */ method = { tag: 'get' };
|
|
328
|
-
/** @type {Scheme | null} */ scheme = { tag: 'HTTP' };
|
|
329
|
-
pathWithQuery = null;
|
|
330
|
-
authority = null;
|
|
331
|
-
/** @type {number | null} */ headers = null;
|
|
332
|
-
body = 3;
|
|
333
|
-
|
|
334
|
-
constructor(id) {
|
|
335
|
-
this.id = id;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
class ActiveResponse {
|
|
340
|
-
/** @type {number} */ id;
|
|
341
|
-
activeResponse = false;
|
|
342
|
-
status = 0;
|
|
343
|
-
body = 3;
|
|
344
|
-
/** @type {number | null} */ headers = null;
|
|
133
|
+
this.incomingHandler = {
|
|
134
|
+
// TODO
|
|
135
|
+
handle () {
|
|
345
136
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
class ActiveFuture {
|
|
352
|
-
/** @type {number} */ id;
|
|
353
|
-
/** @type {number} */ responseId;
|
|
354
|
-
|
|
355
|
-
constructor(id, responseId) {
|
|
356
|
-
this.id = id;
|
|
357
|
-
this.responseId = responseId;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
360
139
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
140
|
+
this.outgoingHandler = {
|
|
141
|
+
/**
|
|
142
|
+
* @param {OutgoingRequest} requestId
|
|
143
|
+
* @param {RequestOptions | undefined} options
|
|
144
|
+
* @returns {FutureIncomingResponse}
|
|
145
|
+
*/
|
|
146
|
+
handle (requestId, _options) {
|
|
147
|
+
const request = http.requests.get(requestId);
|
|
148
|
+
if (!request) throw Error("not found!");
|
|
149
|
+
|
|
150
|
+
const response = new IncomingResponse();
|
|
151
|
+
|
|
152
|
+
const scheme = request.scheme.tag === "HTTP" ? "http://" : "https://";
|
|
153
|
+
|
|
154
|
+
const url = scheme + request.authority + request.pathWithQuery;
|
|
155
|
+
const headers = {
|
|
156
|
+
"host": request.authority,
|
|
157
|
+
};
|
|
158
|
+
if (request.headers) {
|
|
159
|
+
const requestHeaders = http.fields.get(request.headers);
|
|
160
|
+
const decoder = new TextDecoder();
|
|
161
|
+
for (const [key, value] of requestHeaders.fields.entries()) {
|
|
162
|
+
headers[key] = decoder.decode(value);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const res = send({
|
|
167
|
+
method: request.method.tag,
|
|
168
|
+
uri: url,
|
|
169
|
+
headers: headers,
|
|
170
|
+
params: [],
|
|
171
|
+
body: combineChunks(request.chunks),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
response.status = res.status;
|
|
175
|
+
if (res.headers && res.headers.length > 0) {
|
|
176
|
+
response.headers = types.newFields(res.headers);
|
|
177
|
+
}
|
|
178
|
+
http.responses.set(response.id, response);
|
|
179
|
+
response.chunks = [res.body];
|
|
180
|
+
|
|
181
|
+
const future = new Future(response.id);
|
|
182
|
+
return future.id;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
364
185
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
186
|
+
const types = this.types = {
|
|
187
|
+
/**
|
|
188
|
+
* @param {Fields} fields
|
|
189
|
+
*/
|
|
190
|
+
dropFields(fields) {
|
|
191
|
+
http.fields.delete(fields);
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* @param {[string, string][]} entries
|
|
196
|
+
* @returns {Fields}
|
|
197
|
+
*/
|
|
198
|
+
newFields(entries) {
|
|
199
|
+
return new Fields(entries).id;
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
fieldsGet(_fields, _name) {
|
|
203
|
+
console.log("[types] Fields get");
|
|
204
|
+
},
|
|
205
|
+
fieldsSet(_fields, _name, _value) {
|
|
206
|
+
console.log("[types] Fields set");
|
|
207
|
+
},
|
|
208
|
+
fieldsDelete(_fields, _name) {
|
|
209
|
+
console.log("[types] Fields delete");
|
|
210
|
+
},
|
|
211
|
+
fieldsAppend(_fields, _name, _value) {
|
|
212
|
+
console.log("[types] Fields append");
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @param {Fields} fields
|
|
217
|
+
* @returns {[string, Uint8Array][]}
|
|
218
|
+
*/
|
|
219
|
+
fieldsEntries(fields) {
|
|
220
|
+
const activeFields = http.fields.get(fields);
|
|
221
|
+
return activeFields ? Array.from(activeFields.fields) : [];
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
fieldsClone(_fields) {
|
|
225
|
+
console.log("[types] Fields clone");
|
|
226
|
+
},
|
|
227
|
+
finishIncomingStream(s) {
|
|
228
|
+
io.getStream(s).bodyFinished = true;
|
|
229
|
+
},
|
|
230
|
+
finishOutgoingStream(s, _trailers) {
|
|
231
|
+
io.getStream(s).bodyFinished = true;
|
|
232
|
+
},
|
|
233
|
+
dropIncomingRequest(_req) {
|
|
234
|
+
console.log("[types] Drop incoming request");
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* @param {OutgoingRequest} request
|
|
239
|
+
*/
|
|
240
|
+
dropOutgoingRequest(request) {
|
|
241
|
+
http.requests.delete(request);
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
incomingRequestMethod(_req) {
|
|
245
|
+
console.log("[types] Incoming request method");
|
|
246
|
+
},
|
|
247
|
+
incomingRequestPathWithQuery(_req) {
|
|
248
|
+
console.log("[types] Incoming request path with query");
|
|
249
|
+
},
|
|
250
|
+
incomingRequestScheme(_req) {
|
|
251
|
+
console.log("[types] Incoming request scheme");
|
|
252
|
+
},
|
|
253
|
+
incomingRequestAuthority(_req) {
|
|
254
|
+
console.log("[types] Incoming request authority");
|
|
255
|
+
},
|
|
256
|
+
incomingRequestHeaders(_req) {
|
|
257
|
+
console.log("[types] Incoming request headers");
|
|
258
|
+
},
|
|
259
|
+
incomingRequestConsume(_req) {
|
|
260
|
+
console.log("[types] Incoming request consume");
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* @param {Method} method
|
|
265
|
+
* @param {string | undefined} pathWithQuery
|
|
266
|
+
* @param {Scheme | undefined} scheme
|
|
267
|
+
* @param {string | undefined} authority
|
|
268
|
+
* @param {Headers} headers
|
|
269
|
+
* @returns {number}
|
|
270
|
+
*/
|
|
271
|
+
newOutgoingRequest(method, pathWithQuery, scheme, authority, headers) {
|
|
272
|
+
const req = new OutgoingRequest();
|
|
273
|
+
req.pathWithQuery = pathWithQuery;
|
|
274
|
+
req.authority = authority;
|
|
275
|
+
req.method = method;
|
|
276
|
+
req.headers = headers;
|
|
277
|
+
req.scheme = scheme;
|
|
278
|
+
return req.id;
|
|
279
|
+
},
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @param {OutgoingRequest} request
|
|
283
|
+
* @returns {OutgoingStream}
|
|
284
|
+
*/
|
|
285
|
+
outgoingRequestWrite(request) {
|
|
286
|
+
return http.requests.get(request).body;
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
dropResponseOutparam(_res) {
|
|
290
|
+
console.log("[types] Drop response outparam");
|
|
291
|
+
},
|
|
292
|
+
setResponseOutparam(_response) {
|
|
293
|
+
console.log("[types] Set response outparam");
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* @param {IncomingResponse} response
|
|
298
|
+
*/
|
|
299
|
+
dropIncomingResponse(response) {
|
|
300
|
+
http.responses.delete(response);
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
dropOutgoingResponse(_res) {
|
|
304
|
+
console.log("[types] Drop outgoing response");
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @param {IncomingResponse} response
|
|
309
|
+
* @returns {StatusCode}
|
|
310
|
+
*/
|
|
311
|
+
incomingResponseStatus(response) {
|
|
312
|
+
const r = http.responses.get(response);
|
|
313
|
+
return r.status;
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @param {IncomingResponse} response
|
|
318
|
+
* @returns {Headers}
|
|
319
|
+
*/
|
|
320
|
+
incomingResponseHeaders(response) {
|
|
321
|
+
const r = http.responses.get(response);
|
|
322
|
+
return r.headers ?? 0;
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* @param {IncomingResponse} response
|
|
327
|
+
* @returns {IncomingStream}
|
|
328
|
+
*/
|
|
329
|
+
incomingResponseConsume(response) {
|
|
330
|
+
const r = http.responses.get(response);
|
|
331
|
+
return r.body;
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
newOutgoingResponse(_statusCode, _headers) {
|
|
335
|
+
console.log("[types] New outgoing response");
|
|
336
|
+
},
|
|
337
|
+
outgoingResponseWrite(_res) {
|
|
338
|
+
console.log("[types] Outgoing response write");
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* @param {FutureIncomingResponse} future
|
|
344
|
+
*/
|
|
345
|
+
dropFutureIncomingResponse(future) {
|
|
346
|
+
return http.futures.delete(future);
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @param {FutureIncomingResponse} future
|
|
351
|
+
* @returns {Result<IncomingResponse, Error> | undefined}
|
|
352
|
+
*/
|
|
353
|
+
futureIncomingResponseGet(future) {
|
|
354
|
+
const f = http.futures.get(future);
|
|
355
|
+
if (!f) {
|
|
356
|
+
return {
|
|
357
|
+
tag: "err",
|
|
358
|
+
val: UnexpectedError(`no such future ${f}`),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
// For now this will assume the future will return
|
|
362
|
+
// the response immediately
|
|
363
|
+
const response = f.responseId;
|
|
364
|
+
const r = http.responses.get(response);
|
|
365
|
+
if (!r) {
|
|
366
|
+
return {
|
|
367
|
+
tag: "err",
|
|
368
|
+
val: UnexpectedError(`no such response ${response}`),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
tag: "ok",
|
|
373
|
+
val: response,
|
|
374
|
+
};
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
listenToFutureIncomingResponse(_f) {
|
|
378
|
+
console.log("[types] Listen to future incoming response");
|
|
379
|
+
}
|
|
380
|
+
};
|
|
369
381
|
}
|
|
370
382
|
}
|