mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 16:49:18 -05:00
feat: implement Addr interface (#2821)
This commit is contained in:
parent
b6a4ec7d16
commit
20739a8111
3 changed files with 50 additions and 16 deletions
|
@ -32,11 +32,18 @@ pub fn op_accept(
|
||||||
None => Err(deno_error::bad_resource()),
|
None => Err(deno_error::bad_resource()),
|
||||||
Some(server_resource) => {
|
Some(server_resource) => {
|
||||||
let op = tokio_util::accept(server_resource)
|
let op = tokio_util::accept(server_resource)
|
||||||
.map_err(ErrBox::from)
|
|
||||||
.and_then(move |(tcp_stream, _socket_addr)| {
|
.and_then(move |(tcp_stream, _socket_addr)| {
|
||||||
|
let local_addr = tcp_stream.local_addr()?;
|
||||||
|
let remote_addr = tcp_stream.peer_addr()?;
|
||||||
let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
|
let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
|
||||||
|
Ok((tcp_stream_resource, local_addr, remote_addr))
|
||||||
|
})
|
||||||
|
.map_err(ErrBox::from)
|
||||||
|
.and_then(move |(tcp_stream_resource, local_addr, remote_addr)| {
|
||||||
futures::future::ok(json!({
|
futures::future::ok(json!({
|
||||||
"rid": tcp_stream_resource.rid
|
"rid": tcp_stream_resource.rid,
|
||||||
|
"localAddr": local_addr.to_string(),
|
||||||
|
"remoteAddr": remote_addr.to_string(),
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -64,14 +71,22 @@ pub fn op_dial(
|
||||||
state.check_net(&address)?;
|
state.check_net(&address)?;
|
||||||
|
|
||||||
let op = resolve_addr(&address).and_then(move |addr| {
|
let op = resolve_addr(&address).and_then(move |addr| {
|
||||||
TcpStream::connect(&addr).map_err(ErrBox::from).and_then(
|
TcpStream::connect(&addr)
|
||||||
move |tcp_stream| {
|
.map_err(ErrBox::from)
|
||||||
|
.and_then(move |tcp_stream| {
|
||||||
|
let local_addr = tcp_stream.local_addr()?;
|
||||||
|
let remote_addr = tcp_stream.peer_addr()?;
|
||||||
let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
|
let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
|
||||||
|
Ok((tcp_stream_resource, local_addr, remote_addr))
|
||||||
|
})
|
||||||
|
.map_err(ErrBox::from)
|
||||||
|
.and_then(move |(tcp_stream_resource, local_addr, remote_addr)| {
|
||||||
futures::future::ok(json!({
|
futures::future::ok(json!({
|
||||||
"rid": tcp_stream_resource.rid
|
"rid": tcp_stream_resource.rid,
|
||||||
|
"localAddr": local_addr.to_string(),
|
||||||
|
"remoteAddr": remote_addr.to_string(),
|
||||||
}))
|
}))
|
||||||
},
|
})
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(JsonOp::Async(Box::new(op)))
|
Ok(JsonOp::Async(Box::new(op)))
|
||||||
|
@ -129,7 +144,11 @@ pub fn op_listen(
|
||||||
|
|
||||||
let addr = resolve_addr(&address).wait()?;
|
let addr = resolve_addr(&address).wait()?;
|
||||||
let listener = TcpListener::bind(&addr)?;
|
let listener = TcpListener::bind(&addr)?;
|
||||||
|
let local_addr = listener.local_addr()?;
|
||||||
let resource = resources::add_tcp_listener(listener);
|
let resource = resources::add_tcp_listener(listener);
|
||||||
|
|
||||||
Ok(JsonOp::Sync(json!(resource.rid)))
|
Ok(JsonOp::Sync(json!({
|
||||||
|
"rid": resource.rid,
|
||||||
|
"localAddr": local_addr.to_string()
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
|
|
24
js/net.ts
24
js/net.ts
|
@ -9,8 +9,10 @@ export type Network = "tcp";
|
||||||
// TODO support other types:
|
// TODO support other types:
|
||||||
// export type Network = "tcp" | "tcp4" | "tcp6" | "unix" | "unixpacket";
|
// export type Network = "tcp" | "tcp4" | "tcp6" | "unix" | "unixpacket";
|
||||||
|
|
||||||
// TODO Support finding network from Addr, see https://golang.org/pkg/net/#Addr
|
export interface Addr {
|
||||||
export type Addr = string;
|
network: Network;
|
||||||
|
address: string;
|
||||||
|
}
|
||||||
|
|
||||||
/** A Listener is a generic network listener for stream-oriented protocols. */
|
/** A Listener is a generic network listener for stream-oriented protocols. */
|
||||||
export interface Listener extends AsyncIterator<Conn> {
|
export interface Listener extends AsyncIterator<Conn> {
|
||||||
|
@ -75,12 +77,15 @@ class ConnImpl implements Conn {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ListenerImpl implements Listener {
|
class ListenerImpl implements Listener {
|
||||||
constructor(readonly rid: number) {}
|
constructor(
|
||||||
|
readonly rid: number,
|
||||||
|
private network: Network,
|
||||||
|
private localAddr: string
|
||||||
|
) {}
|
||||||
|
|
||||||
async accept(): Promise<Conn> {
|
async accept(): Promise<Conn> {
|
||||||
const res = await sendAsync(dispatch.OP_ACCEPT, { rid: this.rid });
|
const res = await sendAsync(dispatch.OP_ACCEPT, { rid: this.rid });
|
||||||
// TODO(bartlomieju): add remoteAddr and localAddr on Rust side
|
return new ConnImpl(res.rid, res.remoteAddr, res.localAddr);
|
||||||
return new ConnImpl(res.rid, res.remoteAddr!, res.localAddr!);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(): void {
|
close(): void {
|
||||||
|
@ -88,7 +93,10 @@ class ListenerImpl implements Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
addr(): Addr {
|
addr(): Addr {
|
||||||
return notImplemented();
|
return {
|
||||||
|
network: this.network,
|
||||||
|
address: this.localAddr
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async next(): Promise<IteratorResult<Conn>> {
|
async next(): Promise<IteratorResult<Conn>> {
|
||||||
|
@ -136,8 +144,8 @@ export interface Conn extends Reader, Writer, Closer {
|
||||||
* See `dial()` for a description of the network and address parameters.
|
* See `dial()` for a description of the network and address parameters.
|
||||||
*/
|
*/
|
||||||
export function listen(network: Network, address: string): Listener {
|
export function listen(network: Network, address: string): Listener {
|
||||||
const rid = sendSync(dispatch.OP_LISTEN, { network, address });
|
const res = sendSync(dispatch.OP_LISTEN, { network, address });
|
||||||
return new ListenerImpl(rid);
|
return new ListenerImpl(res.rid, network, res.localAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Dial connects to the address on the named network.
|
/** Dial connects to the address on the named network.
|
||||||
|
|
|
@ -3,6 +3,9 @@ import { testPerm, assert, assertEquals } from "./test_util.ts";
|
||||||
|
|
||||||
testPerm({ net: true }, function netListenClose(): void {
|
testPerm({ net: true }, function netListenClose(): void {
|
||||||
const listener = Deno.listen("tcp", "127.0.0.1:4500");
|
const listener = Deno.listen("tcp", "127.0.0.1:4500");
|
||||||
|
const addr = listener.addr();
|
||||||
|
assertEquals(addr.network, "tcp");
|
||||||
|
assertEquals(addr.address, "127.0.0.1:4500");
|
||||||
listener.close();
|
listener.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -46,11 +49,15 @@ testPerm({ net: true }, async function netDialListen(): Promise<void> {
|
||||||
const listener = Deno.listen("tcp", ":4500");
|
const listener = Deno.listen("tcp", ":4500");
|
||||||
listener.accept().then(
|
listener.accept().then(
|
||||||
async (conn): Promise<void> => {
|
async (conn): Promise<void> => {
|
||||||
|
assert(conn.remoteAddr != null);
|
||||||
|
assertEquals(conn.localAddr, "127.0.0.1:4500");
|
||||||
await conn.write(new Uint8Array([1, 2, 3]));
|
await conn.write(new Uint8Array([1, 2, 3]));
|
||||||
conn.close();
|
conn.close();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const conn = await Deno.dial("tcp", "127.0.0.1:4500");
|
const conn = await Deno.dial("tcp", "127.0.0.1:4500");
|
||||||
|
assertEquals(conn.remoteAddr, "127.0.0.1:4500");
|
||||||
|
assert(conn.localAddr != null);
|
||||||
const buf = new Uint8Array(1024);
|
const buf = new Uint8Array(1024);
|
||||||
const readResult = await conn.read(buf);
|
const readResult = await conn.read(buf);
|
||||||
assertEquals(3, readResult);
|
assertEquals(3, readResult);
|
||||||
|
|
Loading…
Reference in a new issue