@bytecodealliance/preview2-shim 0.14.0 → 0.14.2
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/README.md +2 -2
- package/lib/browser/filesystem.js +6 -5
- package/lib/browser/http.js +1 -3
- package/lib/browser/random.js +1 -1
- package/lib/io/calls.js +128 -1
- package/lib/io/worker-http.js +159 -65
- package/lib/io/worker-io.js +40 -43
- package/lib/io/worker-socket-tcp.js +131 -0
- package/lib/io/worker-socket-udp.js +219 -0
- package/lib/io/worker-thread.js +288 -82
- package/lib/nodejs/cli.js +27 -11
- package/lib/nodejs/filesystem.js +89 -38
- package/lib/nodejs/http.js +643 -522
- package/lib/nodejs/index.js +0 -1
- package/lib/nodejs/sockets/socket-common.js +15 -2
- package/lib/nodejs/sockets/tcp-socket-impl.js +279 -188
- package/lib/nodejs/sockets/udp-socket-impl.js +305 -165
- package/lib/nodejs/sockets/wasi-sockets.js +54 -33
- package/lib/nodejs/sockets.js +25 -11
- package/lib/synckit/index.js +22 -39
- package/package.json +1 -1
- package/types/interfaces/wasi-http-types.d.ts +53 -41
- package/types/interfaces/wasi-sockets-tcp.d.ts +5 -0
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
} from "../../io/calls.js";
|
|
17
17
|
import { ioCall, pollableCreate } from "../../io/worker-io.js";
|
|
18
18
|
import { deserializeIpAddress } from "./socket-common.js";
|
|
19
|
-
import {
|
|
20
|
-
import { IncomingDatagramStream, OutgoingDatagramStream,
|
|
19
|
+
import { TcpSocket, tcpSocketImplCreate } from "./tcp-socket-impl.js";
|
|
20
|
+
import { IncomingDatagramStream, OutgoingDatagramStream, UdpSocket, udpSocketImplCreate } from "./udp-socket-impl.js";
|
|
21
21
|
|
|
22
22
|
const symbolDispose = Symbol.dispose || Symbol.for("dispose");
|
|
23
23
|
|
|
@@ -120,11 +120,14 @@ export const IpAddressFamily = {
|
|
|
120
120
|
};
|
|
121
121
|
|
|
122
122
|
export class WasiSockets {
|
|
123
|
+
#allowDnsLookup = true;
|
|
124
|
+
#allowTcp = true;
|
|
125
|
+
#allowUdp = true;
|
|
123
126
|
networkCnt = 1;
|
|
124
127
|
socketCnt = 1;
|
|
125
128
|
|
|
126
129
|
// TODO: figure out what the max number of sockets should be
|
|
127
|
-
|
|
130
|
+
MAX_SOCKET_INSTANCES = 100;
|
|
128
131
|
|
|
129
132
|
/** @type {Network} */ networkInstance = null;
|
|
130
133
|
/** @type {Map<number,Network>} */ networks = new Map();
|
|
@@ -141,32 +144,12 @@ export class WasiSockets {
|
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
146
|
|
|
144
|
-
class UdpSocket extends UdpSocketImpl {
|
|
145
|
-
/**
|
|
146
|
-
* @param {IpAddressFamily} addressFamily
|
|
147
|
-
* */
|
|
148
|
-
constructor(addressFamily) {
|
|
149
|
-
super(addressFamily, net.socketCnt++);
|
|
150
|
-
net.udpSockets.set(this.id, this);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
147
|
this.udp = {
|
|
155
148
|
UdpSocket,
|
|
156
149
|
OutgoingDatagramStream,
|
|
157
150
|
IncomingDatagramStream,
|
|
158
151
|
};
|
|
159
152
|
|
|
160
|
-
class TcpSocket extends TcpSocketImpl {
|
|
161
|
-
/**
|
|
162
|
-
* @param {IpAddressFamily} addressFamily
|
|
163
|
-
* */
|
|
164
|
-
constructor(addressFamily) {
|
|
165
|
-
super(addressFamily, TcpSocket, net.socketCnt++);
|
|
166
|
-
net.tcpSockets.set(this.id, this);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
153
|
this.tcp = {
|
|
171
154
|
TcpSocket,
|
|
172
155
|
};
|
|
@@ -199,14 +182,23 @@ export class WasiSockets {
|
|
|
199
182
|
);
|
|
200
183
|
|
|
201
184
|
assert(
|
|
202
|
-
net.socketCnt + 1 > net.
|
|
185
|
+
net.socketCnt + 1 > net.MAX_SOCKET_INSTANCES,
|
|
203
186
|
errorCode.newSocketLimit,
|
|
204
187
|
"The new socket resource could not be created because of a system limit"
|
|
205
188
|
);
|
|
206
189
|
|
|
207
190
|
try {
|
|
208
|
-
|
|
191
|
+
const id = net.socketCnt++;
|
|
192
|
+
const udpSocket = udpSocketImplCreate(addressFamily, id);
|
|
193
|
+
udpSocket.allowed = () => {
|
|
194
|
+
return net.#allowUdp;
|
|
195
|
+
};
|
|
196
|
+
net.udpSockets.set(id, udpSocket);
|
|
197
|
+
return udpSocket;
|
|
209
198
|
} catch (err) {
|
|
199
|
+
console.log("udp socket create error", {
|
|
200
|
+
err,
|
|
201
|
+
});
|
|
210
202
|
assert(true, errorCode.notSupported, err);
|
|
211
203
|
}
|
|
212
204
|
},
|
|
@@ -227,17 +219,25 @@ export class WasiSockets {
|
|
|
227
219
|
);
|
|
228
220
|
|
|
229
221
|
assert(
|
|
230
|
-
net.socketCnt + 1 > net.
|
|
222
|
+
net.socketCnt + 1 > net.MAX_SOCKET_INSTANCES,
|
|
231
223
|
errorCode.newSocketLimit,
|
|
232
224
|
"The new socket resource could not be created because of a system limit"
|
|
233
225
|
);
|
|
234
226
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
227
|
+
try {
|
|
228
|
+
const id = net.socketCnt++;
|
|
229
|
+
const tcpSocket = tcpSocketImplCreate(addressFamily, id);
|
|
230
|
+
tcpSocket.allowed = () => {
|
|
231
|
+
return net.#allowTcp;
|
|
232
|
+
};
|
|
233
|
+
net.tcpSockets.set(id, tcpSocket);
|
|
234
|
+
return tcpSocket;
|
|
235
|
+
} catch (err) {
|
|
236
|
+
console.log("tcp socket create error", {
|
|
237
|
+
err,
|
|
238
|
+
});
|
|
239
|
+
assert(true, errorCode.notSupported, err);
|
|
240
|
+
}
|
|
241
241
|
},
|
|
242
242
|
};
|
|
243
243
|
|
|
@@ -255,7 +255,7 @@ export class WasiSockets {
|
|
|
255
255
|
const family = `ipv${isIP(address)}`;
|
|
256
256
|
return {
|
|
257
257
|
tag: family,
|
|
258
|
-
val: deserializeIpAddress(address),
|
|
258
|
+
val: deserializeIpAddress(address, family),
|
|
259
259
|
};
|
|
260
260
|
});
|
|
261
261
|
}
|
|
@@ -305,13 +305,34 @@ export class WasiSockets {
|
|
|
305
305
|
* @throws {invalid-argument} `name` is a syntactically invalid domain name or IP address.
|
|
306
306
|
*/
|
|
307
307
|
resolveAddresses(network, name) {
|
|
308
|
+
if (!net.#allowDnsLookup)
|
|
309
|
+
throw 'permanent-resolver-failure';
|
|
308
310
|
// TODO: bind to network
|
|
309
311
|
return resolveAddressStreamCreate(name);
|
|
310
312
|
},
|
|
311
313
|
};
|
|
312
314
|
}
|
|
315
|
+
|
|
316
|
+
static _denyDnsLookup (sockets) {
|
|
317
|
+
sockets.#allowDnsLookup = false;
|
|
318
|
+
}
|
|
319
|
+
static _denyTcp (sockets) {
|
|
320
|
+
sockets.#allowTcp = false;
|
|
321
|
+
}
|
|
322
|
+
static _denyUdp (sockets) {
|
|
323
|
+
sockets.#allowUdp = false;
|
|
324
|
+
}
|
|
313
325
|
}
|
|
314
326
|
|
|
327
|
+
export const denyDnsLookup = WasiSockets._denyDnsLookup;
|
|
328
|
+
delete WasiSockets._denyDnsLookup;
|
|
329
|
+
|
|
330
|
+
export const denyTcp = WasiSockets._denyTcp;
|
|
331
|
+
delete WasiSockets._denyTcp;
|
|
332
|
+
|
|
333
|
+
export const denyUdp = WasiSockets._denyUdp;
|
|
334
|
+
delete WasiSockets._denyUdp;
|
|
335
|
+
|
|
315
336
|
function convertResolveAddressError(err) {
|
|
316
337
|
switch (err.code) {
|
|
317
338
|
default:
|
package/lib/nodejs/sockets.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
|
-
import { WasiSockets } from "./sockets/wasi-sockets.js";
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { WasiSockets, denyDnsLookup, denyTcp, denyUdp } from "./sockets/wasi-sockets.js";
|
|
2
|
+
|
|
3
|
+
export function _denyDnsLookup() {
|
|
4
|
+
denyDnsLookup(sockets);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function _denyTcp() {
|
|
8
|
+
denyTcp(sockets);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function _denyUdp() {
|
|
12
|
+
denyUdp(sockets);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const sockets = new WasiSockets();
|
|
16
|
+
|
|
17
|
+
export const {
|
|
18
|
+
ipNameLookup,
|
|
19
|
+
instanceNetwork,
|
|
20
|
+
network,
|
|
21
|
+
tcpCreateSocket,
|
|
22
|
+
udpCreateSocket,
|
|
23
|
+
tcp,
|
|
24
|
+
udp,
|
|
25
|
+
} = sockets;
|
package/lib/synckit/index.js
CHANGED
|
@@ -33,7 +33,6 @@ import {
|
|
|
33
33
|
} from "node:worker_threads";
|
|
34
34
|
|
|
35
35
|
const DEFAULT_WORKER_BUFFER_SIZE = 1024;
|
|
36
|
-
const syncFnCache = new Map();
|
|
37
36
|
|
|
38
37
|
function extractProperties(object) {
|
|
39
38
|
if (object && typeof object === "object") {
|
|
@@ -45,61 +44,45 @@ function extractProperties(object) {
|
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
const CALL_TIMEOUT = undefined;
|
|
48
|
+
|
|
49
|
+
export function createSyncFn(workerPath, callbackHandler) {
|
|
49
50
|
if (!path.isAbsolute(workerPath)) {
|
|
50
51
|
throw new Error("`workerPath` must be absolute");
|
|
51
52
|
}
|
|
52
|
-
const cachedSyncFn = syncFnCache.get(workerPath);
|
|
53
|
-
if (cachedSyncFn) {
|
|
54
|
-
return cachedSyncFn;
|
|
55
|
-
}
|
|
56
|
-
const syncFn = startWorkerThread(
|
|
57
|
-
workerPath,
|
|
58
|
-
typeof bufferSizeOrOptions === "number"
|
|
59
|
-
? { bufferSize: bufferSizeOrOptions, timeout }
|
|
60
|
-
: bufferSizeOrOptions
|
|
61
|
-
);
|
|
62
|
-
syncFnCache.set(workerPath, syncFn);
|
|
63
|
-
return syncFn;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function startWorkerThread(
|
|
67
|
-
workerPath,
|
|
68
|
-
{
|
|
69
|
-
bufferSize = DEFAULT_WORKER_BUFFER_SIZE,
|
|
70
|
-
timeout = undefined,
|
|
71
|
-
execArgv = [],
|
|
72
|
-
} = {}
|
|
73
|
-
) {
|
|
74
53
|
const { port1: mainPort, port2: workerPort } = new MessageChannel();
|
|
75
54
|
const worker = new Worker(workerPath, {
|
|
76
55
|
workerData: { workerPort },
|
|
77
56
|
transferList: [workerPort],
|
|
78
|
-
execArgv:
|
|
57
|
+
execArgv: []
|
|
58
|
+
});
|
|
59
|
+
worker.on('message', ({ type, id, payload }) => {
|
|
60
|
+
if (!type)
|
|
61
|
+
throw new Error('Internal error: Expected a type of a worker callback');
|
|
62
|
+
callbackHandler(type, id, payload);
|
|
79
63
|
});
|
|
80
64
|
let nextID = 0;
|
|
81
65
|
const syncFn = (...args) => {
|
|
82
|
-
const
|
|
83
|
-
const sharedBuffer = new SharedArrayBuffer(
|
|
66
|
+
const cid = nextID++;
|
|
67
|
+
const sharedBuffer = new SharedArrayBuffer(DEFAULT_WORKER_BUFFER_SIZE);
|
|
84
68
|
const sharedBufferView = new Int32Array(sharedBuffer);
|
|
85
|
-
const msg = { sharedBuffer,
|
|
69
|
+
const msg = { sharedBuffer, cid, args };
|
|
86
70
|
worker.postMessage(msg);
|
|
87
|
-
const status = Atomics.wait(sharedBufferView, 0, 0,
|
|
71
|
+
const status = Atomics.wait(sharedBufferView, 0, 0, CALL_TIMEOUT);
|
|
88
72
|
if (!["ok", "not-equal"].includes(status)) {
|
|
89
73
|
throw new Error("Internal error: Atomics.wait() failed: " + status);
|
|
90
74
|
}
|
|
91
75
|
const {
|
|
92
|
-
|
|
76
|
+
cid: cid2,
|
|
93
77
|
result,
|
|
94
78
|
error,
|
|
95
79
|
properties,
|
|
96
80
|
} = receiveMessageOnPort(mainPort).message;
|
|
97
|
-
if (
|
|
98
|
-
throw new Error(`Internal error: Expected id ${
|
|
81
|
+
if (cid !== cid2) {
|
|
82
|
+
throw new Error(`Internal error: Expected id ${cid} but got id ${cid2}`);
|
|
99
83
|
}
|
|
100
84
|
if (error) {
|
|
101
|
-
if (error instanceof Error)
|
|
102
|
-
throw Object.assign(error, properties);
|
|
85
|
+
if (error instanceof Error) throw Object.assign(error, properties);
|
|
103
86
|
throw error;
|
|
104
87
|
}
|
|
105
88
|
return result;
|
|
@@ -114,14 +97,14 @@ export function runAsWorker(fn) {
|
|
|
114
97
|
}
|
|
115
98
|
const { workerPort } = workerData;
|
|
116
99
|
try {
|
|
117
|
-
parentPort.on("message", ({ sharedBuffer,
|
|
100
|
+
parentPort.on("message", ({ sharedBuffer, cid, args }) => {
|
|
118
101
|
(async () => {
|
|
119
102
|
const sharedBufferView = new Int32Array(sharedBuffer);
|
|
120
103
|
let msg;
|
|
121
104
|
try {
|
|
122
|
-
msg = {
|
|
105
|
+
msg = { cid, result: await fn(...args) };
|
|
123
106
|
} catch (error) {
|
|
124
|
-
msg = {
|
|
107
|
+
msg = { cid, error, properties: extractProperties(error) };
|
|
125
108
|
}
|
|
126
109
|
workerPort.postMessage(msg);
|
|
127
110
|
Atomics.add(sharedBufferView, 0, 1);
|
|
@@ -129,10 +112,10 @@ export function runAsWorker(fn) {
|
|
|
129
112
|
})();
|
|
130
113
|
});
|
|
131
114
|
} catch (error) {
|
|
132
|
-
parentPort.on("message", ({ sharedBuffer,
|
|
115
|
+
parentPort.on("message", ({ sharedBuffer, cid }) => {
|
|
133
116
|
const sharedBufferView = new Int32Array(sharedBuffer);
|
|
134
117
|
workerPort.postMessage({
|
|
135
|
-
|
|
118
|
+
cid,
|
|
136
119
|
error,
|
|
137
120
|
properties: extractProperties(error),
|
|
138
121
|
});
|
package/package.json
CHANGED
|
@@ -37,7 +37,14 @@ export namespace WasiHttpTypes {
|
|
|
37
37
|
* syntactically invalid, or if a header was forbidden.
|
|
38
38
|
*/
|
|
39
39
|
/**
|
|
40
|
-
* Get all of the values corresponding to a key.
|
|
40
|
+
* Get all of the values corresponding to a key. If the key is not present
|
|
41
|
+
* in this `fields`, an empty list is returned. However, if the key is
|
|
42
|
+
* present but empty, this is represented by a list with one or more
|
|
43
|
+
* empty field-values present.
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Returns `true` when the key is present in this `fields`. If the key is
|
|
47
|
+
* syntactically invalid, `false` is returned.
|
|
41
48
|
*/
|
|
42
49
|
/**
|
|
43
50
|
* Set all of the values for a key. Clears any existing values for that
|
|
@@ -255,10 +262,14 @@ export namespace WasiHttpTypes {
|
|
|
255
262
|
* The outer `option` represents future readiness. Users can wait on this
|
|
256
263
|
* `option` to become `some` using the `subscribe` method.
|
|
257
264
|
*
|
|
258
|
-
* The `result`
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
265
|
+
* The outer `result` is used to retrieve the trailers or error at most
|
|
266
|
+
* once. It will be success on the first call in which the outer option
|
|
267
|
+
* is `some`, and error on subsequent calls.
|
|
268
|
+
*
|
|
269
|
+
* The inner `result` represents that either the HTTP Request or Response
|
|
270
|
+
* body, as well as any trailers, were received successfully, or that an
|
|
271
|
+
* error occured receiving them. The optional `trailers` indicates whether
|
|
272
|
+
* or not trailers were present in the body.
|
|
262
273
|
*
|
|
263
274
|
* When some `trailers` are returned by this method, the `trailers`
|
|
264
275
|
* resource is immutable, and a child. Use of the `set`, `append`, or
|
|
@@ -349,7 +360,7 @@ import type { InputStream } from '../interfaces/wasi-io-streams.js';
|
|
|
349
360
|
export { InputStream };
|
|
350
361
|
import type { OutputStream } from '../interfaces/wasi-io-streams.js';
|
|
351
362
|
export { OutputStream };
|
|
352
|
-
import type { IoError } from '../interfaces/wasi-io-error.js';
|
|
363
|
+
import type { Error as IoError } from '../interfaces/wasi-io-error.js';
|
|
353
364
|
export { IoError };
|
|
354
365
|
import type { Pollable } from '../interfaces/wasi-io-poll.js';
|
|
355
366
|
export { Pollable };
|
|
@@ -618,15 +629,16 @@ export type Trailers = Fields;
|
|
|
618
629
|
export type StatusCode = number;
|
|
619
630
|
export type Result<T, E> = { tag: 'ok', val: T } | { tag: 'err', val: E };
|
|
620
631
|
|
|
621
|
-
export class
|
|
622
|
-
|
|
623
|
-
|
|
632
|
+
export class OutgoingBody {
|
|
633
|
+
write(): OutputStream;
|
|
634
|
+
static finish(this_: OutgoingBody, trailers: Trailers | undefined): void;
|
|
624
635
|
}
|
|
625
636
|
|
|
626
637
|
export class Fields {
|
|
627
638
|
constructor()
|
|
628
639
|
static fromList(entries: [FieldKey, FieldValue][]): Fields;
|
|
629
640
|
get(name: FieldKey): FieldValue[];
|
|
641
|
+
has(name: FieldKey): boolean;
|
|
630
642
|
set(name: FieldKey, value: FieldValue[]): void;
|
|
631
643
|
delete(name: FieldKey): void;
|
|
632
644
|
append(name: FieldKey, value: FieldValue): void;
|
|
@@ -634,33 +646,18 @@ export class Fields {
|
|
|
634
646
|
clone(): Fields;
|
|
635
647
|
}
|
|
636
648
|
|
|
637
|
-
export class
|
|
649
|
+
export class FutureIncomingResponse {
|
|
638
650
|
subscribe(): Pollable;
|
|
639
|
-
get(): Result<
|
|
651
|
+
get(): Result<Result<IncomingResponse, ErrorCode>, void> | undefined;
|
|
640
652
|
}
|
|
641
653
|
|
|
642
|
-
export class
|
|
643
|
-
constructor(headers: Headers)
|
|
644
|
-
body(): OutgoingBody;
|
|
654
|
+
export class IncomingRequest {
|
|
645
655
|
method(): Method;
|
|
646
|
-
setMethod(method: Method): void;
|
|
647
656
|
pathWithQuery(): string | undefined;
|
|
648
|
-
setPathWithQuery(pathWithQuery: string | undefined): void;
|
|
649
657
|
scheme(): Scheme | undefined;
|
|
650
|
-
setScheme(scheme: Scheme | undefined): void;
|
|
651
658
|
authority(): string | undefined;
|
|
652
|
-
setAuthority(authority: string | undefined): void;
|
|
653
659
|
headers(): Headers;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
export class RequestOptions {
|
|
657
|
-
constructor()
|
|
658
|
-
connectTimeoutMs(): Duration | undefined;
|
|
659
|
-
setConnectTimeoutMs(ms: Duration | undefined): void;
|
|
660
|
-
firstByteTimeoutMs(): Duration | undefined;
|
|
661
|
-
setFirstByteTimeoutMs(ms: Duration | undefined): void;
|
|
662
|
-
betweenBytesTimeoutMs(): Duration | undefined;
|
|
663
|
-
setBetweenBytesTimeoutMs(ms: Duration | undefined): void;
|
|
660
|
+
consume(): IncomingBody;
|
|
664
661
|
}
|
|
665
662
|
|
|
666
663
|
export class IncomingBody {
|
|
@@ -668,15 +665,13 @@ export class IncomingBody {
|
|
|
668
665
|
static finish(this_: IncomingBody): FutureTrailers;
|
|
669
666
|
}
|
|
670
667
|
|
|
671
|
-
export class
|
|
672
|
-
|
|
668
|
+
export class FutureTrailers {
|
|
669
|
+
subscribe(): Pollable;
|
|
670
|
+
get(): Result<Result<Trailers | undefined, ErrorCode>, void> | undefined;
|
|
673
671
|
}
|
|
674
672
|
|
|
675
|
-
export class
|
|
676
|
-
|
|
677
|
-
pathWithQuery(): string | undefined;
|
|
678
|
-
scheme(): Scheme | undefined;
|
|
679
|
-
authority(): string | undefined;
|
|
673
|
+
export class IncomingResponse {
|
|
674
|
+
status(): StatusCode;
|
|
680
675
|
headers(): Headers;
|
|
681
676
|
consume(): IncomingBody;
|
|
682
677
|
}
|
|
@@ -689,13 +684,30 @@ export class OutgoingResponse {
|
|
|
689
684
|
body(): OutgoingBody;
|
|
690
685
|
}
|
|
691
686
|
|
|
692
|
-
export class
|
|
693
|
-
|
|
687
|
+
export class OutgoingRequest {
|
|
688
|
+
constructor(headers: Headers)
|
|
689
|
+
body(): OutgoingBody;
|
|
690
|
+
method(): Method;
|
|
691
|
+
setMethod(method: Method): void;
|
|
692
|
+
pathWithQuery(): string | undefined;
|
|
693
|
+
setPathWithQuery(pathWithQuery: string | undefined): void;
|
|
694
|
+
scheme(): Scheme | undefined;
|
|
695
|
+
setScheme(scheme: Scheme | undefined): void;
|
|
696
|
+
authority(): string | undefined;
|
|
697
|
+
setAuthority(authority: string | undefined): void;
|
|
694
698
|
headers(): Headers;
|
|
695
|
-
consume(): IncomingBody;
|
|
696
699
|
}
|
|
697
700
|
|
|
698
|
-
export class
|
|
699
|
-
|
|
700
|
-
|
|
701
|
+
export class RequestOptions {
|
|
702
|
+
constructor()
|
|
703
|
+
connectTimeout(): Duration | undefined;
|
|
704
|
+
setConnectTimeout(duration: Duration | undefined): void;
|
|
705
|
+
firstByteTimeout(): Duration | undefined;
|
|
706
|
+
setFirstByteTimeout(duration: Duration | undefined): void;
|
|
707
|
+
betweenBytesTimeout(): Duration | undefined;
|
|
708
|
+
setBetweenBytesTimeout(duration: Duration | undefined): void;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
export class ResponseOutparam {
|
|
712
|
+
static set(param: ResponseOutparam, response: Result<OutgoingResponse, ErrorCode>): void;
|
|
701
713
|
}
|
|
@@ -24,6 +24,11 @@ export namespace WasiSocketsTcp {
|
|
|
24
24
|
* - `not-in-progress`: A `bind` operation is not in progress.
|
|
25
25
|
* - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
|
|
26
26
|
*
|
|
27
|
+
* # Implementors note
|
|
28
|
+
* When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT
|
|
29
|
+
* state of a recently closed socket on the same local address (i.e. the SO_REUSEADDR socket
|
|
30
|
+
* option should be set implicitly on platforms that require it).
|
|
31
|
+
*
|
|
27
32
|
* # References
|
|
28
33
|
* - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html>
|
|
29
34
|
* - <https://man7.org/linux/man-pages/man2/bind.2.html>
|