use super::{http::Server, *}; use dever_runtime::{ http, task::{Limits, Runtime}, tls, }; use std::{ net::{TcpListener, TcpStream}, time::{Duration, Instant}, }; #[test] fn automatic_api_accepts_http2_tls_and_validates_before_listening() { let directory = Directory::new(); let project = Project::load(&fixture().with_file_name("http-application")).unwrap(); let program = project.check().unwrap(); let binary = build::build(&program, &project.sources, "main", &directory.0.join("api")).unwrap(); let certificate = Path::new(env!("CARGO_MANIFEST_DIR")) .join("../test/dever-tests/fixtures/tls") .canonicalize() .unwrap(); std::fs::create_dir(directory.0.join("config")).unwrap(); for http2 in [false, true] { let socket = TcpListener::bind("127.0.0.1:0").unwrap(); let port = socket.local_addr().unwrap().port(); drop(socket); let mut settings = serde_json::json!({"http":{"host":"127.0.0.1","port":port,"tls":{"certificate":certificate.join("server.pem"),"key":certificate.join("server-key.pem")},"limits":{"http2":if http2 { serde_json::json!({}) } else { serde_json::Value::Null }}},"sites":{"public":{"path":"","hosts":["localhost"]}}}); let path = directory.0.join("config/setting.json"); std::fs::write(&path, settings.to_string()).unwrap(); let mut server = Server(Command::new(&binary).spawn().unwrap()); let deadline = Instant::now() + Duration::from_secs(5); while TcpStream::connect(("127.0.0.1", port)).is_err() { assert!(server.0.try_wait().unwrap().is_none()); assert!(Instant::now() < deadline); std::thread::sleep(Duration::from_millis(10)); } Runtime::new(Limits::default()).unwrap().run(async |scope| { let limits = http::Limits { http2:http2.then(Default::default),..Default::default() }; let root = tls::client(&std::fs::read(certificate.join("root.pem")).unwrap()).unwrap(); let client = http::client(&format!("https://localhost:{port}"),&root,&limits,&Default::default(),scope).unwrap(); for _ in 0..2 { let response = client.request(http::Request { method:"GET".into(),target:"/demo/greeting/greet?name=Dever".into(),headers:vec![],body:dever_runtime::Bytes::new() }).await.unwrap(); assert_eq!(response.status,200); assert_eq!(serde_json::from_slice::(&response.body).unwrap()["data"],"Hello, Dever"); } client.close().await.unwrap(); }).unwrap(); drop(server); settings["http"]["tls"]["key"] = certificate .join("root.pem") .to_string_lossy() .into_owned() .into(); std::fs::write(&path, settings.to_string()).unwrap(); let failed = Command::new(&binary).output().unwrap(); assert!(!failed.status.success()); assert!(String::from_utf8_lossy(&failed.stderr).contains("TLS")); assert!(TcpListener::bind(("127.0.0.1", port)).is_ok()); } }