I have the problem that the example of the actix web streaming proxy is not working as expected.
You can find my code below.
What I want to achieve: Stream an mp3 from another server from my backend so I can get around CORS and handing over the IP of my e.g. phone to the 3d party server.
I came as far as getting the audio to play event though no cors header is present but I can't get the total time of the podcast and can't fast forward thus.
How to reproduce:
- Take the sample actix web server
- Add the below endpoint
- Use this url in your browser: . The integrated html audio player doesn't show a time. When accessing it with only the query parameter i.e. the original url it works without a problem and I can skip around.
#[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()))
}