我遇到的问题是 Actix Web 流代理的示例无法按预期工作。
您可以在下面找到我的代码。
我想要实现的目标: 从我的后端从另一台服务器流式传输 mp3,这样我就可以绕过 CORS 并移交我的 IP(例如)。打电话到 3d 方服务器。
虽然不存在 cors 标头,但我已经达到了获取音频播放事件的目的,但我无法获取播客的总时间,因此无法快进。
如何重现:
#[get("/proxy/podcast")]
pub(crate) async fn proxy_podcast(
mut payload: web::Payload,
params: web::Query<Params>,
peer_addr: Option<PeerAddr>,
method: Method,
) -> Result<HttpResponse, Error> {
let (tx, rx) = mpsc::unbounded_channel();
actix_web::rt::spawn(async move {
while let Some(chunk) = payload.next().await {
tx.send(chunk).unwrap();
}
});
let forwarded_req = reqwest::Client::new()
.request(method, params.url.clone())
.body(reqwest::Body::wrap_stream(UnboundedReceiverStream::new(rx)));
let forwarded_req = match peer_addr {
Some(PeerAddr(addr)) => forwarded_req.header("x-forwarded-for", addr.ip().to_string()),
None => forwarded_req,
};
let res = forwarded_req
.send()
.await
.map_err(error::ErrorInternalServerError)?;
println!("{:?}",res.headers());
let mut client_resp = HttpResponse::build(res.status());
// Remove `Connection` as per
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection#Directives
for (header_name, header_value) in res.headers().iter() {
println!("Key: {:?}, Value: {:?}", header_name, header_value);
client_resp.insert_header((header_name.clone(), header_value.clone()));
}
Ok(client_resp.streaming(res.bytes_stream()))
}
我解决了这个问题。我遇到的问题是初始响应中缺少请求标头。我还必须删除前端请求中存在的标头到我的后端。
这是我的结果:
for x in rq.headers() {
if x.0 == "host"||x.0 == "referer"||x.0 == "sec-fetch-site"||x.0 == "sec-fetch-mode" {
continue;
}
header_map.append(x.0.clone(), x.1.clone());
}
// Required to not generate a 302 redirect
header_map.append("sec-fetch-mode", "no-cors".parse().unwrap());
header_map.append("sec-fetch-site", "cross-site".parse().unwrap());