-
-
Save lsk569937453/b42a8cfce21bd20c5da8737db1f5a1b1 to your computer and use it in GitHub Desktop.
Hyper v1 gateway performance problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "hyper_1" | |
version = "0.1.0" | |
edition = "2021" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[[bin]] | |
name = "silverwind" | |
path = "src/main.rs" | |
[dependencies] | |
hyper = { version = "1.2.0", features = ["full"] } | |
tokio = { version = "1.36.0", features = ["full"] } | |
hyper-util = { version = "0.1.3", features = ["full"] } | |
bytes = "1" | |
http-body-util = { version = "0.1.0"} | |
anyhow = { version = "1.0.80" } | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use anyhow::anyhow; | |
use hyper::{server::conn::http1, service::service_fn}; | |
use std::net::SocketAddr; | |
use tokio::net::TcpListener; | |
use bytes::Bytes; | |
use http_body_util::{combinators::BoxBody, BodyExt, Full}; | |
use hyper::body::Incoming; | |
use hyper::{Request, Response, Uri}; | |
use hyper_util::client::legacy::{connect::HttpConnector, Client}; | |
use hyper_util::rt::TokioIo; | |
use std::convert::Infallible; | |
use tokio::runtime; | |
#[tokio::main] | |
async fn main() { | |
if let Err(err) = start_with_error().await { | |
println!("Failed to serve the connection: {:?}", err); | |
} | |
} | |
async fn check(uri: Uri) -> Result<(), anyhow::Error> { | |
let backend_path = uri.path_and_query().ok_or(anyhow!(""))?.as_str(); | |
Ok(()) | |
} | |
async fn do_req( | |
client: Client<HttpConnector, BoxBody<Bytes, Infallible>>, | |
req: Request<BoxBody<Bytes, Infallible>>, | |
) -> Result<Response<BoxBody<Bytes, Infallible>>, Infallible> { | |
let uri = req.uri().clone(); | |
check(uri) | |
.await | |
.map_err(|_| -> Infallible { unreachable!() })?; | |
let response_incoming = client | |
.request(req) | |
.await | |
.map_err(|_| -> Infallible { unreachable!() })?; | |
let res = response_incoming | |
.map(|b| b.boxed()) | |
.map(|item| item.map_err(|_| -> Infallible { unreachable!() }).boxed()); | |
Ok(res) | |
} | |
async fn start_with_error() -> Result<(), Box<dyn std::error::Error>> { | |
let in_addr: SocketAddr = ([0, 0, 0, 0], 6667).into(); | |
let out_addr_clone = "http://backend:8080"; | |
let listener = TcpListener::bind(in_addr).await?; | |
println!("Listening on http://{}", in_addr); | |
println!("Proxying on http://{}", out_addr_clone); | |
let client = Client::builder(hyper_util::rt::TokioExecutor::new()).build(HttpConnector::new()); | |
loop { | |
let (stream, _) = listener.accept().await?; | |
let io = TokioIo::new(stream); | |
let client_clone = client.clone(); | |
let service = service_fn(move |mut req: Request<Incoming>| { | |
let client_clone1 = client_clone.clone(); | |
let uri_now: hyper::http::uri::Uri = out_addr_clone.parse().unwrap(); | |
*req.uri_mut() = uri_now.clone(); | |
let req = req.map(|item| item.map_err(|_| -> Infallible { unreachable!() }).boxed()); | |
do_req(client_clone1, req) | |
}); | |
tokio::task::spawn(async move { | |
if let Err(err) = http1::Builder::new() | |
.preserve_header_case(true) | |
.title_case_headers(true) | |
.serve_connection(io, service) | |
.await | |
{ | |
println!("Failed to serve the connection: {:?}", err); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment