undercroft

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit e729c1e3cbd08596d0f85034a4dc4bf569c61556
parent cbea229f54fef4f5b491647d0a5567e107d7f0d5
Author: Daniel Barlow <dan@telent.net>
Date:   Tue, 21 Apr 2026 22:03:25 +0100

remove axum_server

Diffstat:
MCargo.lock | 73++++++++++++++++++++++---------------------------------------------------
MCargo.toml | 6+++++-
MMakefile | 20+++++++++++---------
Msrc/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); + } + }); + } }