2020-09-09
1518
#rust
Mario Zupan
24822
Sep 9, 2020 ⋅ 5 min read

File upload and download in Rust

Mario Zupan I'm a self-employed Software Engineer and Trainer living in Vienna, Austria. I've worked at several companies and in multiple fields building, maintaining and operating distributed systems at scale using Java, Kotlin, Node, Go and Rust. I also taught advanced software engineering courses for several years at the University of Applied Sciences FH Joanneum in Graz and worked as a technical trainer, empowering other software engineers to reach their full potential. Currently, I work as a freelance software engineer and trainer again, looking to help companies build high-quality software solutions. Check out my personal blog: http://www.zupzup.org.

Recent posts:

The 10 Best React Native Component Libraries You Should Know

The 10 best React Native UI libraries of 2025

UI libraries like React Native Paper and React Native Elements offer pre-developed components that help us deliver our React Native projects faster.

Aman Mittal
Feb 21, 2025 ⋅ 7 min read
top ten docker alternatives worth considering

The 10 best Docker alternatives to consider

Although Docker remains the dominant platform for containerization and container management, it’s good to know about different tools that may work better for certain use cases.

Ayooluwa Isaiah
Feb 21, 2025 ⋅ 13 min read
how to use the ternary operator in javascript

How to use the ternary operator in JavaScript

Add to your JavaScript knowledge of shortcuts by mastering the ternary operator, so you can write cleaner code that your fellow developers will love.

Chizaram Ken
Feb 21, 2025 ⋅ 7 min read
Using tsup To Bundle Your TypeScript Package

Using tsup to bundle your TypeScript package

Learn how to efficiently bundle your TypeScript package with tsup. This guide covers setup, custom output extensions, and best practices for optimized, production-ready builds.

Muhammed Ali
Feb 20, 2025 ⋅ 7 min read
View all posts

12 Replies to "File upload and download in Rust"

  1. Thanks for the interesting tutorial. I expanded it slightly by adding cors. This works fine for the download path, but it seems that its not working (even though compiling) for the upload part. The server throws an Internal Server Error about unknown header (“Content-Type”) event thought this is in the cors. Any idea why this could be?

    let download_cors = … (similar to upload cors)

    let upload_cors = warp::cors()
    .allow_any_origin().allow_headers(vec![“User-Agent”, “Sec-Fetch-Mode”, “Referer”, “Origin”, “Access-Control-Request-Method”, “Access-Control-Request-Headers”, “Content-Type”, “Accept”, “Authorization”, “type”])
    .allow_methods(vec![“GET”, “POST”, “DELETE”, “OPTIONS”]);
    let upload_route = warp::path(“upload”).and(warp::post()).and(warp::multipart::form().max_length(5_000_000)).and_then(upload).with(upload_cors);
    let download_route = warp::path(“files”).and(warp::fs::dir(“./files/”)).with(download_cors);

  2. Hey!

    Author here – thanks for the feedback, first and foremost.

    I added your CORS config and for me it works. How are you calling it? I tested it with cURL and Postman and in both cases it worked just fine.

    One thing I sometimes do to debug the errors, is add log statements (printlns for example) on top of the

    async fn handle_rejection(err: Rejection) -> std::result::Result {

    function, to see what rejection is thrown exactly and then I check the warp docs to see why that might happen.

  3. Dear Mario

    Thanks for the reply and sorry for the slow follow up. I figured out what was wrong. I was calling from a react app and the call actually did a pre-flight check using an options request, which of course was not implemented. Thus the call failed.

    Florian

  4. It seems that this example does not go into the details about how to properly structure a file and the functions within.

    I myself care only about the part that claims to show how to send multipart form data to ANY REST API route that is willing to ingest it.

    Code that is implementing upload function seems to raise errors and fail to compile.

    the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `Try`)
    the trait `Try` is not implemented for `()`
    required by `from_error’

    It is not clear on how to properly use the code that was shown.

  5. Hey Andzej!

    I’m the author of the post. I’m not 100% sure what exact issue you’re encountering.

    In terms of failure to compile – the code in the repository compiles just fine for me. Which version of Rust are you using?

    In terms of structuring the application, you’re right, the goal of this post was not to provide a holistic overview of application structuring, but rather to provide a quick setup for uploading and downloading files using Warp and Rust.

    What’s the exact errors you encounter, or which parts aren’t clear to you? I think it would be best if you opened a ticket at https://github.com/zupzup/warp-upload-download-example with your questions and I’ll be happy to help you!

    kind regards,
    Mario

  6. Hi! Thanks for writing this article!

    I would like to dynamically map the request path to a file path (by querying a database), but it seems to me that warp’s serve dir/fs function cannot be reused for that. How would you implement that?

    Thanks!

  7. Hey!

    So, if I understand you correctly, you’d want to map something like https://example.com/files/some/interesting/file to a file, where you get the actual path of the file via a database query based on the path.

    So somewhere in the DB, there is an entry like “path: /some/interesting/file” => “actualpath: /opt/files/24324.jpg/”.

    In that case, I think you can only do this “manually”, by having a handler on “/files”, which then parses the path, does the query, if it finds anything, read the file (e.g. using tokio::fs) and returns the file to the user with the appropariate HTTP headers.

    I’m not 100% sure I understand you correctly, but it sounds like something you’d have to implement step by step.

    Hope this helps!
    Mario

  8. Hi guys, upload using curl command is working just fine, however, upload from a React app in the Chrome browser gives error 500.
    Application log output was:
    unhandled error: Rejection(InvalidHeader { name: “content-type” })
    Any suggestions ?

  9. Hey

    As the error suggests, I believe the issue is with the “content-type” header. In the CURL command you can see

    –header ‘Content-Type: multipart/form-data’

    So in your React app, please check in the dev tools, if the request sent from your frontend actually contains this header and if not, you can try setting it manually on your upload request.

    Hope this helps!

Leave a Reply