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

Drone Proxy: Allow Custom Routes #289

Closed
t-moe opened this issue Dec 21, 2022 · 5 comments · Fixed by #290
Closed

Drone Proxy: Allow Custom Routes #289

t-moe opened this issue Dec 21, 2022 · 5 comments · Fixed by #290
Labels
enhancement New feature or request

Comments

@t-moe
Copy link

t-moe commented Dec 21, 2022

We're using plane in the standalone configuration (single drone, without dnsmasq / firefox).
We use a wilcard dns to map *.example.com => 1.2.3.4

In order to manage plane, we have a custom webservice. Currently we need a separate host or port for that, but we would like to host that on the same host and port as the drone.
For Example:

  • When we visit example.com we reach our custom webservice (e.g. listening on 127.0.0.1:4567)
  • When we visit e485cf9a-fc65-4d7c-935e-656572068226.example.com => we reach the launched backend

It would be nice if we could provide custom subdomain to route mapping in the drone.toml as a map.
Example:

[proxy]
# IP to listen for connections on.
bind_ip = "0.0.0.0"

[proxy.custom_route]
host = "status.example.com"
route = "http://127.0.0.1:9874"

[proxy.custom_route]
host = "example.com"
route = "http://127.0.0.1:4567"

If I'm correct, I could extend the code here, to make that work:

let host = std::str::from_utf8(host.as_bytes())?;
// If the host includes a port, strip it.
let host = host.split_once(':').map(|(host, _)| host).unwrap_or(host);
tracing::info!(ip=%self.remote_ip, url=%req.uri(), "Proxy Request");
// TODO: we shouldn't need to allocate a string just to strip a prefix.
if let Some(subdomain) = host.strip_suffix(&format!(".{}", self.cluster)) {
let subdomain = subdomain.to_string();
if let Some(addr) = self.db.get_proxy_route(&subdomain).await? {
self.connection_tracker.track_request(&subdomain);
*req.uri_mut() = Self::rewrite_uri(&addr, req.uri())?;
if let Some(connection) = req.headers().get(hyper::http::header::CONNECTION) {
if connection
.to_str()
.unwrap_or_default()
.to_lowercase()
.contains(UPGRADE)
{
return self.handle_upgrade(req, &subdomain).await;
}
}
let result = self
.client
.request(req)
.await
.context("Error handling client request.")?;
return Ok(result);
}
}
tracing::warn!(?host, "Unrecognized host.");

@paulgb
Copy link
Member

paulgb commented Dec 21, 2022

I understand the use case here but I'm a little cautious about adding a feature that only makes sense in a single-drone context.

One possibility would be to allow a "fallback" address that anything that is not a current backend is proxied to. In a multi-drone context this would provide a way to display a custom page when an invalid domain is accessed. In your case, it could point to a local nginx/caddy/whatever server which could serve from different directories depending on the hostname.

@t-moe
Copy link
Author

t-moe commented Dec 21, 2022

I see your point.
Yes, a single "fallback" address would be enough. At the moment we only need a single custom route anyways and if we need more later we can still fire up a local nginx (as you said).

@paulgb
Copy link
Member

paulgb commented Dec 21, 2022

Gotcha, this should be do-able then. I should be able to do this over the next couple of days, but if you want to take it on I'd also accept a PR.

My preference would be for this to be a single string like this:

[proxy]
bind_ip = "0.0.0.0"
fallback_addr = "12.12.12.12:8080"

(i.e. no http://)

@paulgb paulgb added the enhancement New feature or request label Dec 21, 2022
@t-moe
Copy link
Author

t-moe commented Jan 9, 2023

This works like a charm.

Paul, Thank you so much for the fast support and for adding the custom features I've requested. 🙌

@paulgb
Copy link
Member

paulgb commented Jan 9, 2023

Glad it works, thanks for following up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants