[Help] How to copy Request<Incoming> for useing sender.send_request and hyper::upgrade::on for web soket proxy at the same time #3352
-
How to copy Request for useing sender.send_request and hyper::upgrade::on for web soket proxy at the same time
my code use std::net::SocketAddr;
use tokio::net::{TcpListener, TcpStream};
use hyper::server::conn::http1;
use hyper::service::service_fn;
use hyper::{Request, Response, StatusCode};
use hyper::body::Incoming;
use hyper_util::rt::TokioIo;
/// Handle server-side I/O after HTTP upgraded.
/*async fn server_upgraded_io(upgraded: Upgraded, conn: Connection<TokioIo<TcpStream>, Incoming>) -> Result<()> {
let upgraded = TokioIo::new(upgraded);
let tcp = conn.into_parts().io;
tokio::io::copy_bidirectional(&mut upgraded, &mut tcp).await?;
Ok(())
} */
/// Our server HTTP handler to initiate HTTP upgrades.
async fn server_upgrade(req: Request<Incoming>) -> Result<Response<Incoming>, hyper::Error> {
let addr = "localhost:8080";
let client_stream = TcpStream::connect(addr).await.unwrap();
let io = TokioIo::new(client_stream);
let (mut sender, conn) = hyper::client::conn::http1::handshake(io).await.unwrap();
tokio::task::spawn(async move {
if let Err(err) = conn.await {
println!("Connection failed: {:?}", err);
}
});
let mut ret = sender.send_request(req).await.unwrap();
if ret.status() == hyper::StatusCode::SWITCHING_PROTOCOLS {
tokio::task::spawn(async move {
let _rets = hyper::upgrade::on(&mut ret).await;
let _reqs = hyper::upgrade::on(&mut req).await;
});
}
return Ok(ret);
}
#[tokio::main]
async fn main() {
let other_addr: SocketAddr = ([127, 0, 0, 1], 3001).into();
let listener = TcpListener::bind(other_addr).await.expect("failed to bind");
loop {
let (stream, _) = listener.accept().await.unwrap();
let io = TokioIo::new(stream);
tokio::spawn(async move {
let task = http1::Builder::new().serve_connection(io, service_fn(server_upgrade));
let _conn = task.with_upgrades().await.unwrap();
});
}
} |
Beta Was this translation helpful? Give feedback.
Answered by
seanmonstar
Oct 18, 2023
Replies: 2 comments 1 reply
-
|
Beta Was this translation helpful? Give feedback.
0 replies
-
So, first you need to make let on_req_upgrade = hyper::upgrade::on(&mut req);
// ...
let mut resp = sender.send_request(req).await?;
tokio::task::spawn(async move {
let _upgraded_req = on_req_upgrade.await;
let _upgraded_resp = hyper::upgrade::on(&mut resp).await;
}); |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
thedtvn
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So, first you need to make
req
bemut req
in the argument list, in order to mutate it. You don't need to grab the upgrade future and await it at the same time. So, you could do: