diff --git a/Cargo.lock b/Cargo.lock index 1b01969af5e9..105805136d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9326,7 +9326,9 @@ dependencies = [ "anyhow", "futures", "futures-util", - "hyper 0.14.30", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "pico-args", "serde", "serde_json", diff --git a/crates/tauri-driver/Cargo.toml b/crates/tauri-driver/Cargo.toml index b5cb0009a974..fe9d153538b4 100644 --- a/crates/tauri-driver/Cargo.toml +++ b/crates/tauri-driver/Cargo.toml @@ -13,16 +13,11 @@ rust-version = "1.77.2" [dependencies] anyhow = "1" -hyper = { version = "0.14", features = [ - "client", - "http1", - "runtime", - "server", - "stream", - "tcp", -] } futures = "0.3" futures-util = "0.3" +http-body-util = "0.1.2" +hyper = { version = "1", features = ["client", "http1", "server"] } +hyper-util = { version = "0.1", features = ["client", "client-legacy", "http1", "server", "tokio"] } pico-args = "0.5" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/crates/tauri-driver/src/server.rs b/crates/tauri-driver/src/server.rs index 93366b2994d9..34304f035af6 100644 --- a/crates/tauri-driver/src/server.rs +++ b/crates/tauri-driver/src/server.rs @@ -5,17 +5,25 @@ use crate::cli::Args; use anyhow::Error; use futures_util::TryFutureExt; -use hyper::header::CONTENT_LENGTH; -use hyper::http::uri::Authority; -use hyper::service::{make_service_fn, service_fn}; -use hyper::{Body, Client, Method, Request, Response, Server}; +use http_body_util::{BodyExt, Full}; +use hyper::{ + body::{Bytes, Incoming}, + header::CONTENT_LENGTH, + http::uri::Authority, + service::service_fn, + Method, Request, Response, +}; +use hyper_util::{ + client::legacy::Client, + rt::{TokioExecutor, TokioIo}, + server::conn::auto, +}; use serde::Deserialize; use serde_json::{json, Map, Value}; use std::convert::Infallible; use std::path::PathBuf; use std::process::Child; - -type HttpClient = Client; +use tokio::net::TcpListener; const TAURI_OPTIONS: &str = "tauri:options"; @@ -55,16 +63,16 @@ impl TauriOptions { } async fn handle( - client: HttpClient, - mut req: Request, + client: Client, + mut req: Request, args: Args, -) -> Result, Error> { +) -> Result>, Error> { // manipulate a new session to convert options to the native driver format if let (&Method::POST, "/session") = (req.method(), req.uri().path()) { let (mut parts, body) = req.into_parts(); // get the body from the future stream and parse it as json - let body = hyper::body::to_bytes(body).await?; + let body = body.collect().await?.to_bytes().to_vec(); let json: Value = serde_json::from_slice(&body)?; // manipulate the json to convert from tauri option to native driver options @@ -74,7 +82,7 @@ async fn handle( let bytes = serde_json::to_vec(&json)?; parts.headers.insert(CONTENT_LENGTH, bytes.len().into()); - req = Request::from_parts(parts, bytes.into()); + req = Request::from_parts(parts, bytes); } client @@ -84,7 +92,10 @@ async fn handle( } /// Transform the request to a request for the native webdriver server. -fn forward_to_native_driver(mut req: Request, args: Args) -> Result, Error> { +fn forward_to_native_driver( + mut req: Request, + args: Args, +) -> Result, Error> { let host: Authority = { let headers = req.headers_mut(); headers.remove("host").expect("hyper request has host") @@ -171,30 +182,36 @@ pub async fn run(args: Args, mut _driver: Child) -> Result<(), Error> { let address = std::net::SocketAddr::from(([127, 0, 0, 1], args.port)); // the client we use to proxy requests to the native webdriver - let client = Client::builder() + let client = Client::builder(TokioExecutor::new()) .http1_preserve_header_case(true) .http1_title_case_headers(true) .retry_canceled_requests(false) .build_http(); - // pass a copy of the client to the http request handler - let service = make_service_fn(move |_| { - let client = client.clone(); - let args = args.clone(); - async move { - Ok::<_, Infallible>(service_fn(move |request| { - handle(client.clone(), request, args.clone()) - })) - } - }); - // set up a http1 server that uses the service we just created - Server::bind(&address) - .http1_title_case_headers(true) - .http1_preserve_header_case(true) - .http1_only(true) - .serve(service) - .await?; + let srv = async move { + let listener = TcpListener::bind(address).await?; + loop { + let (stream, _) = listener.accept().await?; + let io = TokioIo::new(stream); + + tokio::task::spawn(async move { + if let Err(err) = auto::Builder::new(TokioExecutor::new()) + .http1() + .title_case_headers(true) + .preserve_header_case(true) + .serve_connection( + io, + service_fn(|request| handle(client.clone(), request, args.clone())), + ) + .await + { + println!("Error serving connection: {:?}", err); + } + }); + } + }; + srv.await?; #[cfg(unix)] {