某原子的tokio +hyper实现https代理
rust笔记
cargo.toml
[package]
name = "hypedemo"
version = "0.1.0"
edition = "2021"
[dependencies]
hyper={version="0.14.16",features=["full"]}
tokio={version="1",features=["full"]}
anyhow="1.0.53"
hyper-rustls = "0.23"
futures-util = "0.3.19"
以下是代码
use anyhow::{Result, Context, anyhow, Error};
use std::net::SocketAddr;
use std::sync::Arc;
use hyper::{
Body,
Request,
Response,
Server,
Client,
};
use hyper::service::{
make_service_fn,
service_fn,
};
pub fn proxy_crate(req: &mut Request<Body>) -> Result<()> {
for key in &["context-length", "accept-encoding", "content-encoding", "transfer-encoding"] {
req.headers_mut().remove(*key);
}
let uri = req.uri();
let uri_string = match uri.query() {
Some(query_item) => format!("https://crates.io{}?{}", uri.path(), query_item),
None => format!("https://crates.io{}", uri.path())
};
*req.uri_mut() = uri_string.parse().context("Parse url")?;
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
let https = hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.https_only()
.enable_http1()
.build();
let client: Client<_, hyper::Body> = Client::builder().build(https);
let client = Arc::new(client);
let addr = SocketAddr::from(([0, 0, 0, 0], 7000));
let make_svc = make_service_fn(move |_| {
let client = Arc::clone(&client);
async move {
Ok::<_, Error>(service_fn(
move |mut req| {
let client = Arc::clone(&client);
async move {
println!("proxy:{}", req.uri().path());
proxy_crate(&mut req)?;
client.request(req).await.context("proxy request")
}
}
))
}
});
let _server = Server::bind(&addr).serve(make_svc).await.context("Run servrer");
Ok::<(), anyhow::Error>(())
}
一运行正常,但是访问就不行了