Skip to content

Commit 9e33bdf

Browse files
risssondavepgreene
authored andcommitted
packages/ak-axum/server: init (goauthentik#21317)
1 parent d111cd8 commit 9e33bdf

4 files changed

Lines changed: 150 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/ak-axum/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ publish.workspace = true
1111

1212
[dependencies]
1313
ak-common.workspace = true
14+
axum-server.workspace = true
1415
axum.workspace = true
1516
durstr.workspace = true
1617
eyre.workspace = true

packages/ak-axum/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
33
pub mod error;
44
pub mod router;
5+
pub mod server;
56
pub mod tracing;

packages/ak-axum/src/server.rs

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//! Utilities to run an axum server.
2+
3+
use std::{net, os::unix};
4+
5+
use ak_common::arbiter::{Arbiter, Tasks};
6+
use axum::Router;
7+
use axum_server::{
8+
Handle,
9+
accept::DefaultAcceptor,
10+
tls_rustls::{RustlsAcceptor, RustlsConfig},
11+
};
12+
use eyre::Result;
13+
use tracing::info;
14+
15+
async fn run_plain(
16+
arbiter: Arbiter,
17+
name: &str,
18+
router: Router,
19+
addr: net::SocketAddr,
20+
allow_failure: bool,
21+
) -> Result<()> {
22+
info!(addr = addr.to_string(), "starting {name} server");
23+
24+
let handle = Handle::new();
25+
arbiter.add_net_handle(handle.clone()).await;
26+
27+
let res = axum_server::Server::bind(addr)
28+
.acceptor(DefaultAcceptor::new())
29+
.handle(handle)
30+
.serve(router.into_make_service_with_connect_info::<net::SocketAddr>())
31+
.await;
32+
if res.is_err() && allow_failure {
33+
arbiter.shutdown().await;
34+
return Ok(());
35+
}
36+
res?;
37+
38+
Ok(())
39+
}
40+
41+
/// Start a plaintext server.
42+
///
43+
/// `name` is only used for observability purposes and should describe which module is starting the
44+
/// server.
45+
///
46+
/// `allow_failure` allows the server to fail silently.
47+
pub fn start_plain(
48+
tasks: &mut Tasks,
49+
name: &'static str,
50+
router: Router,
51+
addr: net::SocketAddr,
52+
allow_failure: bool,
53+
) -> Result<()> {
54+
let arbiter = tasks.arbiter();
55+
tasks
56+
.build_task()
57+
.name(&format!("{}::run_plain({name}, {addr})", module_path!()))
58+
.spawn(run_plain(arbiter, name, router, addr, allow_failure))?;
59+
Ok(())
60+
}
61+
62+
pub(crate) async fn run_unix(
63+
arbiter: Arbiter,
64+
name: &str,
65+
router: Router,
66+
addr: unix::net::SocketAddr,
67+
allow_failure: bool,
68+
) -> Result<()> {
69+
info!(addr = ?addr, "starting {name} server");
70+
71+
let handle = Handle::new();
72+
arbiter.add_unix_handle(handle.clone()).await;
73+
74+
let res = axum_server::Server::bind(addr)
75+
.acceptor(DefaultAcceptor::new())
76+
.handle(handle)
77+
.serve(router.into_make_service())
78+
.await;
79+
if res.is_err() && allow_failure {
80+
arbiter.shutdown().await;
81+
return Ok(());
82+
}
83+
res?;
84+
85+
Ok(())
86+
}
87+
88+
/// Start a Unix socket server.
89+
///
90+
/// `name` is only used for observability purposes and should describe which module is starting the
91+
/// server.
92+
///
93+
/// `allow_failure` allows the server to fail silently.
94+
pub fn start_unix(
95+
tasks: &mut Tasks,
96+
name: &'static str,
97+
router: Router,
98+
addr: unix::net::SocketAddr,
99+
allow_failure: bool,
100+
) -> Result<()> {
101+
let arbiter = tasks.arbiter();
102+
tasks
103+
.build_task()
104+
.name(&format!("{}::run_unix({name}, {addr:?})", module_path!()))
105+
.spawn(run_unix(arbiter, name, router, addr, allow_failure))?;
106+
Ok(())
107+
}
108+
109+
async fn run_tls(
110+
arbiter: Arbiter,
111+
name: &str,
112+
router: Router,
113+
addr: net::SocketAddr,
114+
config: RustlsConfig,
115+
) -> Result<()> {
116+
info!(addr = addr.to_string(), "starting {name} server");
117+
118+
let handle = Handle::new();
119+
arbiter.add_net_handle(handle.clone()).await;
120+
121+
axum_server::Server::bind(addr)
122+
.acceptor(RustlsAcceptor::new(config).acceptor(DefaultAcceptor::new()))
123+
.handle(handle)
124+
.serve(router.into_make_service_with_connect_info::<net::SocketAddr>())
125+
.await?;
126+
127+
Ok(())
128+
}
129+
130+
/// Start a TLS server.
131+
///
132+
/// `name` is only used for observability purposes and should describe which module is starting the
133+
/// server.
134+
pub fn start_tls(
135+
tasks: &mut Tasks,
136+
name: &'static str,
137+
router: Router,
138+
addr: net::SocketAddr,
139+
config: RustlsConfig,
140+
) -> Result<()> {
141+
let arbiter = tasks.arbiter();
142+
tasks
143+
.build_task()
144+
.name(&format!("{}::run_tls({name}, {addr})", module_path!()))
145+
.spawn(run_tls(arbiter, name, router, addr, config))?;
146+
Ok(())
147+
}

0 commit comments

Comments
 (0)