commit e729c1e3cbd08596d0f85034a4dc4bf569c61556
parent cbea229f54fef4f5b491647d0a5567e107d7f0d5
Author: Daniel Barlow <dan@telent.net>
Date: Tue, 21 Apr 2026 22:03:25 +0100
remove axum_server
Diffstat:
| M | Cargo.lock | | | 73 | ++++++++++++++++++++++--------------------------------------------------- |
| M | Cargo.toml | | | 6 | +++++- |
| M | Makefile | | | 20 | +++++++++++--------- |
| M | src/main.rs | | | 95 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- |
4 files changed, 121 insertions(+), 73 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -53,24 +53,12 @@ dependencies = [
]
[[package]]
-name = "arc-swap"
-version = "1.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
-
-[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
-name = "autocfg"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
-
-[[package]]
name = "aws-lc-rs"
version = "1.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -145,28 +133,6 @@ dependencies = [
]
[[package]]
-name = "axum-server"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1df331683d982a0b9492b38127151e6453639cd34926eb9c07d4cd8c6d22bfc"
-dependencies = [
- "arc-swap",
- "bytes",
- "either",
- "fs-err",
- "http",
- "http-body",
- "hyper",
- "hyper-util",
- "pin-project-lite",
- "rustls",
- "rustls-pki-types",
- "tokio",
- "tokio-rustls",
- "tower-service",
-]
-
-[[package]]
name = "bitflags"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -258,12 +224,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
[[package]]
-name = "either"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
-
-[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -291,16 +251,6 @@ dependencies = [
]
[[package]]
-name = "fs-err"
-version = "3.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0"
-dependencies = [
- "autocfg",
- "tokio",
-]
-
-[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -463,6 +413,7 @@ dependencies = [
"pin-project-lite",
"smallvec",
"tokio",
+ "want",
]
[[package]]
@@ -663,6 +614,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
dependencies = [
"aws-lc-rs",
+ "log",
"once_cell",
"rustls-pki-types",
"rustls-webpki",
@@ -794,10 +746,14 @@ name = "slops"
version = "0.1.0"
dependencies = [
"axum",
- "axum-server",
"clap",
"clap_derive",
+ "hyper",
+ "hyper-util",
+ "log",
"tokio",
+ "tokio-rustls",
+ "tower-service",
]
[[package]]
@@ -945,6 +901,12 @@ dependencies = [
]
[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -963,6 +925,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -5,7 +5,11 @@ edition = "2024"
[dependencies]
axum = "0.8.9"
-axum-server = {version = "0.8.0", features = ["tls-rustls-no-provider", "tls-rustls"] }
+hyper = { version = "1.0.0", features = ["full"] }
+hyper-util = { version = "0.1", features = ["http2"] }
clap = {version = "4.6.0", features = ["derive"] }
clap_derive = "4.6.0"
tokio = { version = "1.52.0", features = ["full"] }
+tokio-rustls = "0.26"
+tower-service = "0.3.2"
+log = "0.4.29"
diff --git a/Makefile b/Makefile
@@ -1,7 +1,8 @@
SERVERNAME=$(shell hostname)
+SERVERPORT=3002
default: certificates
-certificates: certs/ca.crt certs/server.crt
+certificates: certs/ca.crt certs/server.crt certs/client.crt
private/ca.key:
mkdir -p private
@@ -11,15 +12,16 @@ certs/ca.crt: private/ca.key
mkdir -p certs
openssl req -addext basicConstraints=critical,CA:TRUE,pathlen:0 --x509 -new -nodes -key private/ca.key -sha256 -days 3650 -out certs/ca.crt
-certs/server.csr:
+certs/%.csr:
mkdir -p certs
- openssl req -newkey rsa:2048 -addext "subjectAltName = DNS:$(SERVERNAME).lan,DNS:$(SERVERNAME),DNS:$(SERVERNAME).telent.net" -nodes -keyout private/server.key --out certs/server.csr
+ openssl req -newkey rsa:2048 -addext "subjectAltName = DNS:$*.lan,DNS:$*,DNS:$*.telent.net" -nodes -keyout private/$*.key --out $@
-# certs/client.csr:
-# openssl req -newkey rsa:2048 -addext "subjectAltName = DNS:$(SERVERNAME).lan,DNS:$(SERVERNAME),DNS:$(SERVERNAME).telent.net" -nodes -keyout private/server.key --out certs/server.csr
-certs/server.crt: private/ca.key certs/server.csr
- openssl x509 -req -in certs/server.csr -days 365 -CA certs/ca.crt -CAkey private/ca.key -CAcreateserial -copy_extensions copyall -out certs/server.crt
+certs/%.crt: certs/%.csr private/ca.key
+ openssl x509 -req -in $< -days 365 -CA certs/ca.crt -CAkey private/ca.key -CAcreateserial -copy_extensions copyall -out $@
-run:
- cargo run -- --ca-certificate certs/ca.crt --certificate certs/server.crt --key private/server.key --port 3002 secrets.yml.age
+run: certificates
+ cargo run -- --ca-certificate certs/ca.crt --certificate certs/server.crt --key private/server.key --port $(SERVERPORT) secrets.yml.age
+
+ping:
+ curl --connect-to ::127.0.0.1:3002 --cert certs/client.crt --key private/client.key --cacert certs/ca.crt -v https://${SERVERNAME}:$(SERVERPORT)
diff --git a/src/main.rs b/src/main.rs
@@ -1,8 +1,20 @@
-use axum::{routing::get, Router};
+
+use axum::{extract::Request, routing::get, Router};
+use std::sync::Arc;
use std::net::SocketAddr;
-use axum_server::tls_rustls::RustlsConfig;
-use clap::{Parser, Subcommand};
+use hyper::body::Incoming;
+use hyper_util::rt::{TokioExecutor, TokioIo};
+use tokio::net::TcpListener;
+use tokio_rustls::{
+ rustls::pki_types::{pem::PemObject, CertificateDer, PrivateKeyDer},
+ rustls::ServerConfig,
+ TlsAcceptor,
+};
+use tower_service::Service;
+
+use clap::Parser;
+use log::{error,warn};
#[derive(Parser)]
#[command(name = "slops")]
@@ -32,17 +44,76 @@ async fn main() {
let port = cli.port.unwrap_or(3000);
println!("port = {:?}", port);
- let app = Router::new().route("/", get(|| async { "Hello, world!" }));
+ // let store = load_store_from_pem(cli.ca_certificate).unwrap();
+ // let client_cert_verifier = Arc::new(AllowAnyAnonymousOrAuthenticatedClient::new(store));
+
+ let private_key = PrivateKeyDer::from_pem_file(cli.key).unwrap();
+
+ let certs = CertificateDer::pem_file_iter(cli.certificate)
+ .unwrap()
+ .map(|cert| cert.unwrap())
+ .collect();
- let tls_config =
- RustlsConfig::from_pem_file(cli.certificate, cli.key)
- .await
- .unwrap();
+ let mut c =
+ ServerConfig::builder()
+ // .with_safe_defaults()
+ .with_no_client_auth()
+// .with_client_cert_verifier(client_cert_verifier)
+ .with_single_cert(certs, private_key)
+ .expect("bad certificate/key");
+
+ c.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+
+ let tls_config = Arc::new(c);
+ let tls_acceptor = TlsAcceptor::from(tls_config);
let addr = SocketAddr::from(([127, 0, 0, 1], port));
+ let tcp_listener = TcpListener::bind(addr).await.unwrap();
+
println!("listening on {}", addr);
- axum_server::bind_rustls(addr, tls_config)
- .serve(app.into_make_service())
- .await
- .unwrap();
+
+ let app = Router::new().route("/", get(|| async { "Hello, world!" }));
+
+ loop {
+ let tower_service = app.clone();
+ let tls_acceptor = tls_acceptor.clone();
+
+ // Wait for new tcp connection
+ let (cnx, addr) = tcp_listener.accept().await.unwrap();
+
+ tokio::spawn(async move {
+ // Wait for tls handshake to happen
+ let Ok(stream) = tls_acceptor.accept(cnx).await else {
+ error!("error during tls handshake connection from {}", addr);
+ return;
+ };
+
+ // Hyper has its own `AsyncRead` and `AsyncWrite` traits
+ // and doesn't use tokio. `TokioIo` converts between
+ // them.
+ let stream = TokioIo::new(stream);
+
+ // Hyper also has its own `Service` trait and doesn't use
+ // tower. We can use `hyper::service::service_fn` to
+ // create a hyper `Service` that calls our app through
+ // `tower::Service::call`.
+ let hyper_service = hyper::service::service_fn(move |request: Request<Incoming>| {
+
+ // We have to clone `tower_service` because hyper's
+ // `Service` uses `&self` whereas
+ // tower's `Service` requires `&mut self`.
+ //
+ // We don't need to call `poll_ready` since `Router`
+ // is always ready.
+ tower_service.clone().call(request)
+ });
+
+ let ret = hyper_util::server::conn::auto::Builder::new(TokioExecutor::new())
+ .serve_connection_with_upgrades(stream, hyper_service)
+ .await;
+ if let Err(err) = ret {
+ warn!("error serving connection from {}: {}", addr, err);
+ }
+ });
+ }
}