Search code examples
rustrust-rocket

How can I proxy/forward data using the Rocket web framework?


I have a list of links I want to serve data randomly from, as if the user manually went to the url themselves. These are not all the same content/file type, however they are all images (jpeg and png) (Ideally I would like to do this with any file type, not just jpeg and png or just images). I know I can serve them directly as an octet stream like this, but this will result in the files being downloaded, instead of being displayed inline. I have considered changing the content type based on the link extension, but I can't find any information on how to use content types that are unknown at compile time. I also feel like there might be a better way than that. How to forward data from a reqwest::blocking::Body in a Rocket responder? Seems to be somewhat similar to my question, however the file type is always png. I am using v0.5-rc of rocket.

#[get("/rand_img")]
async fn get_img() -> Vec<u8> {
    let vs = vec![
        "https://www.publicdomainpictures.net/pictures/320000/velka/background-image.png",
        "https://www.publicdomainpictures.net/pictures/410000/velka/cobalt-city-1.png",
        "https://www.publicdomainpictures.net/pictures/60000/velka/went-boating.jpg",
        "https://www.publicdomainpictures.net/pictures/30000/velka/paulino-nacht.jpg"
    ];
    let choice = vs.choose(&mut rand::thread_rng()).unwrap();
    let response = reqwest::get(*choice).await.unwrap().bytes().await.unwrap();
    response.to_vec()
}

Solution

  • I ended up downloading the image data, storing it in memory, and returning a content type and the image data.

        let imager = reqwest::get(&link)
            .await
            .expect("unable to fetch image")
            .bytes()
            .await
            .unwrap();
        let ext = &link.chars().rev().collect::<String>()[0..3] // this is really bad, i should split by `.` instead
        .chars()
        .rev().collect::<String>();
        return (ContentType::from_extension(ext).unwrap(), imager.to_vec())