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 software developer originally from Graz but living in Vienna, Austria. I previously worked as a full-stack web developer before quitting my job to work as a freelancer and explore open source. Currently, I work at Netconomy.

Recent posts:

Radix Ui Adoption Guide Overview Examples And Alternatives

Radix UI adoption guide: Overview, examples, and alternatives

Radix UI is quickly rising in popularity and has become an excellent go-to solution for building modern design systems and websites.

Nefe Emadamerho-Atori
Apr 25, 2024 ⋅ 11 min read
Understanding The Css Revert Layer Keyword, Part Of Css Cascade Layers

Understanding the CSS revert-layer keyword

In this article, we’ll explore CSS cascade layers — and, specifically, the revert-layer keyword — to help you refine your styling strategy.

Chimezie Innocent
Apr 24, 2024 ⋅ 6 min read
Exploring Nushell, A Rust Powered, Cross Platform Shell

Exploring Nushell, a Rust-powered, cross-platform shell

Nushell is a modern, performant, extensible shell built with Rust. Explore its pros, cons, and how to install and get started with it.

Oduah Chigozie
Apr 23, 2024 ⋅ 6 min read
Exploring Zed, A Newly Open Source Code Editor Written In Rust

Exploring Zed, an open source code editor written in Rust

The Zed code editor sets itself apart with its lightning-fast performance and cutting-edge collaborative features.

Nefe Emadamerho-Atori
Apr 22, 2024 ⋅ 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