mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
chore(deps/driver): update hyper to version 1 (#12240)
Co-authored-by: Fabian-Lars <github@fabianlars.de>
This commit is contained in:
5
.changes/tauri-driver-hyper-v1.md
Normal file
5
.changes/tauri-driver-hyper-v1.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
tauri-driver: 'patch:enhance'
|
||||
---
|
||||
|
||||
Updated `hyper` to version 1. This won't affect the user facing API.
|
||||
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -13,16 +13,17 @@ 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"
|
||||
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"
|
||||
|
||||
@@ -5,17 +5,24 @@
|
||||
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::{connect::HttpConnector, 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<hyper::client::HttpConnector>;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
const TAURI_OPTIONS: &str = "tauri:options";
|
||||
|
||||
@@ -55,36 +62,46 @@ impl TauriOptions {
|
||||
}
|
||||
|
||||
async fn handle(
|
||||
client: HttpClient,
|
||||
mut req: Request<Body>,
|
||||
client: Client<HttpConnector, Full<Bytes>>,
|
||||
req: Request<Incoming>,
|
||||
args: Args,
|
||||
) -> Result<Response<Body>, Error> {
|
||||
) -> Result<Response<Incoming>, 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();
|
||||
let new_req: Request<Full<Bytes>> =
|
||||
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 json: Value = serde_json::from_slice(&body)?;
|
||||
// get the body from the future stream and parse it as json
|
||||
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
|
||||
let json = map_capabilities(json);
|
||||
// manipulate the json to convert from tauri option to native driver options
|
||||
let json = map_capabilities(json);
|
||||
|
||||
// serialize json and update the content-length header to be accurate
|
||||
let bytes = serde_json::to_vec(&json)?;
|
||||
parts.headers.insert(CONTENT_LENGTH, bytes.len().into());
|
||||
// serialize json and update the content-length header to be accurate
|
||||
let bytes = serde_json::to_vec(&json)?;
|
||||
parts.headers.insert(CONTENT_LENGTH, bytes.len().into());
|
||||
|
||||
req = Request::from_parts(parts, bytes.into());
|
||||
}
|
||||
Request::from_parts(parts, Full::new(bytes.into()))
|
||||
} else {
|
||||
let (parts, body) = req.into_parts();
|
||||
|
||||
let body = body.collect().await?.to_bytes().to_vec();
|
||||
|
||||
Request::from_parts(parts, Full::new(body.into()))
|
||||
};
|
||||
|
||||
client
|
||||
.request(forward_to_native_driver(req, args)?)
|
||||
.request(forward_to_native_driver(new_req, args)?)
|
||||
.err_into()
|
||||
.await
|
||||
}
|
||||
|
||||
/// Transform the request to a request for the native webdriver server.
|
||||
fn forward_to_native_driver(mut req: Request<Body>, args: Args) -> Result<Request<Body>, Error> {
|
||||
fn forward_to_native_driver(
|
||||
mut req: Request<Full<Bytes>>,
|
||||
args: Args,
|
||||
) -> Result<Request<Full<Bytes>>, Error> {
|
||||
let host: Authority = {
|
||||
let headers = req.headers_mut();
|
||||
headers.remove("host").expect("hyper request has host")
|
||||
@@ -171,30 +188,44 @@ 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 {
|
||||
if let Ok(listener) = TcpListener::bind(address).await {
|
||||
loop {
|
||||
let client = client.clone();
|
||||
let args = args.clone();
|
||||
if let Ok((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);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
println!("accept new stream fail, ignore here");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("can not listen to address: {:?}", address);
|
||||
}
|
||||
};
|
||||
srv.await;
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user