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:

Understanding Solid Js Props A Complete Guide From Beginner To Advanced

Understanding SolidJS props: A complete guide

Let’s see how SolidJS props work to promote component reusability, exploring basic to advanced concepts for a complete understanding.

Temitope Oyedele
Dec 7, 2023 ⋅ 11 min read
Eleventy Vs. Next.js Static-Site Generation

Eleventy vs. Next.js for static site generation

We evaluate Eleventy and Next.js and compare both static site generators in terms of performance, developer experience, scalability, and ecosystem.

Nelson Michael
Dec 7, 2023 ⋅ 11 min read
Build Full-Stack App React Goxygen

Build a full-stack app with React and Goxygen

We show how to use Goxgen to scaffold a full-stack React app. See how to integrate React with Go and modify Goxygen to suit your project requirements.

Clara Ekekenta
Dec 6, 2023 ⋅ 8 min read
Express Js Adoption Guide Overview Examples Alternatives

Express.js adoption guide: Overview, examples, and alternatives

Express.js is a Node.js framework for creating maintainable and fast backend web applications in JavaScript. In the fast-paced world of […]

Antonello Zanini
Dec 6, 2023 ⋅ 17 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