Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add app protocol #130

Merged
merged 5 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions ngrok/examples/labeled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ async fn start_tunnel() -> anyhow::Result<LabeledTunnel> {

let tun = sess
.labeled_tunnel()
//.app_protocol("http2")
.label("edge", "edghts_<edge_id>")
.metadata("example tunnel metadata from rust")
.listen()
Expand Down
8 changes: 8 additions & 0 deletions ngrok/src/config/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ pub(crate) trait TunnelConfig {
///
/// Only for display/informational purposes.
fn forwards_to(&self) -> String;
/// The L7 protocol the upstream service expects
fn forwards_proto(&self) -> String;
/// Internal-only, extra data sent when binding a tunnel.
fn extra(&self) -> BindExtra;
/// The protocol for this tunnel.
Expand All @@ -145,6 +147,10 @@ where
fn forwards_to(&self) -> String {
(**self).forwards_to()
}

fn forwards_proto(&self) -> String {
(**self).forwards_proto()
}
fn extra(&self) -> BindExtra {
(**self).extra()
}
Expand Down Expand Up @@ -190,6 +196,8 @@ pub(crate) struct CommonOpts {
// Tunnel backend metadata. Viewable via the dashboard and API, but has no
// bearing on tunnel behavior.
pub(crate) forwards_to: Option<String>,
// Tunnel L7 app protocol
pub(crate) forwards_proto: Option<String>,
}

impl CommonOpts {
Expand Down
20 changes: 19 additions & 1 deletion ngrok/src/config/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ impl TunnelConfig for HttpOptions {
.clone()
.unwrap_or(default_forwards_to().into())
}

fn forwards_proto(&self) -> String {
self.common_opts
.forwards_proto
.clone()
.unwrap_or(String::new())
OfTheDelmer marked this conversation as resolved.
Show resolved Hide resolved
}

fn extra(&self) -> BindExtra {
BindExtra {
token: Default::default(),
Expand Down Expand Up @@ -253,11 +261,19 @@ impl HttpTunnelBuilder {
self.options.common_opts.forwards_to = Some(forwards_to.into());
self
}

/// Sets the L7 protocol for this tunnel.
pub fn app_protocol(&mut self, app_protocol: impl Into<String>) -> &mut Self {
self.options.common_opts.forwards_proto = Some(app_protocol.into());
self
}

/// Sets the scheme for this edge.
pub fn scheme(&mut self, scheme: Scheme) -> &mut Self {
self.options.scheme = scheme;
self
}

/// Sets the domain to request for this edge.
///
/// https://ngrok.com/docs/network-edge/domains-and-tcp-addresses/#domains
Expand Down Expand Up @@ -422,6 +438,7 @@ mod test {

const METADATA: &str = "testmeta";
const TEST_FORWARD: &str = "testforward";
const TEST_FORWARD_PROTO: &str = "http2";
const ALLOW_CIDR: &str = "0.0.0.0/0";
const DENY_CIDR: &str = "10.1.1.1/32";
const CA_CERT: &[u8] = "test ca cert".as_bytes();
Expand Down Expand Up @@ -473,6 +490,7 @@ mod test {
.webhook_verification("twilio", "asdf")
.basic_auth("ngrok", "online1line")
.forwards_to(TEST_FORWARD)
.app_protocol("http2")
.options,
);
}
Expand All @@ -482,7 +500,7 @@ mod test {
C: TunnelConfig,
{
assert_eq!(TEST_FORWARD, tunnel_cfg.forwards_to());

assert_eq!(TEST_FORWARD_PROTO, tunnel_cfg.forwards_proto());
let extra = tunnel_cfg.extra();
assert_eq!(String::default(), *extra.token);
assert_eq!(METADATA, extra.metadata);
Expand Down
14 changes: 14 additions & 0 deletions ngrok/src/config/labeled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ impl TunnelConfig for LabeledOptions {
.clone()
.unwrap_or(default_forwards_to().into())
}

fn forwards_proto(&self) -> String {
self.common_opts
.forwards_proto
.clone()
.unwrap_or(String::new())
}

fn extra(&self) -> BindExtra {
BindExtra {
token: Default::default(),
Expand Down Expand Up @@ -90,6 +98,12 @@ impl LabeledTunnelBuilder {
self
}

/// Sets the L7 protocol string for this tunnel.
pub fn app_protocol(&mut self, app_protocol: impl Into<String>) -> &mut Self {
self.options.common_opts.forwards_proto = Some(app_protocol.into());
self
}

pub(crate) async fn for_forwarding_to(&mut self, to_url: &Url) -> &mut Self {
self.options.common_opts.for_forwarding_to(to_url);
self
Expand Down
6 changes: 6 additions & 0 deletions ngrok/src/config/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ impl TunnelConfig for TcpOptions {
fn proto(&self) -> String {
"tcp".into()
}

fn forwards_proto(&self) -> String {
// not supported
String::new()
}

fn opts(&self) -> Option<BindOpts> {
// fill out all the options, translating to proto here
let mut tcp_endpoint = proto::TcpEndpoint::default();
Expand Down
7 changes: 7 additions & 0 deletions ngrok/src/config/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ impl TunnelConfig for TlsOptions {
.clone()
.unwrap_or(default_forwards_to().into())
}

fn forwards_proto(&self) -> String {
// not supported
String::new()
}

fn extra(&self) -> BindExtra {
BindExtra {
token: Default::default(),
Expand All @@ -56,6 +62,7 @@ impl TunnelConfig for TlsOptions {
fn proto(&self) -> String {
"tls".into()
}

fn opts(&self) -> Option<BindOpts> {
// fill out all the options, translating to proto here
let mut tls_endpoint = proto::TlsEndpoint::default();
Expand Down
2 changes: 2 additions & 0 deletions ngrok/src/internals/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ pub struct Bind<T> {
pub client_id: String,
pub proto: String,
pub forwards_to: String,
pub forwards_proto: String,
pub opts: T,
pub extra: BindExtra,
}
Expand Down Expand Up @@ -347,6 +348,7 @@ rpc_req!(Bind<T>, BindResp<T>, BIND_REQ; T: std::fmt::Debug + Serialize + Deseri
pub struct StartTunnelWithLabel {
pub labels: HashMap<String, String>,
pub forwards_to: String,
pub forwards_proto: String,
pub metadata: String,
}

Expand Down
4 changes: 4 additions & 0 deletions ngrok/src/internals/raw_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ impl RpcClient {
extra: BindExtra,
id: impl Into<String> + Debug,
forwards_to: impl Into<String> + Debug,
forwards_proto: impl Into<String> + Debug,
) -> Result<BindResp<BindOpts>, RpcError> {
// Sorry, this is awful. Serde untagged unions are pretty fraught and
// hard to debug, so we're using this macro to specialize this call
Expand All @@ -339,6 +340,7 @@ impl RpcClient {
client_id: id.into(),
proto: protocol.into(),
forwards_to: forwards_to.into(),
forwards_proto: forwards_proto.into(),
opts,
extra,
};
Expand All @@ -364,11 +366,13 @@ impl RpcClient {
labels: HashMap<String, String>,
metadata: impl Into<String> + Debug,
forwards_to: impl Into<String> + Debug,
forwards_proto: impl Into<String> + Debug,
) -> Result<StartTunnelWithLabelResp, RpcError> {
let req = StartTunnelWithLabel {
labels,
metadata: metadata.into(),
forwards_to: forwards_to.into(),
forwards_proto: forwards_proto.into(),
};

self.rpc(req).await
Expand Down
20 changes: 18 additions & 2 deletions ngrok/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ struct BoundTunnel {
extra: BindExtra,
labels: HashMap<String, String>,
forwards_to: String,
forwards_proto: String,
tx: Sender<Result<ConnInner, AcceptError>>,
}

Expand Down Expand Up @@ -882,6 +883,7 @@ impl Session {
let mut extra = tunnel_cfg.extra();
let labels = tunnel_cfg.labels();
let forwards_to = tunnel_cfg.forwards_to();
let forwards_proto = tunnel_cfg.forwards_proto();

// non-labeled tunnel
let (tunnel, bound) = if tunnel_cfg.proto() != "" {
Expand All @@ -892,6 +894,7 @@ impl Session {
extra.clone(),
"",
&forwards_to,
&forwards_proto,
)
.await?;

Expand All @@ -917,13 +920,19 @@ impl Session {
extra,
labels,
forwards_to,
forwards_proto,
tx,
},
)
} else {
// labeled tunnel
let resp = client
.listen_label(labels.clone(), &extra.metadata, &forwards_to)
.listen_label(
labels.clone(),
&extra.metadata,
&forwards_to,
&forwards_proto,
)
.await?;

let info = TunnelInnerInfo {
Expand All @@ -946,6 +955,7 @@ impl Session {
proto: Default::default(),
opts: Default::default(),
forwards_to,
forwards_proto,
labels,
tx,
},
Expand Down Expand Up @@ -1079,14 +1089,20 @@ async fn try_reconnect(
tun.extra.clone(),
id,
&tun.forwards_to,
&tun.forwards_proto,
)
.await
.map_err(ConnectError::Rebind)?;
debug!(?resp, %id, %tun.proto, ?tun.opts, ?tun.extra, %tun.forwards_to, "rebound tunnel");
new_tunnels.insert(id.clone(), tun.clone());
} else {
let resp = client
.listen_label(tun.labels.clone(), &tun.extra.metadata, &tun.forwards_to)
.listen_label(
tun.labels.clone(),
&tun.extra.metadata,
&tun.forwards_to,
&tun.forwards_proto,
)
.await
.map_err(ConnectError::Rebind)?;

Expand Down
1 change: 1 addition & 0 deletions ngrok/src/tunnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ macro_rules! tunnel_trait {
/// [TcpTunnelBuilder::forwards_to], etc. to set this value
/// explicitly.
fn forwards_to(&self) -> &str;

/// Returns the arbitrary metadata string for this tunnel.
fn metadata(&self) -> &str;
}
Expand Down
Loading