summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-01-18 21:49:55 +0100
committerGitHub <noreply@github.com>2020-01-18 21:49:55 +0100
commit23e67eb5153bd26dbae471b27dc6a21a6d283b0b (patch)
tree781432ad02563f4c393a90dcb4300976dda731c0
parent34b99fec8edcff7d3b667f273afea69df15e4d5e (diff)
stabilize net Addr (#3709)
Co-authored-by: xiaoxintang <15707971810@163.com>
-rw-r--r--cli/js/lib.deno_runtime.d.ts18
-rw-r--r--cli/js/net.ts39
-rw-r--r--cli/js/net_test.ts14
-rw-r--r--cli/js/tls.ts3
-rw-r--r--cli/ops/net.rs38
-rw-r--r--cli/ops/tls.rs32
-rw-r--r--std/http/server_test.ts57
7 files changed, 115 insertions, 86 deletions
diff --git a/cli/js/lib.deno_runtime.d.ts b/cli/js/lib.deno_runtime.d.ts
index c4055bc35..6e3e2384a 100644
--- a/cli/js/lib.deno_runtime.d.ts
+++ b/cli/js/lib.deno_runtime.d.ts
@@ -1307,8 +1307,8 @@ declare namespace Deno {
interface Addr {
transport: Transport;
- /** UNSTABLE: Address is unstable because inconsistent with ConnectOptions. */
- address: string;
+ hostname: string;
+ port: number;
}
/** UNSTABLE: Maybe remove ShutdownMode entirely. */
@@ -1342,21 +1342,19 @@ declare namespace Deno {
*/
close(): void;
/** Return the address of the `Listener`. */
- addr(): Addr;
+ addr: Addr;
[Symbol.asyncIterator](): AsyncIterator<Conn>;
}
export interface Conn extends Reader, Writer, Closer {
- /** UNSTABLE: return Addr?
- *
+ /**
* The local address of the connection.
*/
- localAddr: string;
- /** UNSTABLE: return Addr?
- *
+ localAddr: Addr;
+ /**
* The remote address of the connection.
*/
- remoteAddr: string;
+ remoteAddr: Addr;
/** The resource ID of the connection. */
rid: number;
/** Shuts down (`shutdown(2)`) the reading side of the TCP connection. Most
@@ -1426,7 +1424,7 @@ declare namespace Deno {
}
/**
- * Dial connects to the address on the named transport.
+ * Connects to the address on the named transport.
*
* @param options
* @param options.port The port to connect to. (Required.)
diff --git a/cli/js/net.ts b/cli/js/net.ts
index 374454136..a89468f02 100644
--- a/cli/js/net.ts
+++ b/cli/js/net.ts
@@ -8,11 +8,10 @@ export type Transport = "tcp";
// TODO support other types:
// export type Transport = "tcp" | "tcp4" | "tcp6" | "unix" | "unixpacket";
-// TODO(ry) Replace 'address' with 'hostname' and 'port', similar to ConnectOptions
-// and ListenOptions.
export interface Addr {
transport: Transport;
- address: string;
+ hostname: string;
+ port: number;
}
/** A Listener is a generic transport listener for stream-oriented protocols. */
@@ -26,7 +25,7 @@ export interface Listener extends AsyncIterator<Conn> {
close(): void;
/** Return the address of the `Listener`. */
- addr(): Addr;
+ addr: Addr;
[Symbol.asyncIterator](): AsyncIterator<Conn>;
}
@@ -54,8 +53,8 @@ export function shutdown(rid: number, how: ShutdownMode): void {
export class ConnImpl implements Conn {
constructor(
readonly rid: number,
- readonly remoteAddr: string,
- readonly localAddr: string
+ readonly remoteAddr: Addr,
+ readonly localAddr: Addr
) {}
write(p: Uint8Array): Promise<number> {
@@ -88,8 +87,7 @@ export class ConnImpl implements Conn {
export class ListenerImpl implements Listener {
constructor(
readonly rid: number,
- private transport: Transport,
- private localAddr: string,
+ public addr: Addr,
private closing: boolean = false
) {}
@@ -103,13 +101,6 @@ export class ListenerImpl implements Listener {
close(this.rid);
}
- addr(): Addr {
- return {
- transport: this.transport,
- address: this.localAddr
- };
- }
-
async next(): Promise<IteratorResult<Conn>> {
if (this.closing) {
return { value: undefined, done: true };
@@ -134,9 +125,9 @@ export class ListenerImpl implements Listener {
export interface Conn extends Reader, Writer, Closer {
/** The local address of the connection. */
- localAddr: string;
+ localAddr: Addr;
/** The remote address of the connection. */
- remoteAddr: string;
+ remoteAddr: Addr;
/** The resource ID of the connection. */
rid: number;
/** Shuts down (`shutdown(2)`) the reading side of the TCP connection. Most
@@ -175,12 +166,13 @@ export interface ListenOptions {
export function listen(options: ListenOptions): Listener {
const hostname = options.hostname || "0.0.0.0";
const transport = options.transport || "tcp";
+
const res = sendSync(dispatch.OP_LISTEN, {
hostname,
port: options.port,
transport
});
- return new ListenerImpl(res.rid, transport, res.localAddr);
+ return new ListenerImpl(res.rid, res.localAddr);
}
export interface ConnectOptions {
@@ -189,7 +181,9 @@ export interface ConnectOptions {
transport?: Transport;
}
-/** Dial connects to the address on the named transport.
+const connectDefaults = { hostname: "127.0.0.1", transport: "tcp" };
+
+/** Connects to the address on the named transport.
*
* @param options
* @param options.port The port to connect to. (Required.)
@@ -207,10 +201,7 @@ export interface ConnectOptions {
* connect({ hostname: "golang.org", port: 80, transport: "tcp" })
*/
export async function connect(options: ConnectOptions): Promise<Conn> {
- const res = await sendAsync(dispatch.OP_CONNECT, {
- hostname: options.hostname || "127.0.0.1",
- port: options.port,
- transport: options.transport || "tcp"
- });
+ options = Object.assign(connectDefaults, options);
+ const res = await sendAsync(dispatch.OP_CONNECT, options);
return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
}
diff --git a/cli/js/net_test.ts b/cli/js/net_test.ts
index ec395bc1d..e4d0be81f 100644
--- a/cli/js/net_test.ts
+++ b/cli/js/net_test.ts
@@ -3,11 +3,9 @@ import { testPerm, assert, assertEquals } from "./test_util.ts";
testPerm({ net: true }, function netListenClose(): void {
const listener = Deno.listen({ hostname: "127.0.0.1", port: 4500 });
- const addr = listener.addr();
- assertEquals(addr.transport, "tcp");
- // TODO(ry) Replace 'address' with 'hostname' and 'port', similar to
- // ConnectOptions and ListenOptions.
- assertEquals(addr.address, "127.0.0.1:4500");
+ assertEquals(listener.addr.transport, "tcp");
+ assertEquals(listener.addr.hostname, "127.0.0.1");
+ assertEquals(listener.addr.port, 4500);
listener.close();
});
@@ -52,13 +50,15 @@ testPerm({ net: true }, async function netDialListen(): Promise<void> {
listener.accept().then(
async (conn): Promise<void> => {
assert(conn.remoteAddr != null);
- assertEquals(conn.localAddr, "127.0.0.1:4500");
+ assertEquals(conn.localAddr.hostname, "127.0.0.1");
+ assertEquals(conn.localAddr.port, 4500);
await conn.write(new Uint8Array([1, 2, 3]));
conn.close();
}
);
const conn = await Deno.connect({ hostname: "127.0.0.1", port: 4500 });
- assertEquals(conn.remoteAddr, "127.0.0.1:4500");
+ assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
+ assertEquals(conn.remoteAddr.port, 4500);
assert(conn.localAddr != null);
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
diff --git a/cli/js/tls.ts b/cli/js/tls.ts
index 4dfb32e31..b8815831b 100644
--- a/cli/js/tls.ts
+++ b/cli/js/tls.ts
@@ -6,6 +6,7 @@ import { Listener, Transport, Conn, ConnImpl, ListenerImpl } from "./net.ts";
// TODO(ry) There are many configuration options to add...
// https://docs.rs/rustls/0.16.0/rustls/struct.ClientConfig.html
interface ConnectTLSOptions {
+ transport?: Transport;
port: number;
hostname?: string;
certFile?: string;
@@ -59,5 +60,5 @@ export function listenTLS(options: ListenTLSOptions): Listener {
certFile: options.certFile,
keyFile: options.keyFile
});
- return new TLSListenerImpl(res.rid, transport, res.localAddr);
+ return new TLSListenerImpl(res.rid, res.localAddr);
}
diff --git a/cli/ops/net.rs b/cli/ops/net.rs
index f337a28d8..836ec2e8d 100644
--- a/cli/ops/net.rs
+++ b/cli/ops/net.rs
@@ -117,8 +117,16 @@ fn op_accept(
table.add("tcpStream", Box::new(StreamResource::TcpStream(tcp_stream)));
Ok(json!({
"rid": rid,
- "localAddr": local_addr.to_string(),
- "remoteAddr": remote_addr.to_string(),
+ "localAddr": {
+ "hostname": local_addr.ip().to_string(),
+ "port": local_addr.port(),
+ "transport": "tcp",
+ },
+ "remoteAddr": {
+ "hostname": remote_addr.ip().to_string(),
+ "port": remote_addr.port(),
+ "transport": "tcp",
+ }
}))
};
@@ -152,8 +160,16 @@ fn op_connect(
table.add("tcpStream", Box::new(StreamResource::TcpStream(tcp_stream)));
Ok(json!({
"rid": rid,
- "localAddr": local_addr.to_string(),
- "remoteAddr": remote_addr.to_string(),
+ "localAddr": {
+ "hostname": local_addr.ip().to_string(),
+ "port": local_addr.port(),
+ "transport": args.transport,
+ },
+ "remoteAddr": {
+ "hostname": remote_addr.ip().to_string(),
+ "port": remote_addr.port(),
+ "transport": args.transport,
+ }
}))
};
@@ -272,7 +288,6 @@ fn op_listen(
futures::executor::block_on(resolve_addr(&args.hostname, args.port))?;
let listener = futures::executor::block_on(TcpListener::bind(&addr))?;
let local_addr = listener.local_addr()?;
- let local_addr_str = local_addr.to_string();
let listener_resource = TcpListenerResource {
listener,
waker: None,
@@ -280,10 +295,19 @@ fn op_listen(
};
let mut table = state.lock_resource_table();
let rid = table.add("tcpListener", Box::new(listener_resource));
- debug!("New listener {} {}", rid, local_addr_str);
+ debug!(
+ "New listener {} {}:{}",
+ rid,
+ local_addr.ip().to_string(),
+ local_addr.port()
+ );
Ok(JsonOp::Sync(json!({
"rid": rid,
- "localAddr": local_addr_str,
+ "localAddr": {
+ "hostname": local_addr.ip().to_string(),
+ "port": local_addr.port(),
+ "transport": args.transport,
+ },
})))
}
diff --git a/cli/ops/tls.rs b/cli/ops/tls.rs
index fc2dec0d1..cb0ae2ecb 100644
--- a/cli/ops/tls.rs
+++ b/cli/ops/tls.rs
@@ -53,6 +53,7 @@ pub fn init(i: &mut Isolate, s: &ThreadSafeState) {
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct ConnectTLSArgs {
+ transport: String,
hostname: String,
port: u16,
cert_file: Option<String>,
@@ -101,8 +102,16 @@ pub fn op_connect_tls(
);
Ok(json!({
"rid": rid,
- "localAddr": local_addr.to_string(),
- "remoteAddr": remote_addr.to_string(),
+ "localAddr": {
+ "hostname": local_addr.ip().to_string(),
+ "port": local_addr.port(),
+ "transport": args.transport,
+ },
+ "remoteAddr": {
+ "hostname": remote_addr.ip().to_string(),
+ "port": remote_addr.port(),
+ "transport": args.transport,
+ }
}))
};
@@ -257,7 +266,6 @@ fn op_listen_tls(
futures::executor::block_on(resolve_addr(&args.hostname, args.port))?;
let listener = futures::executor::block_on(TcpListener::bind(&addr))?;
let local_addr = listener.local_addr()?;
- let local_addr_str = local_addr.to_string();
let tls_listener_resource = TlsListenerResource {
listener,
tls_acceptor,
@@ -269,7 +277,11 @@ fn op_listen_tls(
Ok(JsonOp::Sync(json!({
"rid": rid,
- "localAddr": local_addr_str
+ "localAddr": {
+ "hostname": local_addr.ip().to_string(),
+ "port": local_addr.port(),
+ "transport": args.transport,
+ },
})))
}
@@ -371,8 +383,16 @@ fn op_accept_tls(
};
Ok(json!({
"rid": rid,
- "localAddr": local_addr.to_string(),
- "remoteAddr": remote_addr.to_string(),
+ "localAddr": {
+ "transport": "tcp",
+ "hostname": local_addr.ip().to_string(),
+ "port": local_addr.port()
+ },
+ "remoteAddr": {
+ "transport": "tcp",
+ "hostname": remote_addr.ip().to_string(),
+ "port": remote_addr.port()
+ }
}))
};
diff --git a/std/http/server_test.ts b/std/http/server_test.ts
index aee9db0ff..a4bc58ad1 100644
--- a/std/http/server_test.ts
+++ b/std/http/server_test.ts
@@ -41,6 +41,29 @@ const dec = new TextDecoder();
type Handler = () => void;
+const mockConn = {
+ localAddr: {
+ transport: "tcp",
+ hostname: "",
+ port: 0
+ },
+ remoteAddr: {
+ transport: "tcp",
+ hostname: "",
+ port: 0
+ },
+ rid: -1,
+ closeRead: (): void => {},
+ closeWrite: (): void => {},
+ read: async (): Promise<number | Deno.EOF> => {
+ return 0;
+ },
+ write: async (): Promise<number> => {
+ return -1;
+ },
+ close: (): void => {}
+};
+
const responseTests: ResponseTest[] = [
// Default response
{
@@ -75,20 +98,7 @@ test(async function responseWrite(): Promise<void> {
const request = new ServerRequest();
request.w = bufw;
- request.conn = {
- localAddr: "",
- remoteAddr: "",
- rid: -1,
- closeRead: (): void => {},
- closeWrite: (): void => {},
- read: async (): Promise<number | Deno.EOF> => {
- return 0;
- },
- write: async (): Promise<number> => {
- return -1;
- },
- close: (): void => {}
- };
+ request.conn = mockConn as Deno.Conn;
await request.respond(testCase.response);
assertEquals(buf.toString(), testCase.raw);
@@ -416,21 +426,6 @@ test(async function writeStringReaderResponse(): Promise<void> {
assertEquals(r.more, false);
});
-const mockConn = {
- localAddr: "",
- remoteAddr: "",
- rid: -1,
- closeRead: (): void => {},
- closeWrite: (): void => {},
- read: async (): Promise<number | Deno.EOF> => {
- return 0;
- },
- write: async (): Promise<number> => {
- return -1;
- },
- close: (): void => {}
-};
-
test(async function readRequestError(): Promise<void> {
const input = `GET / HTTP/1.1
malformedHeader
@@ -438,7 +433,7 @@ malformedHeader
const reader = new BufReader(new StringReader(input));
let err;
try {
- await readRequest(mockConn, reader);
+ await readRequest(mockConn as Deno.Conn, reader);
} catch (e) {
err = e;
}
@@ -517,7 +512,7 @@ test(async function testReadRequestError(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let req: any;
try {
- req = await readRequest(mockConn, reader);
+ req = await readRequest(mockConn as Deno.Conn, reader);
} catch (e) {
err = e;
}