summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/unit/fetch_test.ts36
-rw-r--r--ext/tls/lib.rs2
-rw-r--r--test_util/Cargo.toml2
-rw-r--r--test_util/src/lib.rs156
4 files changed, 180 insertions, 16 deletions
diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts
index a2bd1741b..bc61d67b5 100644
--- a/cli/tests/unit/fetch_test.ts
+++ b/cli/tests/unit/fetch_test.ts
@@ -1324,3 +1324,39 @@ unitTest(
}), TypeError);
},
);
+
+unitTest(
+ { permissions: { net: true, read: true } },
+ async function fetchSupportsHttp1Only() {
+ const caCert = await Deno.readTextFile("cli/tests/testdata/tls/RootCA.pem");
+ const client = Deno.createHttpClient({ caCerts: [caCert] });
+ const res = await fetch("https://localhost:5546/http_version", { client });
+ assert(res.ok);
+ assertEquals(await res.text(), "HTTP/1.1");
+ client.close();
+ },
+);
+
+unitTest(
+ { permissions: { net: true, read: true } },
+ async function fetchSupportsHttp2() {
+ const caCert = await Deno.readTextFile("cli/tests/testdata/tls/RootCA.pem");
+ const client = Deno.createHttpClient({ caCerts: [caCert] });
+ const res = await fetch("https://localhost:5547/http_version", { client });
+ assert(res.ok);
+ assertEquals(await res.text(), "HTTP/2.0");
+ client.close();
+ },
+);
+
+unitTest(
+ { permissions: { net: true, read: true } },
+ async function fetchPrefersHttp2() {
+ const caCert = await Deno.readTextFile("cli/tests/testdata/tls/RootCA.pem");
+ const client = Deno.createHttpClient({ caCerts: [caCert] });
+ const res = await fetch("https://localhost:5545/http_version", { client });
+ assert(res.ok);
+ assertEquals(await res.text(), "HTTP/2.0");
+ client.close();
+ },
+);
diff --git a/ext/tls/lib.rs b/ext/tls/lib.rs
index 076ef59fb..fb4fac85b 100644
--- a/ext/tls/lib.rs
+++ b/ext/tls/lib.rs
@@ -238,6 +238,8 @@ pub fn create_http_client(
.expect("invalid client key or certificate");
}
+ tls_config.alpn_protocols = vec!["h2".into(), "http/1.1".into()];
+
let mut headers = HeaderMap::new();
headers.insert(USER_AGENT, user_agent.parse().unwrap());
let mut builder = Client::builder()
diff --git a/test_util/Cargo.toml b/test_util/Cargo.toml
index 92523ac81..e93793392 100644
--- a/test_util/Cargo.toml
+++ b/test_util/Cargo.toml
@@ -17,7 +17,7 @@ async-stream = "0.3.2"
atty = "0.2.14"
base64 = "0.13.0"
futures = "0.3.16"
-hyper = { version = "0.14.12", features = ["server", "http1", "runtime"] }
+hyper = { version = "0.14.12", features = ["server", "http1", "http2", "runtime"] }
lazy_static = "1.4.0"
os_pipe = "0.9.2"
regex = "1.5.4"
diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs
index f20601340..52924ac90 100644
--- a/test_util/src/lib.rs
+++ b/test_util/src/lib.rs
@@ -61,6 +61,8 @@ const TLS_CLIENT_AUTH_PORT: u16 = 4552;
const BASIC_AUTH_REDIRECT_PORT: u16 = 4554;
const TLS_PORT: u16 = 4557;
const HTTPS_PORT: u16 = 5545;
+const H1_ONLY_PORT: u16 = 5546;
+const H2_ONLY_PORT: u16 = 5547;
const HTTPS_CLIENT_AUTH_PORT: u16 = 5552;
const WS_PORT: u16 = 4242;
const WSS_PORT: u16 = 4243;
@@ -290,10 +292,22 @@ async fn run_ws_close_server(addr: &SocketAddr) {
}
}
+enum SupportedHttpVersions {
+ All,
+ Http1Only,
+ Http2Only,
+}
+impl Default for SupportedHttpVersions {
+ fn default() -> SupportedHttpVersions {
+ SupportedHttpVersions::All
+ }
+}
+
async fn get_tls_config(
cert: &str,
key: &str,
ca: &str,
+ http_versions: SupportedHttpVersions,
) -> io::Result<Arc<rustls::ServerConfig>> {
let cert_path = testdata_path().join(cert);
let key_path = testdata_path().join(key);
@@ -336,6 +350,15 @@ async fn get_tls_config(
let allow_client_auth =
rustls::AllowAnyAnonymousOrAuthenticatedClient::new(root_cert_store);
let mut config = rustls::ServerConfig::new(allow_client_auth);
+ match http_versions {
+ SupportedHttpVersions::All => {
+ config.set_protocols(&["h2".into(), "http/1.1".into()]);
+ }
+ SupportedHttpVersions::Http1Only => {}
+ SupportedHttpVersions::Http2Only => {
+ config.set_protocols(&["h2".into()]);
+ }
+ }
config
.set_single_cert(cert, key)
.map_err(|e| {
@@ -354,9 +377,10 @@ async fn run_wss_server(addr: &SocketAddr) {
let key_file = "tls/localhost.key";
let ca_cert_file = "tls/RootCA.pem";
- let tls_config = get_tls_config(cert_file, key_file, ca_cert_file)
- .await
- .unwrap();
+ let tls_config =
+ get_tls_config(cert_file, key_file, ca_cert_file, Default::default())
+ .await
+ .unwrap();
let tls_acceptor = TlsAcceptor::from(tls_config);
let listener = TcpListener::bind(addr).await.unwrap();
println!("ready: wss"); // Eye catcher for HttpServerCount
@@ -396,9 +420,10 @@ async fn run_tls_client_auth_server() {
let cert_file = "tls/localhost.crt";
let key_file = "tls/localhost.key";
let ca_cert_file = "tls/RootCA.pem";
- let tls_config = get_tls_config(cert_file, key_file, ca_cert_file)
- .await
- .unwrap();
+ let tls_config =
+ get_tls_config(cert_file, key_file, ca_cert_file, Default::default())
+ .await
+ .unwrap();
let tls_acceptor = TlsAcceptor::from(tls_config);
// Listen on ALL addresses that localhost can resolves to.
@@ -459,9 +484,10 @@ async fn run_tls_server() {
let cert_file = "tls/localhost.crt";
let key_file = "tls/localhost.key";
let ca_cert_file = "tls/RootCA.pem";
- let tls_config = get_tls_config(cert_file, key_file, ca_cert_file)
- .await
- .unwrap();
+ let tls_config =
+ get_tls_config(cert_file, key_file, ca_cert_file, Default::default())
+ .await
+ .unwrap();
let tls_acceptor = TlsAcceptor::from(tls_config);
// Listen on ALL addresses that localhost can resolves to.
@@ -819,6 +845,10 @@ async fn main_server(req: Request<Body>) -> hyper::Result<Response<Body>> {
Ok(Response::new(Body::empty()))
}
}
+ (_, "/http_version") => {
+ let version = format!("{:?}", req.version());
+ Ok(Response::new(version.into()))
+ }
_ => {
let mut file_path = testdata_path();
file_path.push(&req.uri().path()[1..]);
@@ -959,9 +989,99 @@ async fn wrap_main_https_server() {
let cert_file = "tls/localhost.crt";
let key_file = "tls/localhost.key";
let ca_cert_file = "tls/RootCA.pem";
- let tls_config = get_tls_config(cert_file, key_file, ca_cert_file)
- .await
- .unwrap();
+ let tls_config =
+ get_tls_config(cert_file, key_file, ca_cert_file, Default::default())
+ .await
+ .unwrap();
+ loop {
+ let tcp = TcpListener::bind(&main_server_https_addr)
+ .await
+ .expect("Cannot bind TCP");
+ println!("ready: https"); // Eye catcher for HttpServerCount
+ let tls_acceptor = TlsAcceptor::from(tls_config.clone());
+ // Prepare a long-running future stream to accept and serve cients.
+ let incoming_tls_stream = async_stream::stream! {
+ loop {
+ let (socket, _) = tcp.accept().await?;
+ let stream = tls_acceptor.accept(socket);
+ yield stream.await;
+ }
+ }
+ .boxed();
+
+ let main_server_https_svc = make_service_fn(|_| async {
+ Ok::<_, Infallible>(service_fn(main_server))
+ });
+ let main_server_https = Server::builder(HyperAcceptor {
+ acceptor: incoming_tls_stream,
+ })
+ .serve(main_server_https_svc);
+
+ //continue to prevent TLS error stopping the server
+ if main_server_https.await.is_err() {
+ continue;
+ }
+ }
+}
+
+async fn wrap_https_h1_only_server() {
+ let main_server_https_addr = SocketAddr::from(([127, 0, 0, 1], H1_ONLY_PORT));
+ let cert_file = "tls/localhost.crt";
+ let key_file = "tls/localhost.key";
+ let ca_cert_file = "tls/RootCA.pem";
+ let tls_config = get_tls_config(
+ cert_file,
+ key_file,
+ ca_cert_file,
+ SupportedHttpVersions::Http1Only,
+ )
+ .await
+ .unwrap();
+ loop {
+ let tcp = TcpListener::bind(&main_server_https_addr)
+ .await
+ .expect("Cannot bind TCP");
+ println!("ready: https"); // Eye catcher for HttpServerCount
+ let tls_acceptor = TlsAcceptor::from(tls_config.clone());
+ // Prepare a long-running future stream to accept and serve cients.
+ let incoming_tls_stream = async_stream::stream! {
+ loop {
+ let (socket, _) = tcp.accept().await?;
+ let stream = tls_acceptor.accept(socket);
+ yield stream.await;
+ }
+ }
+ .boxed();
+
+ let main_server_https_svc = make_service_fn(|_| async {
+ Ok::<_, Infallible>(service_fn(main_server))
+ });
+ let main_server_https = Server::builder(HyperAcceptor {
+ acceptor: incoming_tls_stream,
+ })
+ .http1_only(true)
+ .serve(main_server_https_svc);
+
+ //continue to prevent TLS error stopping the server
+ if main_server_https.await.is_err() {
+ continue;
+ }
+ }
+}
+
+async fn wrap_https_h2_only_server() {
+ let main_server_https_addr = SocketAddr::from(([127, 0, 0, 1], H2_ONLY_PORT));
+ let cert_file = "tls/localhost.crt";
+ let key_file = "tls/localhost.key";
+ let ca_cert_file = "tls/RootCA.pem";
+ let tls_config = get_tls_config(
+ cert_file,
+ key_file,
+ ca_cert_file,
+ SupportedHttpVersions::Http2Only,
+ )
+ .await
+ .unwrap();
loop {
let tcp = TcpListener::bind(&main_server_https_addr)
.await
@@ -984,6 +1104,7 @@ async fn wrap_main_https_server() {
let main_server_https = Server::builder(HyperAcceptor {
acceptor: incoming_tls_stream,
})
+ .http2_only(true)
.serve(main_server_https_svc);
//continue to prevent TLS error stopping the server
@@ -999,9 +1120,10 @@ async fn wrap_client_auth_https_server() {
let cert_file = "tls/localhost.crt";
let key_file = "tls/localhost.key";
let ca_cert_file = "tls/RootCA.pem";
- let tls_config = get_tls_config(cert_file, key_file, ca_cert_file)
- .await
- .unwrap();
+ let tls_config =
+ get_tls_config(cert_file, key_file, ca_cert_file, Default::default())
+ .await
+ .unwrap();
loop {
let tcp = TcpListener::bind(&main_server_https_addr)
.await
@@ -1078,6 +1200,8 @@ pub async fn run_all_servers() {
let client_auth_server_https_fut = wrap_client_auth_https_server();
let main_server_fut = wrap_main_server();
let main_server_https_fut = wrap_main_https_server();
+ let h1_only_server_fut = wrap_https_h1_only_server();
+ let h2_only_server_fut = wrap_https_h2_only_server();
let mut server_fut = async {
futures::join!(
@@ -1096,6 +1220,8 @@ pub async fn run_all_servers() {
main_server_fut,
main_server_https_fut,
client_auth_server_https_fut,
+ h1_only_server_fut,
+ h2_only_server_fut
)
}
.boxed();