I am writing a simple web server using warp
. I'm having issues image files which are stored in 'dynamic' directories, i.e. the directories have a static prefix but might be renamed. I successfully resolved the correct file, e.g. "1/image.png" resolves to "1-dynamic-name/image.png". But I don't understand how I am able to return the binary file content to the client.
My current approach is the following (shortened for clarity):
Routing:
let dyn_image = warp::path("base").and(warp::path::param::<u32>())
.and(warp::path::param::<String>()).and(warp::path::end())
.and(warp::get()).and_then(dyn_image);
warp::serve(dyn_image).run(([0, 0, 0, 0], 8000)).await;
Resolving:
pub async fn dyn_image(idx: u32, image: String) -> Result<impl warp::Reply, Rejection> {
let mut img_dir: PathBuf = ...
// Resolving the dynamic directory
if img_dir.exists() {
// How can I now serve the image file back to the client?
return Ok(warp::reply::?); // What's the correct reply?
}
Err(warp::reject())
}
I am struggling with the actual reply content. As far as I read the documentation, only reply::json
and reply::html
are implemented for a convenient response creation. But how is binary data handled? Do I need a stream, can I specify the file directly, like in warp::fs::file("...")
, or do I read the entire file into a buffer? I also saw something like a ResponseBuilder
?
The result return type you are returning Result<impl warp::Reply, Rejection>
can be many different data types. For example, you can create a http::Response
which contains the data of your file. Or even implement your own custom data type which sets the headers for you.
use std::fs;
use warp::{Filter, http::Response};
return warp::any().map(|| {
Response::builder()
.header("Content-Type", "application/octet-stream")
.body(fs::read(file_path).expect("Could not read file"))
Code modified from warp::reply documentation. You probably need to read the file in as a byte stream as shown by std::fs::read. Standard error handling applies, the file should probably be read before building a Response so you can build a proper error response if the file is not readable.