Skip to content

Instantly share code, notes, and snippets.

@masakielastic
Created November 16, 2025 23:39
Show Gist options
  • Select an option

  • Save masakielastic/03177dd5b43ff84af96a4ba91e8cbd45 to your computer and use it in GitHub Desktop.

Select an option

Save masakielastic/03177dd5b43ff84af96a4ba91e8cbd45 to your computer and use it in GitHub Desktop.
warp v0.4 で HTTP/1/2 +TLS サーバー (Filter からサービスの作成)

warp v0.4 で HTTP/1/2 +TLS サーバー (Filter からサービスの作成)

構成

  • Cargo.tmol
  • src/main.rs

実行

cargo run を実行します。 ブラウザーや curl でアクセスします。

curl -kv https://localhost:3000

HTTP のバージョンを指定する場合

curl -kv --http1.1 https://localhost:3000
[package]
name = "warp-project"
version = "0.1.0"
edition = "2021"
[dependencies]
hyper = { version = "1", features = ["full"] }
tokio = { version = "1", features = ["full"] }
hyper-util = { version = "0.1", features = ["full"] }
warp = { version = "0.4", default-features = false }
tokio-rustls = "0.26"
rustls = "0.23"
rustls-pemfile = "2"
use std::{fs::File, io::BufReader, net::SocketAddr, sync::Arc};
use tokio::net::TcpListener;
use tokio_rustls::TlsAcceptor;
use warp::Filter;
use hyper_util::rt::{TokioExecutor, TokioIo};
use hyper_util::server::conn::auto;
use hyper_util::service::TowerToHyperService;
use rustls::ServerConfig;
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use rustls_pemfile::{certs, pkcs8_private_keys};
type Error = Box<dyn std::error::Error + Send + Sync>;
fn load_tls_config() -> Result<Arc<ServerConfig>, Error> {
let cert_file = &mut BufReader::new(File::open("localhost.pem")?);
let key_file = &mut BufReader::new(File::open("localhost-key.pem")?);
let cert_chain: Vec<CertificateDer<'static>> =
certs(cert_file).collect::<Result<Vec<_>, _>>()?;
let mut keys: Vec<PrivatePkcs8KeyDer<'static>> =
pkcs8_private_keys(key_file).collect::<Result<Vec<_>, _>>()?;
if keys.is_empty() {
return Err("no private key found in certs/key.pem".into());
}
let key_der: PrivateKeyDer<'static> = PrivateKeyDer::from(keys.remove(0));
let mut config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(cert_chain, key_der)?;
config.alpn_protocols = vec![
b"h2".to_vec(),
b"http/1.1".to_vec(),
];
Ok(Arc::new(config))
}
#[tokio::main]
async fn main() -> Result<(), Error> {
// rustls::crypto::aws_lc_rs::default_provider().install_default();
// ★ Reply を String にする
let routes = warp::path::end().map(|| {
"Hello from warp over TLS (HTTP/1 & HTTP/2 auto)!".to_string()
});
let warp_service = warp::service(routes);
let hyper_service = TowerToHyperService::new(warp_service);
let tls_config = load_tls_config()?;
let tls_acceptor = TlsAcceptor::from(tls_config);
let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
let listener = TcpListener::bind(addr).await?;
println!("Listening on https://{addr} (HTTP/1 & HTTP/2 via ALPN)");
loop {
let (tcp_stream, peer_addr) = listener.accept().await?;
let svc = hyper_service.clone();
let acceptor = tls_acceptor.clone();
tokio::spawn(async move {
println!("accepted connection from {peer_addr}");
let tls_stream = match acceptor.accept(tcp_stream).await {
Ok(s) => s,
Err(e) => {
eprintln!("TLS accept error: {e}");
return;
}
};
let io = TokioIo::new(tls_stream);
if let Err(err) = auto::Builder::new(TokioExecutor::new())
.serve_connection(io, svc)
.await
{
eprintln!("server connection error: {err}");
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment