Reply with a stream
sorin-davidoi opened this issue ยท 7 comments
Looking over the list of implementations for Reply, there doesn't seem to be a way to reply with a Stream
.
I am basically trying to port the following code from using hyper
to warp
:
fn main () {
let addr = ([127, 0, 0, 1], 8000).into();
let server = Server::bind(&addr)
.serve(|| hyper::service::service_fn(handler))
.map(|r| {
println!("Response: {:?}", r);
}).map_err(|e| {
println!("Error: {}", e);
});
hyper::rt::run(server);
}
type BoxedFuture = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>;
fn handler(_request: Request<Body>) -> BoxedFuture {
let mut response = Response::new(Body::empty());
*response.body_mut() =
Body::wrap_stream(<something that implements Stream>);
Box::new(future::ok(response))
}
My original concern was that I didn't want to expose exactly how streaming responses works, in case adding compression filters needed to adjust them, and thus create a breaking change. However, I think warp can also implement Reply
for response with a hyper::Body
, and if the internal type needs to change, that specific impl can simply map it...
Master now has changes to allow any Response<impl Into<hyper::Body>>
!
That was quick, thank you!
@seanmonstar Was this reverted? The following code doesn't work for me, even though I explicitly create a hyper::Body
:
async fn get_x() -> Result<impl warp::Reply, std::convert::Infallible> {
let response_stream = reqwest::get("....").await.unwrap().bytes_stream();
let body: hyper::Body = hyper::Body::wrap_stream(response_stream);
Ok(body)
}
errs with
the trait `warp::reply::Reply` is not implemented for `hyper::body::body::Body`
Of course if there is a better way to forward the reqwest
response, a hint would be much appreciated :)
@tp I don't think this was reverted... a guess, do the versions match? If the version of hyper
you're using doesn't match the version warp
is, then the trait won't be implemented. (If it doesn't work, let's open a new issue to track, as it'd be a new bug.)
Of course if there is a better way to forward the
reqwest
response, a hint would be much appreciated :)
This seems to work for me:
async fn proxy(_unused: String) -> Result<impl warp::Reply, Infallible> {
let response_stream =
reqwest::get("http://build/builds/file.tar.bz2").await.unwrap().bytes_stream();
let body= hyper::Body::wrap_stream(response_stream);
Ok(warp::reply::Response::new(body))
}
@darkprokoba I have a similar requirement. Could you please help?
I want to create a similar proxy kind of setup.
But before the get request, I want to add header information to it.
Also, want to work on post reqwest, how to pass the received post request json body to the external url?