1
0
Fork 0
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:
Bartek Iwańczuk 2019-08-27 17:35:32 +02:00 committed by Ryan Dahl
parent b6a4ec7d16
commit 20739a8111
3 changed files with 50 additions and 16 deletions

View file

@ -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()
})))
} }

View file

@ -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.

View file

@ -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);