mirror of
https://github.com/denoland/deno.git
synced 2025-01-03 04:48:52 -05:00
fix(unstable): Deno.serve() can parse hostnames (#15579)
This commit is contained in:
parent
5268fa0e0f
commit
a4cc09447e
2 changed files with 49 additions and 15 deletions
|
@ -34,16 +34,27 @@ function onListen<T>(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Deno.test(async function httpServerInvalidHostname() {
|
Deno.test(async function httpServerCanResolveHostnames() {
|
||||||
await assertRejects(
|
const ac = new AbortController();
|
||||||
() =>
|
const listeningPromise = deferred();
|
||||||
Deno.serve({
|
|
||||||
|
const server = Deno.serve({
|
||||||
handler: (_req) => new Response("ok"),
|
handler: (_req) => new Response("ok"),
|
||||||
hostname: "localhost",
|
hostname: "localhost",
|
||||||
}),
|
port: 4501,
|
||||||
TypeError,
|
signal: ac.signal,
|
||||||
"hostname could not be parsed as an IP address",
|
onListen: onListen(listeningPromise),
|
||||||
);
|
onError: createOnErrorCb(ac),
|
||||||
|
});
|
||||||
|
|
||||||
|
await listeningPromise;
|
||||||
|
const resp = await fetch("http://localhost:4501/", {
|
||||||
|
headers: { "connection": "close" },
|
||||||
|
});
|
||||||
|
const text = await resp.text();
|
||||||
|
assertEquals(text, "ok");
|
||||||
|
ac.abort();
|
||||||
|
await server;
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test({ permissions: { net: true } }, async function httpServerBasic() {
|
Deno.test({ permissions: { net: true } }, async function httpServerBasic() {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// https://github.com/rust-lang/rust-clippy/issues/6446
|
// https://github.com/rust-lang/rust-clippy/issues/6446
|
||||||
#![allow(clippy::await_holding_lock)]
|
#![allow(clippy::await_holding_lock)]
|
||||||
|
|
||||||
|
use deno_core::error::generic_error;
|
||||||
use deno_core::error::type_error;
|
use deno_core::error::type_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::op;
|
use deno_core::op;
|
||||||
|
@ -47,6 +48,7 @@ use std::io::Write;
|
||||||
use std::marker::PhantomPinned;
|
use std::marker::PhantomPinned;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
use std::net::ToSocketAddrs;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -1232,6 +1234,28 @@ fn run_server(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_addr_port_pair(hostname: &str, port: u16) -> (&str, u16) {
|
||||||
|
// Default to localhost if given just the port. Example: ":80"
|
||||||
|
if hostname.is_empty() {
|
||||||
|
return ("0.0.0.0", port);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this looks like an ipv6 IP address. Example: "[2001:db8::1]"
|
||||||
|
// Then we remove the brackets.
|
||||||
|
let addr = hostname.trim_start_matches('[').trim_end_matches(']');
|
||||||
|
(addr, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resolve network address *synchronously*.
|
||||||
|
pub fn resolve_addr_sync(
|
||||||
|
hostname: &str,
|
||||||
|
port: u16,
|
||||||
|
) -> Result<impl Iterator<Item = SocketAddr>, AnyError> {
|
||||||
|
let addr_port_pair = make_addr_port_pair(hostname, port);
|
||||||
|
let result = addr_port_pair.to_socket_addrs()?;
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
fn op_flash_serve<P>(
|
fn op_flash_serve<P>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
|
@ -1244,11 +1268,10 @@ where
|
||||||
state
|
state
|
||||||
.borrow_mut::<P>()
|
.borrow_mut::<P>()
|
||||||
.check_net(&(&opts.hostname, Some(opts.port)))?;
|
.check_net(&(&opts.hostname, Some(opts.port)))?;
|
||||||
let parsed_hostname = opts
|
|
||||||
.hostname
|
let addr = resolve_addr_sync(&opts.hostname, opts.port)?
|
||||||
.parse()
|
.next()
|
||||||
.map_err(|_| type_error("hostname could not be parsed as an IP address"))?;
|
.ok_or_else(|| generic_error("No resolved address found"))?;
|
||||||
let addr = SocketAddr::new(parsed_hostname, opts.port);
|
|
||||||
let (tx, rx) = mpsc::channel(100);
|
let (tx, rx) = mpsc::channel(100);
|
||||||
let (close_tx, close_rx) = mpsc::channel(1);
|
let (close_tx, close_rx) = mpsc::channel(1);
|
||||||
let (listening_tx, listening_rx) = mpsc::channel(1);
|
let (listening_tx, listening_rx) = mpsc::channel(1);
|
||||||
|
|
Loading…
Reference in a new issue