use axum::{Router, serve};
use axum_reverse_proxy::{DiscoverableBalancedProxy, DnsDiscovery, DnsDiscoveryConfig};
use hyper_util::client::legacy::{Client, connect::HttpConnector};
use std::time::Duration;
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let dns_config = DnsDiscoveryConfig::new("httpbin.org", 80)
.with_refresh_interval(Duration::from_secs(30))
.with_https(false);
let discovery = DnsDiscovery::new(dns_config).expect("Failed to create DNS discovery");
let mut connector = HttpConnector::new();
connector.set_nodelay(true);
connector.enforce_http(false);
#[cfg(all(feature = "tls", not(feature = "native-tls")))]
let connector = {
use hyper_rustls::HttpsConnectorBuilder;
HttpsConnectorBuilder::new()
.with_native_roots()
.unwrap()
.https_or_http()
.enable_http1()
.wrap_connector(connector)
};
#[cfg(feature = "native-tls")]
let connector = {
use hyper_tls::HttpsConnector;
HttpsConnector::new_with_connector(connector)
};
let client = Client::builder(hyper_util::rt::TokioExecutor::new())
.pool_idle_timeout(Duration::from_secs(60))
.pool_max_idle_per_host(32)
.retry_canceled_requests(true)
.set_host(true)
.build(connector);
let mut proxy = DiscoverableBalancedProxy::new_with_client("/api", client, discovery);
proxy.start_discovery().await;
tokio::time::sleep(Duration::from_millis(500)).await;
println!("Discovered {} services", proxy.service_count().await);
let app: Router = Router::new().nest_service("/", proxy);
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
println!("Server running on http://localhost:3000");
println!("Try: curl http://localhost:3000/api/get");
println!(
"The proxy will automatically load balance across all IP addresses resolved for httpbin.org"
);
serve(listener, app).await.unwrap();
}