Last active
June 13, 2025 01:50
-
-
Save masakielastic/35e0280c29db522652682eb6244ab798 to your computer and use it in GitHub Desktop.
Axum v0.8.4 HTTPS・HTTP/2 サーバー
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "axum_project" | |
version = "0.1.0" | |
edition = "2024" | |
[dependencies] | |
axum = { version = "0.8", features = ["http2"] } | |
tokio = { version = "1", features = ["full"] } | |
hyper = { version = "1", features = ["http1", "http2", "server"] } | |
hyper-util = { version = "0.1", features = ["tokio"] } | |
tokio-rustls = "0.25" | |
rustls = "0.22" | |
rustls-pemfile = "2" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use axum::{routing::get, Router}; | |
use hyper_util::server::conn::auto::Builder as AutoBuilder; | |
use hyper_util::{rt::tokio::{TokioIo, TokioExecutor}, service::TowerToHyperService}; | |
use rustls::{ | |
pki_types::{CertificateDer, PrivateKeyDer}, | |
ServerConfig, | |
}; | |
use rustls_pemfile::{certs, pkcs8_private_keys}; | |
use std::{ | |
fs::File, | |
io::BufReader, | |
net::SocketAddr, | |
sync::Arc, | |
}; | |
use tokio::{net::TcpListener, task}; | |
use tokio_rustls::TlsAcceptor; | |
#[tokio::main] | |
async fn main() { | |
// TLS証明書と鍵の読み込み | |
let cert_file = &mut BufReader::new(File::open("cert.pem").unwrap()); | |
let cert_chain = certs(cert_file) | |
.filter_map(Result::ok) | |
.collect::<Vec<CertificateDer>>(); | |
let key_file = &mut BufReader::new(File::open("key.pem").unwrap()); | |
let keys = pkcs8_private_keys(key_file) | |
.filter_map(Result::ok) | |
.map(PrivateKeyDer::from) | |
.collect::<Vec<PrivateKeyDer>>(); | |
let key = keys | |
.into_iter() | |
.next() | |
.expect("No private key found in key.pem (PKCS#8 format expected)"); | |
// TLS 設定 | |
let mut tls_config = ServerConfig::builder() | |
.with_no_client_auth() | |
.with_single_cert(cert_chain, key) | |
.expect("TLS config error"); | |
tls_config.alpn_protocols = vec![ | |
b"h2".to_vec(), // HTTP/2 | |
b"http/1.1".to_vec(), // fallback | |
]; | |
let tls_acceptor = TlsAcceptor::from(Arc::new(tls_config)); | |
// アプリ作成 | |
let app = Router::new().route("/", get(handler)); | |
let service = TowerToHyperService::new(app.into_service()); | |
// サーバー起動 | |
let addr = SocketAddr::from(([127, 0, 0, 1], 8443)); | |
let listener = TcpListener::bind(addr).await.unwrap(); | |
println!("🚀 Listening on https://{addr}"); | |
loop { | |
let (tcp, _) = listener.accept().await.unwrap(); | |
let tls_acceptor = tls_acceptor.clone(); | |
let service = service.clone(); | |
task::spawn(async move { | |
match tls_acceptor.accept(tcp).await { | |
Ok(tls_stream) => { | |
let io = TokioIo::new(tls_stream); | |
let executor = TokioExecutor::new(); | |
if let Err(err) = AutoBuilder::new(executor) | |
.serve_connection(io, service) | |
.await | |
{ | |
eprintln!("connection error: {err:?}"); | |
} | |
} | |
Err(err) => { | |
eprintln!("TLS error: {err:?}"); | |
} | |
} | |
}); | |
} | |
} | |
async fn handler() -> &'static str { | |
"Hello, HTTPS with Axum + Hyper!" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment