2022-01-20 02:10:16 -05:00
|
|
|
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
2020-03-10 11:38:02 -04:00
|
|
|
import {
|
|
|
|
assert,
|
|
|
|
assertEquals,
|
2020-09-27 06:22:32 -04:00
|
|
|
assertNotEquals,
|
2021-09-22 09:21:11 -04:00
|
|
|
assertRejects,
|
2020-06-24 18:57:08 -04:00
|
|
|
assertThrows,
|
2020-11-26 11:22:36 -05:00
|
|
|
deferred,
|
2021-06-24 21:44:14 -04:00
|
|
|
delay,
|
2020-03-10 11:38:02 -04:00
|
|
|
} from "./test_util.ts";
|
2018-10-03 23:58:29 -04:00
|
|
|
|
2021-08-16 10:15:00 -04:00
|
|
|
let isCI: boolean;
|
|
|
|
try {
|
|
|
|
isCI = Deno.env.get("CI") !== undefined;
|
|
|
|
} catch {
|
|
|
|
isCI = true;
|
|
|
|
}
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test({ permissions: { net: true } }, function netTcpListenClose() {
|
2020-05-11 14:49:19 -04:00
|
|
|
const listener = Deno.listen({ hostname: "127.0.0.1", port: 3500 });
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(listener.addr.transport === "tcp");
|
2020-01-18 15:49:55 -05:00
|
|
|
assertEquals(listener.addr.hostname, "127.0.0.1");
|
2020-05-11 14:49:19 -04:00
|
|
|
assertEquals(listener.addr.port, 3500);
|
2020-06-08 12:24:51 -04:00
|
|
|
assertNotEquals(listener.rid, 0);
|
2018-10-03 23:58:29 -04:00
|
|
|
listener.close();
|
|
|
|
});
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2020-03-04 11:31:14 -05:00
|
|
|
{
|
2021-09-22 19:50:50 -04:00
|
|
|
permissions: { net: true },
|
2020-03-04 11:31:14 -05:00
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
function netUdpListenClose() {
|
2020-04-28 15:46:39 -04:00
|
|
|
const socket = Deno.listenDatagram({
|
2020-03-04 11:31:14 -05:00
|
|
|
hostname: "127.0.0.1",
|
2020-05-11 14:49:19 -04:00
|
|
|
port: 3500,
|
2020-03-28 13:03:49 -04:00
|
|
|
transport: "udp",
|
2020-03-04 11:31:14 -05:00
|
|
|
});
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(socket.addr.transport === "udp");
|
2020-03-04 11:31:14 -05:00
|
|
|
assertEquals(socket.addr.hostname, "127.0.0.1");
|
2020-05-11 14:49:19 -04:00
|
|
|
assertEquals(socket.addr.port, 3500);
|
2020-03-04 11:31:14 -05:00
|
|
|
socket.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|
2019-01-15 20:36:51 -05:00
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
function netUnixListenClose() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = Deno.makeTempFileSync();
|
|
|
|
const socket = Deno.listen({
|
2020-04-28 12:37:59 -04:00
|
|
|
path: filePath,
|
2020-03-28 13:03:49 -04:00
|
|
|
transport: "unix",
|
2020-03-23 18:02:51 -04:00
|
|
|
});
|
|
|
|
assert(socket.addr.transport === "unix");
|
2020-04-28 12:37:59 -04:00
|
|
|
assertEquals(socket.addr.path, filePath);
|
2020-03-23 18:02:51 -04:00
|
|
|
socket.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
function netUnixPacketListenClose() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = Deno.makeTempFileSync();
|
2020-04-28 15:46:39 -04:00
|
|
|
const socket = Deno.listenDatagram({
|
2020-04-28 12:37:59 -04:00
|
|
|
path: filePath,
|
2020-03-28 13:03:49 -04:00
|
|
|
transport: "unixpacket",
|
2020-03-23 18:02:51 -04:00
|
|
|
});
|
|
|
|
assert(socket.addr.transport === "unixpacket");
|
2020-04-28 12:37:59 -04:00
|
|
|
assertEquals(socket.addr.path, filePath);
|
2020-03-23 18:02:51 -04:00
|
|
|
socket.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: false },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
function netUnixListenWritePermission() {
|
2020-11-27 15:02:25 -05:00
|
|
|
assertThrows(() => {
|
2020-11-27 13:43:39 -05:00
|
|
|
const filePath = Deno.makeTempFileSync();
|
|
|
|
const socket = Deno.listen({
|
|
|
|
path: filePath,
|
|
|
|
transport: "unix",
|
|
|
|
});
|
|
|
|
assert(socket.addr.transport === "unix");
|
|
|
|
assertEquals(socket.addr.path, filePath);
|
|
|
|
socket.close();
|
2020-11-27 15:02:25 -05:00
|
|
|
}, Deno.errors.PermissionDenied);
|
2020-11-27 13:43:39 -05:00
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: false },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
function netUnixPacketListenWritePermission() {
|
2020-11-27 15:02:25 -05:00
|
|
|
assertThrows(() => {
|
2020-11-27 13:43:39 -05:00
|
|
|
const filePath = Deno.makeTempFileSync();
|
|
|
|
const socket = Deno.listenDatagram({
|
|
|
|
path: filePath,
|
|
|
|
transport: "unixpacket",
|
|
|
|
});
|
|
|
|
assert(socket.addr.transport === "unixpacket");
|
|
|
|
assertEquals(socket.addr.path, filePath);
|
|
|
|
socket.close();
|
2020-11-27 15:02:25 -05:00
|
|
|
}, Deno.errors.PermissionDenied);
|
2020-11-27 13:43:39 -05:00
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2020-03-04 11:31:14 -05:00
|
|
|
{
|
2021-09-22 19:50:50 -04:00
|
|
|
permissions: { net: true },
|
2020-03-04 11:31:14 -05:00
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netTcpCloseWhileAccept() {
|
2020-03-24 12:24:58 -04:00
|
|
|
const listener = Deno.listen({ port: 4501 });
|
2020-03-04 11:31:14 -05:00
|
|
|
const p = listener.accept();
|
|
|
|
listener.close();
|
2021-10-09 16:37:19 -04:00
|
|
|
// TODO(piscisaureus): the error type should be `Interrupted` here, which
|
|
|
|
// gets thrown, but then ext/net catches it and rethrows `BadResource`.
|
2021-09-22 09:21:11 -04:00
|
|
|
await assertRejects(
|
2021-10-09 16:37:19 -04:00
|
|
|
() => p,
|
2020-06-24 18:57:08 -04:00
|
|
|
Deno.errors.BadResource,
|
2020-07-14 15:24:17 -04:00
|
|
|
"Listener has been closed",
|
2020-06-24 18:57:08 -04:00
|
|
|
);
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUnixCloseWhileAccept() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = await Deno.makeTempFile();
|
|
|
|
const listener = Deno.listen({
|
2020-04-28 12:37:59 -04:00
|
|
|
path: filePath,
|
2020-03-28 13:03:49 -04:00
|
|
|
transport: "unix",
|
2020-03-23 18:02:51 -04:00
|
|
|
});
|
|
|
|
const p = listener.accept();
|
|
|
|
listener.close();
|
2021-09-22 09:21:11 -04:00
|
|
|
await assertRejects(
|
2021-10-09 16:37:19 -04:00
|
|
|
() => p,
|
2021-12-14 17:27:04 -05:00
|
|
|
Deno.errors.BadResource,
|
|
|
|
"Listener has been closed",
|
2020-06-24 18:57:08 -04:00
|
|
|
);
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netTcpConcurrentAccept() {
|
2020-03-24 12:24:58 -04:00
|
|
|
const listener = Deno.listen({ port: 4502 });
|
2020-03-04 11:31:14 -05:00
|
|
|
let acceptErrCount = 0;
|
2021-08-05 07:08:58 -04:00
|
|
|
const checkErr = (e: Error) => {
|
2020-03-04 11:31:14 -05:00
|
|
|
if (e.message === "Listener has been closed") {
|
|
|
|
assertEquals(acceptErrCount, 1);
|
|
|
|
} else if (e.message === "Another accept task is ongoing") {
|
|
|
|
acceptErrCount++;
|
|
|
|
} else {
|
|
|
|
throw new Error("Unexpected error message");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const p = listener.accept().catch(checkErr);
|
|
|
|
const p1 = listener.accept().catch(checkErr);
|
|
|
|
await Promise.race([p, p1]);
|
|
|
|
listener.close();
|
|
|
|
await Promise.all([p, p1]);
|
|
|
|
assertEquals(acceptErrCount, 1);
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|
2019-01-15 20:36:51 -05:00
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-10-09 16:37:19 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUnixConcurrentAccept() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = await Deno.makeTempFile();
|
2020-04-28 12:37:59 -04:00
|
|
|
const listener = Deno.listen({ transport: "unix", path: filePath });
|
2020-03-23 18:02:51 -04:00
|
|
|
let acceptErrCount = 0;
|
2021-08-05 07:08:58 -04:00
|
|
|
const checkErr = (e: Error) => {
|
2021-12-14 17:27:04 -05:00
|
|
|
if (e.message === "Listener has been closed") {
|
2020-03-23 18:02:51 -04:00
|
|
|
assertEquals(acceptErrCount, 1);
|
2021-10-09 16:37:19 -04:00
|
|
|
} else if (e instanceof Deno.errors.Busy) { // "Listener already in use"
|
2020-03-23 18:02:51 -04:00
|
|
|
acceptErrCount++;
|
|
|
|
} else {
|
2021-10-09 16:37:19 -04:00
|
|
|
throw e;
|
2020-03-23 18:02:51 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
const p = listener.accept().catch(checkErr);
|
|
|
|
const p1 = listener.accept().catch(checkErr);
|
|
|
|
await Promise.race([p, p1]);
|
|
|
|
listener.close();
|
2021-10-09 16:37:19 -04:00
|
|
|
await Promise.all([p, p1]);
|
2020-03-23 18:02:51 -04:00
|
|
|
assertEquals(acceptErrCount, 1);
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test({ permissions: { net: true } }, async function netTcpDialListen() {
|
2020-05-11 14:49:19 -04:00
|
|
|
const listener = Deno.listen({ port: 3500 });
|
2019-04-21 16:40:10 -04:00
|
|
|
listener.accept().then(
|
2021-08-05 07:08:58 -04:00
|
|
|
async (conn) => {
|
2019-08-27 11:35:32 -04:00
|
|
|
assert(conn.remoteAddr != null);
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(conn.localAddr.transport === "tcp");
|
2020-01-18 15:49:55 -05:00
|
|
|
assertEquals(conn.localAddr.hostname, "127.0.0.1");
|
2020-05-11 14:49:19 -04:00
|
|
|
assertEquals(conn.localAddr.port, 3500);
|
2019-04-21 16:40:10 -04:00
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
conn.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2019-04-21 16:40:10 -04:00
|
|
|
);
|
2020-03-24 12:24:58 -04:00
|
|
|
|
2020-05-11 14:49:19 -04:00
|
|
|
const conn = await Deno.connect({ hostname: "127.0.0.1", port: 3500 });
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(conn.remoteAddr.transport === "tcp");
|
2020-01-18 15:49:55 -05:00
|
|
|
assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
|
2020-05-11 14:49:19 -04:00
|
|
|
assertEquals(conn.remoteAddr.port, 3500);
|
2019-08-27 11:35:32 -04:00
|
|
|
assert(conn.localAddr != null);
|
2018-10-03 23:58:29 -04:00
|
|
|
const buf = new Uint8Array(1024);
|
|
|
|
const readResult = await conn.read(buf);
|
2019-07-06 10:16:03 -04:00
|
|
|
assertEquals(3, readResult);
|
2019-05-01 16:58:09 -04:00
|
|
|
assertEquals(1, buf[0]);
|
|
|
|
assertEquals(2, buf[1]);
|
|
|
|
assertEquals(3, buf[2]);
|
|
|
|
assert(conn.rid > 0);
|
|
|
|
|
2020-04-28 12:40:43 -04:00
|
|
|
assert(readResult !== null);
|
2019-05-01 16:58:09 -04:00
|
|
|
|
|
|
|
const readResult2 = await conn.read(buf);
|
2020-04-28 12:40:43 -04:00
|
|
|
assertEquals(readResult2, null);
|
2019-05-01 16:58:09 -04:00
|
|
|
|
|
|
|
listener.close();
|
|
|
|
conn.close();
|
|
|
|
});
|
|
|
|
|
2022-01-31 10:36:54 -05:00
|
|
|
Deno.test({ permissions: { net: true } }, async function netTcpSetNoDelay() {
|
|
|
|
const listener = Deno.listen({ port: 3500 });
|
|
|
|
listener.accept().then(
|
|
|
|
async (conn) => {
|
|
|
|
assert(conn.remoteAddr != null);
|
|
|
|
assert(conn.localAddr.transport === "tcp");
|
|
|
|
assertEquals(conn.localAddr.hostname, "127.0.0.1");
|
|
|
|
assertEquals(conn.localAddr.port, 3500);
|
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
conn.close();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
const conn = await Deno.connect({ hostname: "127.0.0.1", port: 3500 });
|
|
|
|
conn.setNoDelay(true);
|
|
|
|
assert(conn.remoteAddr.transport === "tcp");
|
|
|
|
assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
|
|
|
|
assertEquals(conn.remoteAddr.port, 3500);
|
|
|
|
assert(conn.localAddr != null);
|
|
|
|
const buf = new Uint8Array(1024);
|
|
|
|
const readResult = await conn.read(buf);
|
|
|
|
assertEquals(3, readResult);
|
|
|
|
assertEquals(1, buf[0]);
|
|
|
|
assertEquals(2, buf[1]);
|
|
|
|
assertEquals(3, buf[2]);
|
|
|
|
assert(conn.rid > 0);
|
|
|
|
|
|
|
|
assert(readResult !== null);
|
|
|
|
|
|
|
|
const readResult2 = await conn.read(buf);
|
|
|
|
assertEquals(readResult2, null);
|
|
|
|
|
|
|
|
listener.close();
|
|
|
|
conn.close();
|
|
|
|
});
|
|
|
|
|
|
|
|
Deno.test({ permissions: { net: true } }, async function netTcpSetKeepAlive() {
|
|
|
|
const listener = Deno.listen({ port: 3500 });
|
|
|
|
listener.accept().then(
|
|
|
|
async (conn) => {
|
|
|
|
assert(conn.remoteAddr != null);
|
|
|
|
assert(conn.localAddr.transport === "tcp");
|
|
|
|
assertEquals(conn.localAddr.hostname, "127.0.0.1");
|
|
|
|
assertEquals(conn.localAddr.port, 3500);
|
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
conn.close();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
const conn = await Deno.connect({ hostname: "127.0.0.1", port: 3500 });
|
|
|
|
conn.setKeepAlive(true);
|
|
|
|
assert(conn.remoteAddr.transport === "tcp");
|
|
|
|
assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
|
|
|
|
assertEquals(conn.remoteAddr.port, 3500);
|
|
|
|
assert(conn.localAddr != null);
|
|
|
|
const buf = new Uint8Array(1024);
|
|
|
|
const readResult = await conn.read(buf);
|
|
|
|
assertEquals(3, readResult);
|
|
|
|
assertEquals(1, buf[0]);
|
|
|
|
assertEquals(2, buf[1]);
|
|
|
|
assertEquals(3, buf[2]);
|
|
|
|
assert(conn.rid > 0);
|
|
|
|
|
|
|
|
assert(readResult !== null);
|
|
|
|
|
|
|
|
const readResult2 = await conn.read(buf);
|
|
|
|
assertEquals(readResult2, null);
|
|
|
|
|
|
|
|
listener.close();
|
|
|
|
conn.close();
|
|
|
|
});
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUnixDialListen() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = await Deno.makeTempFile();
|
2020-04-28 12:37:59 -04:00
|
|
|
const listener = Deno.listen({ path: filePath, transport: "unix" });
|
2020-03-23 18:02:51 -04:00
|
|
|
listener.accept().then(
|
2021-08-05 07:08:58 -04:00
|
|
|
async (conn) => {
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(conn.remoteAddr != null);
|
|
|
|
assert(conn.localAddr.transport === "unix");
|
2020-04-28 12:37:59 -04:00
|
|
|
assertEquals(conn.localAddr.path, filePath);
|
2020-03-23 18:02:51 -04:00
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
conn.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
2020-04-28 12:37:59 -04:00
|
|
|
const conn = await Deno.connect({ path: filePath, transport: "unix" });
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(conn.remoteAddr.transport === "unix");
|
2020-04-28 12:37:59 -04:00
|
|
|
assertEquals(conn.remoteAddr.path, filePath);
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(conn.remoteAddr != null);
|
|
|
|
const buf = new Uint8Array(1024);
|
|
|
|
const readResult = await conn.read(buf);
|
|
|
|
assertEquals(3, readResult);
|
|
|
|
assertEquals(1, buf[0]);
|
|
|
|
assertEquals(2, buf[1]);
|
|
|
|
assertEquals(3, buf[2]);
|
|
|
|
assert(conn.rid > 0);
|
|
|
|
|
2020-04-28 12:40:43 -04:00
|
|
|
assert(readResult !== null);
|
2020-03-23 18:02:51 -04:00
|
|
|
|
|
|
|
const readResult2 = await conn.read(buf);
|
2020-04-28 12:40:43 -04:00
|
|
|
assertEquals(readResult2, null);
|
2020-03-23 18:02:51 -04:00
|
|
|
|
|
|
|
listener.close();
|
|
|
|
conn.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUdpSendReceive() {
|
2020-05-11 14:49:19 -04:00
|
|
|
const alice = Deno.listenDatagram({ port: 3500, transport: "udp" });
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(alice.addr.transport === "udp");
|
2020-05-11 14:49:19 -04:00
|
|
|
assertEquals(alice.addr.port, 3500);
|
2020-03-23 18:02:51 -04:00
|
|
|
assertEquals(alice.addr.hostname, "127.0.0.1");
|
2020-02-21 11:26:54 -05:00
|
|
|
|
2020-04-28 15:46:39 -04:00
|
|
|
const bob = Deno.listenDatagram({ port: 4501, transport: "udp" });
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(bob.addr.transport === "udp");
|
2020-03-24 12:24:58 -04:00
|
|
|
assertEquals(bob.addr.port, 4501);
|
2020-03-23 18:02:51 -04:00
|
|
|
assertEquals(bob.addr.hostname, "127.0.0.1");
|
2020-02-21 11:26:54 -05:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
const sent = new Uint8Array([1, 2, 3]);
|
2020-06-13 10:14:31 -04:00
|
|
|
const byteLength = await alice.send(sent, bob.addr);
|
|
|
|
|
|
|
|
assertEquals(byteLength, 3);
|
2020-02-21 11:26:54 -05:00
|
|
|
|
2020-03-04 11:31:14 -05:00
|
|
|
const [recvd, remote] = await bob.receive();
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(remote.transport === "udp");
|
2020-05-11 14:49:19 -04:00
|
|
|
assertEquals(remote.port, 3500);
|
2020-03-04 11:31:14 -05:00
|
|
|
assertEquals(recvd.length, 3);
|
|
|
|
assertEquals(1, recvd[0]);
|
|
|
|
assertEquals(2, recvd[1]);
|
|
|
|
assertEquals(3, recvd[2]);
|
|
|
|
alice.close();
|
|
|
|
bob.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-04 11:31:14 -05:00
|
|
|
);
|
2019-11-09 14:40:22 -05:00
|
|
|
|
2021-11-29 05:14:46 -05:00
|
|
|
Deno.test(
|
|
|
|
{ permissions: { net: true } },
|
|
|
|
async function netUdpSendReceiveBroadcast() {
|
|
|
|
// Must bind sender to an address that can send to the broadcast address on MacOS.
|
|
|
|
// Macos will give us error 49 when sending the broadcast packet if we omit hostname here.
|
|
|
|
const alice = Deno.listenDatagram({
|
|
|
|
port: 3500,
|
|
|
|
transport: "udp",
|
|
|
|
hostname: "0.0.0.0",
|
|
|
|
});
|
|
|
|
|
|
|
|
const bob = Deno.listenDatagram({
|
|
|
|
port: 4501,
|
|
|
|
transport: "udp",
|
|
|
|
hostname: "0.0.0.0",
|
|
|
|
});
|
|
|
|
assert(bob.addr.transport === "udp");
|
|
|
|
assertEquals(bob.addr.port, 4501);
|
|
|
|
assertEquals(bob.addr.hostname, "0.0.0.0");
|
|
|
|
|
|
|
|
const broadcastAddr = { ...bob.addr, hostname: "255.255.255.255" };
|
|
|
|
|
|
|
|
const sent = new Uint8Array([1, 2, 3]);
|
|
|
|
const byteLength = await alice.send(sent, broadcastAddr);
|
|
|
|
|
|
|
|
assertEquals(byteLength, 3);
|
|
|
|
const [recvd, remote] = await bob.receive();
|
|
|
|
assert(remote.transport === "udp");
|
|
|
|
assertEquals(remote.port, 3500);
|
|
|
|
assertEquals(recvd.length, 3);
|
|
|
|
assertEquals(1, recvd[0]);
|
|
|
|
assertEquals(2, recvd[1]);
|
|
|
|
assertEquals(3, recvd[2]);
|
|
|
|
alice.close();
|
|
|
|
bob.close();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUdpConcurrentSendReceive() {
|
2020-12-16 11:14:12 -05:00
|
|
|
const socket = Deno.listenDatagram({ port: 3500, transport: "udp" });
|
|
|
|
assert(socket.addr.transport === "udp");
|
|
|
|
assertEquals(socket.addr.port, 3500);
|
|
|
|
assertEquals(socket.addr.hostname, "127.0.0.1");
|
|
|
|
|
|
|
|
const recvPromise = socket.receive();
|
|
|
|
|
|
|
|
const sendBuf = new Uint8Array([1, 2, 3]);
|
|
|
|
const sendLen = await socket.send(sendBuf, socket.addr);
|
|
|
|
assertEquals(sendLen, 3);
|
|
|
|
|
2021-04-09 17:35:29 -04:00
|
|
|
const [recvBuf, _recvAddr] = await recvPromise;
|
2020-12-16 11:14:12 -05:00
|
|
|
assertEquals(recvBuf.length, 3);
|
|
|
|
assertEquals(1, recvBuf[0]);
|
|
|
|
assertEquals(2, recvBuf[1]);
|
|
|
|
assertEquals(3, recvBuf[2]);
|
|
|
|
|
|
|
|
socket.close();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUdpBorrowMutError() {
|
2020-06-10 11:26:28 -04:00
|
|
|
const socket = Deno.listenDatagram({
|
|
|
|
port: 4501,
|
|
|
|
transport: "udp",
|
|
|
|
});
|
|
|
|
// Panic happened on second send: BorrowMutError
|
|
|
|
const a = socket.send(new Uint8Array(), socket.addr);
|
|
|
|
const b = socket.send(new Uint8Array(), socket.addr);
|
|
|
|
await Promise.all([a, b]);
|
|
|
|
socket.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-06-10 11:26:28 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUnixPacketSendReceive() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = await Deno.makeTempFile();
|
2020-04-28 15:46:39 -04:00
|
|
|
const alice = Deno.listenDatagram({
|
|
|
|
path: filePath,
|
|
|
|
transport: "unixpacket",
|
|
|
|
});
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(alice.addr.transport === "unixpacket");
|
2020-04-28 12:37:59 -04:00
|
|
|
assertEquals(alice.addr.path, filePath);
|
2020-03-23 18:02:51 -04:00
|
|
|
|
2020-04-28 15:46:39 -04:00
|
|
|
const bob = Deno.listenDatagram({
|
|
|
|
path: filePath,
|
|
|
|
transport: "unixpacket",
|
|
|
|
});
|
2020-03-23 18:02:51 -04:00
|
|
|
assert(bob.addr.transport === "unixpacket");
|
2020-04-28 12:37:59 -04:00
|
|
|
assertEquals(bob.addr.path, filePath);
|
2020-03-23 18:02:51 -04:00
|
|
|
|
|
|
|
const sent = new Uint8Array([1, 2, 3]);
|
2020-06-15 12:20:45 -04:00
|
|
|
const byteLength = await alice.send(sent, bob.addr);
|
|
|
|
assertEquals(byteLength, 3);
|
2020-03-23 18:02:51 -04:00
|
|
|
|
|
|
|
const [recvd, remote] = await bob.receive();
|
|
|
|
assert(remote.transport === "unixpacket");
|
2020-04-28 12:37:59 -04:00
|
|
|
assertEquals(remote.path, filePath);
|
2020-03-23 18:02:51 -04:00
|
|
|
assertEquals(recvd.length, 3);
|
|
|
|
assertEquals(1, recvd[0]);
|
|
|
|
assertEquals(2, recvd[1]);
|
|
|
|
assertEquals(3, recvd[2]);
|
|
|
|
alice.close();
|
|
|
|
bob.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2020-12-16 11:14:12 -05:00
|
|
|
// TODO(piscisaureus): Enable after Tokio v0.3/v1.0 upgrade.
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ ignore: true, permissions: { read: true, write: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUnixPacketConcurrentSendReceive() {
|
2020-12-16 11:14:12 -05:00
|
|
|
const filePath = await Deno.makeTempFile();
|
|
|
|
const socket = Deno.listenDatagram({
|
|
|
|
path: filePath,
|
|
|
|
transport: "unixpacket",
|
|
|
|
});
|
|
|
|
assert(socket.addr.transport === "unixpacket");
|
|
|
|
assertEquals(socket.addr.path, filePath);
|
|
|
|
|
|
|
|
const recvPromise = socket.receive();
|
|
|
|
|
|
|
|
const sendBuf = new Uint8Array([1, 2, 3]);
|
|
|
|
const sendLen = await socket.send(sendBuf, socket.addr);
|
|
|
|
assertEquals(sendLen, 3);
|
|
|
|
|
2021-04-09 17:35:29 -04:00
|
|
|
const [recvBuf, _recvAddr] = await recvPromise;
|
2020-12-16 11:14:12 -05:00
|
|
|
assertEquals(recvBuf.length, 3);
|
|
|
|
assertEquals(1, recvBuf[0]);
|
|
|
|
assertEquals(2, recvBuf[1]);
|
|
|
|
assertEquals(3, recvBuf[2]);
|
|
|
|
|
|
|
|
socket.close();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netTcpListenIteratorBreakClosesResource() {
|
|
|
|
async function iterate(listener: Deno.Listener) {
|
2020-04-28 19:08:02 -04:00
|
|
|
let i = 0;
|
|
|
|
|
|
|
|
for await (const conn of listener) {
|
|
|
|
conn.close();
|
|
|
|
i++;
|
|
|
|
|
|
|
|
if (i > 1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const addr = { hostname: "127.0.0.1", port: 8888 };
|
|
|
|
const listener = Deno.listen(addr);
|
2021-08-25 16:04:14 -04:00
|
|
|
const iteratePromise = iterate(listener);
|
2020-04-28 19:08:02 -04:00
|
|
|
|
2021-06-24 21:44:14 -04:00
|
|
|
await delay(100);
|
2020-04-28 19:08:02 -04:00
|
|
|
const conn1 = await Deno.connect(addr);
|
|
|
|
conn1.close();
|
|
|
|
const conn2 = await Deno.connect(addr);
|
|
|
|
conn2.close();
|
|
|
|
|
2021-08-25 16:04:14 -04:00
|
|
|
await iteratePromise;
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-04-28 19:08:02 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netTcpListenCloseWhileIterating() {
|
2021-07-31 21:10:19 -04:00
|
|
|
const listener = Deno.listen({ port: 8001 });
|
2020-02-21 11:26:54 -05:00
|
|
|
const nextWhileClosing = listener[Symbol.asyncIterator]().next();
|
|
|
|
listener.close();
|
|
|
|
assertEquals(await nextWhileClosing, { value: undefined, done: true });
|
|
|
|
|
|
|
|
const nextAfterClosing = listener[Symbol.asyncIterator]().next();
|
|
|
|
assertEquals(await nextAfterClosing, { value: undefined, done: true });
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-02-21 11:26:54 -05:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUdpListenCloseWhileIterating() {
|
2021-01-25 10:02:03 -05:00
|
|
|
const socket = Deno.listenDatagram({ port: 8000, transport: "udp" });
|
2020-02-21 11:26:54 -05:00
|
|
|
const nextWhileClosing = socket[Symbol.asyncIterator]().next();
|
|
|
|
socket.close();
|
|
|
|
assertEquals(await nextWhileClosing, { value: undefined, done: true });
|
|
|
|
|
|
|
|
const nextAfterClosing = socket[Symbol.asyncIterator]().next();
|
|
|
|
assertEquals(await nextAfterClosing, { value: undefined, done: true });
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-02-21 11:26:54 -05:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUnixListenCloseWhileIterating() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = Deno.makeTempFileSync();
|
2020-04-28 12:37:59 -04:00
|
|
|
const socket = Deno.listen({ path: filePath, transport: "unix" });
|
2020-03-23 18:02:51 -04:00
|
|
|
const nextWhileClosing = socket[Symbol.asyncIterator]().next();
|
|
|
|
socket.close();
|
|
|
|
assertEquals(await nextWhileClosing, { value: undefined, done: true });
|
|
|
|
|
|
|
|
const nextAfterClosing = socket[Symbol.asyncIterator]().next();
|
|
|
|
assertEquals(await nextAfterClosing, { value: undefined, done: true });
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-09-22 19:50:50 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os === "windows",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netUnixPacketListenCloseWhileIterating() {
|
2020-03-23 18:02:51 -04:00
|
|
|
const filePath = Deno.makeTempFileSync();
|
2020-04-28 15:46:39 -04:00
|
|
|
const socket = Deno.listenDatagram({
|
|
|
|
path: filePath,
|
|
|
|
transport: "unixpacket",
|
|
|
|
});
|
2020-03-23 18:02:51 -04:00
|
|
|
const nextWhileClosing = socket[Symbol.asyncIterator]().next();
|
|
|
|
socket.close();
|
|
|
|
assertEquals(await nextWhileClosing, { value: undefined, done: true });
|
|
|
|
|
|
|
|
const nextAfterClosing = socket[Symbol.asyncIterator]().next();
|
|
|
|
assertEquals(await nextAfterClosing, { value: undefined, done: true });
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-23 18:02:51 -04:00
|
|
|
);
|
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-10-09 16:37:19 -04:00
|
|
|
{ permissions: { net: true } },
|
2021-08-05 07:08:58 -04:00
|
|
|
async function netListenAsyncIterator() {
|
2020-05-11 14:49:19 -04:00
|
|
|
const addr = { hostname: "127.0.0.1", port: 3500 };
|
2020-03-10 11:38:02 -04:00
|
|
|
const listener = Deno.listen(addr);
|
2021-08-05 07:08:58 -04:00
|
|
|
const runAsyncIterator = async () => {
|
2020-03-10 11:38:02 -04:00
|
|
|
for await (const conn of listener) {
|
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
conn.close();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
runAsyncIterator();
|
|
|
|
const conn = await Deno.connect(addr);
|
|
|
|
const buf = new Uint8Array(1024);
|
|
|
|
const readResult = await conn.read(buf);
|
|
|
|
assertEquals(3, readResult);
|
|
|
|
assertEquals(1, buf[0]);
|
|
|
|
assertEquals(2, buf[1]);
|
|
|
|
assertEquals(3, buf[2]);
|
|
|
|
assert(conn.rid > 0);
|
2018-10-03 23:58:29 -04:00
|
|
|
|
2020-04-28 12:40:43 -04:00
|
|
|
assert(readResult !== null);
|
2018-10-03 23:58:29 -04:00
|
|
|
|
2020-03-10 11:38:02 -04:00
|
|
|
const readResult2 = await conn.read(buf);
|
2020-04-28 12:40:43 -04:00
|
|
|
assertEquals(readResult2, null);
|
2018-10-03 23:58:29 -04:00
|
|
|
|
2020-03-10 11:38:02 -04:00
|
|
|
listener.close();
|
|
|
|
conn.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-10 11:38:02 -04:00
|
|
|
);
|
2018-10-05 12:16:24 -04:00
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2020-03-10 11:38:02 -04:00
|
|
|
{
|
2021-09-22 19:50:50 -04:00
|
|
|
permissions: { net: true },
|
2020-03-10 11:38:02 -04:00
|
|
|
},
|
|
|
|
async function netCloseWriteSuccess() {
|
2020-05-11 14:49:19 -04:00
|
|
|
const addr = { hostname: "127.0.0.1", port: 3500 };
|
2020-03-10 11:38:02 -04:00
|
|
|
const listener = Deno.listen(addr);
|
2020-11-26 11:22:36 -05:00
|
|
|
const closeDeferred = deferred();
|
2020-03-28 13:03:49 -04:00
|
|
|
listener.accept().then(async (conn) => {
|
2020-03-10 11:38:02 -04:00
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
await closeDeferred;
|
|
|
|
conn.close();
|
|
|
|
});
|
|
|
|
const conn = await Deno.connect(addr);
|
|
|
|
conn.closeWrite(); // closing write
|
|
|
|
const buf = new Uint8Array(1024);
|
|
|
|
// Check read not impacted
|
|
|
|
const readResult = await conn.read(buf);
|
|
|
|
assertEquals(3, readResult);
|
|
|
|
assertEquals(1, buf[0]);
|
|
|
|
assertEquals(2, buf[1]);
|
|
|
|
assertEquals(3, buf[2]);
|
2021-01-19 23:11:08 -05:00
|
|
|
// Verify that the write end of the socket is closed.
|
|
|
|
// TODO(piscisaureus): assert that thrown error is of a specific type.
|
2021-09-22 09:21:11 -04:00
|
|
|
await assertRejects(async () => {
|
2020-03-10 11:38:02 -04:00
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
});
|
|
|
|
closeDeferred.resolve();
|
|
|
|
listener.close();
|
2019-04-28 17:15:15 -04:00
|
|
|
conn.close();
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-10 11:38:02 -04:00
|
|
|
);
|
2020-03-11 18:19:24 -04:00
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2020-03-11 18:19:24 -04:00
|
|
|
{
|
2021-08-16 10:15:00 -04:00
|
|
|
// https://github.com/denoland/deno/issues/11580
|
|
|
|
ignore: Deno.build.os === "darwin" && isCI,
|
2021-09-22 19:50:50 -04:00
|
|
|
permissions: { net: true },
|
2020-03-11 18:19:24 -04:00
|
|
|
},
|
|
|
|
async function netHangsOnClose() {
|
|
|
|
let acceptedConn: Deno.Conn;
|
|
|
|
|
2021-08-05 07:08:58 -04:00
|
|
|
async function iteratorReq(listener: Deno.Listener) {
|
2020-03-11 18:19:24 -04:00
|
|
|
const p = new Uint8Array(10);
|
|
|
|
const conn = await listener.accept();
|
|
|
|
acceptedConn = conn;
|
|
|
|
|
|
|
|
try {
|
|
|
|
while (true) {
|
|
|
|
const nread = await conn.read(p);
|
2020-04-28 12:40:43 -04:00
|
|
|
if (nread === null) {
|
2020-03-11 18:19:24 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
await conn.write(new Uint8Array([1, 2, 3]));
|
|
|
|
}
|
|
|
|
} catch (err) {
|
2021-10-09 16:37:19 -04:00
|
|
|
assert(err);
|
|
|
|
assert(err instanceof Deno.errors.Interrupted);
|
2020-03-11 18:19:24 -04:00
|
|
|
}
|
|
|
|
}
|
2020-03-24 12:24:58 -04:00
|
|
|
|
2020-05-11 14:49:19 -04:00
|
|
|
const addr = { hostname: "127.0.0.1", port: 3500 };
|
2020-03-11 18:19:24 -04:00
|
|
|
const listener = Deno.listen(addr);
|
2021-08-04 19:45:10 -04:00
|
|
|
const listenerPromise = iteratorReq(listener);
|
|
|
|
const connectionPromise = (async () => {
|
|
|
|
const conn = await Deno.connect(addr);
|
|
|
|
await conn.write(new Uint8Array([1, 2, 3, 4]));
|
|
|
|
const buf = new Uint8Array(10);
|
|
|
|
await conn.read(buf);
|
|
|
|
conn!.close();
|
|
|
|
acceptedConn!.close();
|
|
|
|
listener.close();
|
|
|
|
})();
|
|
|
|
|
|
|
|
await Promise.all([
|
|
|
|
listenerPromise,
|
|
|
|
connectionPromise,
|
|
|
|
]);
|
2020-07-14 15:24:17 -04:00
|
|
|
},
|
2020-03-11 18:19:24 -04:00
|
|
|
);
|
2020-09-27 10:44:53 -04:00
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2020-09-27 10:44:53 -04:00
|
|
|
{
|
2021-09-22 19:50:50 -04:00
|
|
|
permissions: { net: true },
|
2020-09-27 10:44:53 -04:00
|
|
|
},
|
|
|
|
function netExplicitUndefinedHostname() {
|
|
|
|
const listener = Deno.listen({ hostname: undefined, port: 8080 });
|
|
|
|
assertEquals((listener.addr as Deno.NetAddr).hostname, "0.0.0.0");
|
|
|
|
listener.close();
|
|
|
|
},
|
|
|
|
);
|
2021-10-02 13:09:59 -04:00
|
|
|
|
2021-11-23 11:45:18 -05:00
|
|
|
Deno.test(
|
2021-10-02 13:09:59 -04:00
|
|
|
{
|
|
|
|
ignore: Deno.build.os !== "linux",
|
|
|
|
permissions: { read: true, write: true },
|
|
|
|
},
|
|
|
|
function netUnixAbstractPathShouldNotPanic() {
|
|
|
|
const listener = Deno.listen({
|
|
|
|
path: "\0aaa",
|
|
|
|
transport: "unix",
|
|
|
|
});
|
|
|
|
assert("not panic");
|
|
|
|
listener.close();
|
|
|
|
},
|
|
|
|
);
|