summaryrefslogtreecommitdiff
path: root/ext/net/01_net.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/net/01_net.js')
-rw-r--r--ext/net/01_net.js242
1 files changed, 84 insertions, 158 deletions
diff --git a/ext/net/01_net.js b/ext/net/01_net.js
index acd8ee179..d7a093ba6 100644
--- a/ext/net/01_net.js
+++ b/ext/net/01_net.js
@@ -10,10 +10,10 @@
Error,
ObjectPrototypeIsPrototypeOf,
PromiseResolve,
+ Symbol,
SymbolAsyncIterator,
SymbolFor,
TypedArrayPrototypeSubarray,
- TypeError,
Uint8Array,
} = window.__bootstrap.primordials;
@@ -38,6 +38,30 @@
return core.shutdown(rid);
}
+ function opAccept(rid, transport) {
+ return core.opAsync("op_net_accept", { rid, transport });
+ }
+
+ function opListen(args) {
+ return ops.op_net_listen(args);
+ }
+
+ function opConnect(args) {
+ return core.opAsync("op_net_connect", args);
+ }
+
+ function opReceive(rid, transport, zeroCopy) {
+ return core.opAsync(
+ "op_dgram_recv",
+ { rid, transport },
+ zeroCopy,
+ );
+ }
+
+ function opSend(args, zeroCopy) {
+ return core.opAsync("op_dgram_send", args, zeroCopy);
+ }
+
function resolveDns(query, recordType, options) {
return core.opAsync("op_dns_resolve", { query, recordType, options });
}
@@ -111,6 +135,11 @@
class UnixConn extends Conn {}
+ // Use symbols for method names to hide these in stable API.
+ // TODO(kt3k): Remove these symbols when ref/unref become stable.
+ const listenerRef = Symbol("listenerRef");
+ const listenerUnref = Symbol("listenerUnref");
+
class Listener {
#rid = 0;
#addr = null;
@@ -130,35 +159,21 @@
return this.#addr;
}
- async accept() {
- let promise;
- switch (this.addr.transport) {
- case "tcp":
- promise = core.opAsync("op_net_accept_tcp", this.rid);
- break;
- case "unix":
- promise = core.opAsync("op_net_accept_unix", this.rid);
- break;
- default:
- throw new Error(`Unsupported transport: ${this.addr.transport}`);
- }
+ accept() {
+ const promise = opAccept(this.rid, this.addr.transport);
this.#promiseId = promise[promiseIdSymbol];
- if (this.#unref) core.unrefOp(this.#promiseId);
- const [rid, localAddr, remoteAddr] = await promise;
- this.#promiseId = null;
- if (this.addr.transport == "tcp") {
- localAddr.transport = "tcp";
- remoteAddr.transport = "tcp";
- return new TcpConn(rid, remoteAddr, localAddr);
- } else if (this.addr.transport == "unix") {
- return new UnixConn(
- rid,
- { transport: "unix", path: remoteAddr },
- { transport: "unix", path: localAddr },
- );
- } else {
- throw new Error("unreachable");
+ if (this.#unref) {
+ this.#unrefOpAccept();
}
+ return promise.then((res) => {
+ if (this.addr.transport == "tcp") {
+ return new TcpConn(res.rid, res.remoteAddr, res.localAddr);
+ } else if (this.addr.transport == "unix") {
+ return new UnixConn(res.rid, res.remoteAddr, res.localAddr);
+ } else {
+ throw new Error("unreachable");
+ }
+ });
}
async next() {
@@ -190,15 +205,22 @@
return this;
}
- ref() {
+ [listenerRef]() {
this.#unref = false;
+ this.#refOpAccept();
+ }
+
+ [listenerUnref]() {
+ this.#unref = true;
+ this.#unrefOpAccept();
+ }
+
+ #refOpAccept() {
if (typeof this.#promiseId === "number") {
core.refOp(this.#promiseId);
}
}
-
- unref() {
- this.#unref = true;
+ #unrefOpAccept() {
if (typeof this.#promiseId === "number") {
core.unrefOp(this.#promiseId);
}
@@ -225,54 +247,18 @@
async receive(p) {
const buf = p || new Uint8Array(this.bufSize);
- let nread;
- let remoteAddr;
- switch (this.addr.transport) {
- case "udp": {
- [nread, remoteAddr] = await core.opAsync(
- "op_net_recv_udp",
- this.rid,
- buf,
- );
- remoteAddr.transport = "udp";
- break;
- }
- case "unixpacket": {
- let path;
- [nread, path] = await core.opAsync(
- "op_net_recv_unixpacket",
- this.rid,
- buf,
- );
- remoteAddr = { transport: "unixpacket", path };
- break;
- }
- default:
- throw new Error(`Unsupported transport: ${this.addr.transport}`);
- }
- const sub = TypedArrayPrototypeSubarray(buf, 0, nread);
+ const { size, remoteAddr } = await opReceive(
+ this.rid,
+ this.addr.transport,
+ buf,
+ );
+ const sub = TypedArrayPrototypeSubarray(buf, 0, size);
return [sub, remoteAddr];
}
- async send(p, opts) {
- switch (this.addr.transport) {
- case "udp":
- return await core.opAsync(
- "op_net_send_udp",
- this.rid,
- { hostname: opts.hostname ?? "127.0.0.1", port: opts.port },
- p,
- );
- case "unixpacket":
- return await core.opAsync(
- "op_net_send_unixpacket",
- this.rid,
- opts.path,
- p,
- );
- default:
- throw new Error(`Unsupported transport: ${this.addr.transport}`);
- }
+ send(p, addr) {
+ const args = { hostname: "127.0.0.1", ...addr, rid: this.rid };
+ return opSend(args, p);
}
close() {
@@ -296,100 +282,40 @@
}
}
- function listen(args) {
- switch (args.transport ?? "tcp") {
- case "tcp": {
- const [rid, addr] = ops.op_net_listen_tcp({
- hostname: args.hostname ?? "0.0.0.0",
- port: args.port,
- });
- addr.transport = "tcp";
- return new Listener(rid, addr);
- }
- case "unix": {
- const [rid, path] = ops.op_net_listen_unix(args.path);
- const addr = {
- transport: "unix",
- path,
- };
- return new Listener(rid, addr);
- }
- default:
- throw new TypeError(`Unsupported transport: '${transport}'`);
- }
- }
+ function listen({ hostname, ...options }, constructor = Listener) {
+ const res = opListen({
+ transport: "tcp",
+ hostname: typeof hostname === "undefined" ? "0.0.0.0" : hostname,
+ ...options,
+ });
- function listenDatagram(args) {
- switch (args.transport) {
- case "udp": {
- const [rid, addr] = ops.op_net_listen_udp(
- {
- hostname: args.hostname ?? "127.0.0.1",
- port: args.port,
- },
- args.reuseAddress ?? false,
- );
- addr.transport = "udp";
- return new Datagram(rid, addr);
- }
- case "unixpacket": {
- const [rid, path] = ops.op_net_listen_unixpacket(args.path);
- const addr = {
- transport: "unixpacket",
- path,
- };
- return new Datagram(rid, addr);
- }
- default:
- throw new TypeError(`Unsupported transport: '${transport}'`);
- }
+ return new constructor(res.rid, res.localAddr);
}
- async function connect(args) {
- switch (args.transport ?? "tcp") {
- case "tcp": {
- const [rid, localAddr, remoteAddr] = await core.opAsync(
- "op_net_connect_tcp",
- {
- hostname: args.hostname ?? "127.0.0.1",
- port: args.port,
- },
- );
- localAddr.transport = "tcp";
- remoteAddr.transport = "tcp";
- return new TcpConn(rid, remoteAddr, localAddr);
- }
- case "unix": {
- const [rid, localAddr, remoteAddr] = await core.opAsync(
- "op_net_connect_unix",
- args.path,
- );
- return new UnixConn(
- rid,
- { transport: "unix", path: remoteAddr },
- { transport: "unix", path: localAddr },
- );
- }
- default:
- throw new TypeError(`Unsupported transport: '${transport}'`);
+ async function connect(options) {
+ if (options.transport === "unix") {
+ const res = await opConnect(options);
+ return new UnixConn(res.rid, res.remoteAddr, res.localAddr);
}
- }
- function setup(unstable) {
- if (!unstable) {
- delete Listener.prototype.ref;
- delete Listener.prototype.unref;
- }
+ const res = await opConnect({
+ transport: "tcp",
+ hostname: "127.0.0.1",
+ ...options,
+ });
+ return new TcpConn(res.rid, res.remoteAddr, res.localAddr);
}
window.__bootstrap.net = {
- setup,
connect,
Conn,
TcpConn,
UnixConn,
+ opConnect,
listen,
- listenDatagram,
+ listenerRef,
+ listenerUnref,
+ opListen,
Listener,
shutdown,
Datagram,