Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ napi_sym = { version = "0.141.0", path = "./ext/napi/sym" }
node_resolver = { version = "0.49.0", path = "./libs/node_resolver" }
test_util = { package = "test_server", path = "./tests/util/server" }

deno_tunnel = "0.5.0"
deno_tunnel = "0.7.0"

# widely used libraries
anyhow = "1.0.57"
Expand Down
6 changes: 5 additions & 1 deletion cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,11 @@ async fn resolve_flags_and_init(
.or_else(|| env::var("DENO_CONNECTED").ok())
{
if let Err(err) = initialize_tunnel(&host, &flags).await {
exit_for_error(AnyError::from(err))
exit_for_error(err.context("Failed to start with --connected"));
}
// SAFETY: We're doing this before any threads are created.
unsafe {
std::env::set_var("DENO_CONNECTED", &host);
}
}

Expand Down
17 changes: 15 additions & 2 deletions ext/net/tunnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::collections::HashMap;
use std::net::SocketAddr;
use std::rc::Rc;
use std::sync::OnceLock;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;

use deno_core::AsyncMutFuture;
use deno_core::AsyncRefCell;
Expand All @@ -27,14 +29,25 @@ use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;

static TUNNEL: OnceLock<TunnelConnection> = OnceLock::new();
static RUN_BEFORE_EXIT: AtomicBool = AtomicBool::new(true);

pub fn set_tunnel(tunnel: TunnelConnection) {
if TUNNEL.set(tunnel).is_ok() {
deno_signals::before_exit(before_exit);
deno_signals::before_exit(before_exit_internal);
}
}

fn before_exit() {
fn before_exit_internal() {
if RUN_BEFORE_EXIT.load(Ordering::Relaxed) {
before_exit();
}
}

pub fn disable_before_exit() {
RUN_BEFORE_EXIT.store(false, Ordering::Relaxed);
}

pub fn before_exit() {
if let Some(tunnel) = get_tunnel() {
log::trace!("deno_net::tunnel::before_exit >");

Expand Down
3 changes: 3 additions & 0 deletions ext/telemetry/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,7 @@ pub fn init(
.map_err(|_| deno_core::anyhow::anyhow!("failed to set otel globals"))?;

deno_signals::before_exit(before_exit);
deno_net::tunnel::disable_before_exit();

Ok(())
}
Expand All @@ -953,6 +954,8 @@ fn before_exit() {

let r = meter_provider.shutdown();
log::trace!("meters={:?}", r);

deno_net::tunnel::before_exit();
}

pub fn handle_log(record: &log::Record) {
Expand Down
1 change: 1 addition & 0 deletions tests/specs/run/tunnel/test.out
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
You are connected to https://localhost:[WILDLINE]!
HTTP/1.1 200 OK
content-type: application/json
vary: Accept-Encoding
Expand Down
19 changes: 15 additions & 4 deletions tests/specs/run/tunnel/test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const VERSION = 1;
const VERSION = 2;

const server = new Deno.QuicEndpoint({
hostname: "localhost",
Expand Down Expand Up @@ -31,6 +31,7 @@ const child = new Deno.Command(Deno.execPath(), {
}).spawn();

setTimeout(() => {
console.error("timeout, killing");
child.kill("SIGKILL");
Deno.exit(1);
}, 5000);
Expand All @@ -48,19 +49,19 @@ async function handleConnection(conn: Deno.QuicConn) {
const reader = bi.readable.getReader({ mode: "byob" });
const version = await readUint32LE(reader);
if (version !== VERSION) {
conn.close();
conn.close({ closeCode: 1, reason: "invalid version" });
return;
}
const writer = bi.writable.getWriter();
await writeUint32LE(writer, VERSION);
const header = await readStreamHeader(reader);
if (header.headerType !== "Control") {
conn.close();
conn.close({ closeCode: 1, reason: "expected Control" });
return;
}
const auth = await readStreamHeader(reader);
if (auth.headerType !== "AuthenticateApp") {
conn.close();
conn.close({ closeCode: 1, reason: "expected AuthenticateApp" });
return;
}
await writeStreamHeader(writer, {
Expand All @@ -75,6 +76,16 @@ async function handleConnection(conn: Deno.QuicConn) {
metadata: {},
});

const next = await readStreamHeader(reader);
if (next.headerType !== "Listening") {
conn.close({ closeCode: 1, reason: "expected Listening" });
return;
}

await writeStreamHeader(writer, {
headerType: "Routed",
});

reader.releaseLock();
writer.releaseLock();
}
Expand Down
Loading