#[cfg(all(feature = "tls", feature = "server", feature = "client"))]
mod tests {
use oxitls::rcgen_bridge::generate_self_signed_ed25519;
use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
fn to_pem(ck: &oxitls::rcgen_bridge::CertifiedKey) -> (Vec<u8>, Vec<u8>) {
let cert_pem = ck.cert_pem.as_bytes().to_vec();
let key_pem = ck.key_pem().into_bytes();
(cert_pem, key_pem)
}
#[tokio::test]
async fn test_with_alpn_h2_roundtrip() {
let ck = generate_self_signed_ed25519(&["localhost"]).expect("cert gen");
let (cert_pem, key_pem) = to_pem(&ck);
let router = oxihttp::Router::new().get("/h2test", |_req| async {
oxihttp::response::text_response("h2-ok")
});
let (addr, _handle) = oxihttp::Server::bind("127.0.0.1:0")
.with_alpn(["h2", "http/1.1"])
.with_tls_from_pem(&cert_pem, &key_pem)
.expect("with_tls_from_pem")
.serve_with_addr(router)
.await
.expect("serve_with_addr");
let client = oxihttp::Client::builder()
.with_trusted_cert_der(ck.cert_der.clone())
.with_alpn(&["h2", "http/1.1"])
.build_https()
.expect("build_https");
let url = format!("https://localhost:{}/h2test", addr.port());
let resp = client.get(&url).expect("GET").send().await.expect("send");
assert_eq!(resp.status(), oxihttp::StatusCode::OK);
let version = resp.version();
let body = resp.body_text().await.expect("body_text");
assert_eq!(body, "h2-ok");
assert_eq!(
version,
http::Version::HTTP_2,
"expected HTTP/2 via ALPN negotiation, got {version:?}"
);
}
#[tokio::test]
async fn test_with_alpn_from_der_h2_roundtrip() {
let ck = generate_self_signed_ed25519(&["localhost"]).expect("cert gen");
let certs = vec![CertificateDer::from(ck.cert_der.clone())];
let key = PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(ck.pkcs8_der.clone()));
let router = oxihttp::Router::new().get("/dertest", |_req| async {
oxihttp::response::text_response("der-ok")
});
let (addr, _handle) = oxihttp::Server::bind("127.0.0.1:0")
.with_alpn(["h2", "http/1.1"])
.with_tls_from_der(certs, key)
.expect("with_tls_from_der")
.serve_with_addr(router)
.await
.expect("serve_with_addr");
let client = oxihttp::Client::builder()
.with_trusted_cert_der(ck.cert_der.clone())
.with_alpn(&["h2", "http/1.1"])
.build_https()
.expect("build_https");
let url = format!("https://localhost:{}/dertest", addr.port());
let resp = client.get(&url).expect("GET").send().await.expect("send");
assert_eq!(resp.status(), oxihttp::StatusCode::OK);
let version = resp.version();
let body = resp.body_text().await.expect("body_text");
assert_eq!(body, "der-ok");
assert_eq!(
version,
http::Version::HTTP_2,
"expected HTTP/2 via ALPN negotiation, got {version:?}"
);
}
#[tokio::test]
async fn test_with_alpn_http1_only() {
let ck = generate_self_signed_ed25519(&["localhost"]).expect("cert gen");
let (cert_pem, key_pem) = to_pem(&ck);
let router = oxihttp::Router::new().get("/h1test", |_req| async {
oxihttp::response::text_response("h1-ok")
});
let (addr, _handle) = oxihttp::Server::bind("127.0.0.1:0")
.with_alpn(["http/1.1"])
.with_tls_from_pem(&cert_pem, &key_pem)
.expect("with_tls_from_pem")
.serve_with_addr(router)
.await
.expect("serve_with_addr");
let client = oxihttp::Client::builder()
.with_trusted_cert_der(ck.cert_der.clone())
.with_alpn(&["h2", "http/1.1"])
.build_https()
.expect("build_https");
let url = format!("https://localhost:{}/h1test", addr.port());
let resp = client.get(&url).expect("GET").send().await.expect("send");
assert_eq!(resp.status(), oxihttp::StatusCode::OK);
let version = resp.version();
let body = resp.body_text().await.expect("body_text");
assert_eq!(body, "h1-ok");
assert_eq!(
version,
http::Version::HTTP_11,
"expected HTTP/1.1 when server ALPN only includes http/1.1, got {version:?}"
);
}
}