• Stars
    star
    147
  • Rank 251,347 (Top 5 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 4 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An async parser for multipart/form-data content-type in Rust

Github Actions Status crates.io Documentation MIT

multer-rs

An async parser for multipart/form-data content-type in Rust.

It accepts a Stream of Bytes as a source, so that It can be plugged into any async Rust environment e.g. any async server.

Docs

Install

Add this to your Cargo.toml:

[dependencies]
multer = "2.0"

Basic Example

use bytes::Bytes;
use futures::stream::Stream;
// Import multer types.
use multer::Multipart;
use std::convert::Infallible;
use futures::stream::once;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Generate a byte stream and the boundary from somewhere e.g. server request body.
    let (stream, boundary) = get_byte_stream_from_somewhere().await;

    // Create a `Multipart` instance from that byte stream and the boundary.
    let mut multipart = Multipart::new(stream, boundary);

    // Iterate over the fields, use `next_field()` to get the next field.
    while let Some(mut field) = multipart.next_field().await? {
        // Get field name.
        let name = field.name();
        // Get the field's filename if provided in "Content-Disposition" header.
        let file_name = field.file_name();

        println!("Name: {:?}, File Name: {:?}", name, file_name);

        // Process the field data chunks e.g. store them in a file.
        while let Some(chunk) = field.chunk().await? {
            // Do something with field chunk.
            println!("Chunk: {:?}", chunk);
        }
    }

    Ok(())
}

// Generate a byte stream and the boundary from somewhere e.g. server request body.
async fn get_byte_stream_from_somewhere() -> (impl Stream<Item = Result<Bytes, Infallible>>, &'static str) {
    let data = "--X-BOUNDARY\r\nContent-Disposition: form-data; name=\"my_text_field\"\r\n\r\nabcd\r\n--X-BOUNDARY--\r\n";
    let stream = once(async move { Result::<Bytes, Infallible>::Ok(Bytes::from(data)) });
    
    (stream, "X-BOUNDARY")
}

Prevent Denial of Service (DoS) Attacks

This crate also provides some APIs to prevent potential DoS attacks with fine grained control. It's recommended to add some constraints on field (specially text field) size to prevent DoS attacks exhausting the server's memory.

An example:

use multer::{Multipart, Constraints, SizeLimit};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create some constraints to be applied to the fields to prevent DoS attack.
    let constraints = Constraints::new()
         // We only accept `my_text_field` and `my_file_field` fields,
         // For any unknown field, we will throw an error.
         .allowed_fields(vec!["my_text_field", "my_file_field"])
         .size_limit(
             SizeLimit::new()
                 // Set 15mb as size limit for the whole stream body.
                 .whole_stream(15 * 1024 * 1024)
                 // Set 10mb as size limit for all fields.
                 .per_field(10 * 1024 * 1024)
                 // Set 30kb as size limit for our text field only.
                 .for_field("my_text_field", 30 * 1024),
         );

    // Create a `Multipart` instance from a stream and the constraints.
    let mut multipart = Multipart::with_constraints(some_stream, "X-BOUNDARY", constraints);

    while let Some(field) = multipart.next_field().await.unwrap() {
        let content = field.text().await.unwrap();
        assert_eq!(content, "abcd");
    } 
   
    Ok(())
}

Usage with hyper.rs server

An example showing usage with hyper.rs.

For more examples, please visit examples.

Contributing

Your PRs and suggestions are always welcome.

More Repositories

1

electron-menubar

Boilerplate for electron menubar application with PopOver with React + Webpack
JavaScript
159
star
2

rust-web-frameworks-benchmark

A hello world benchmark for the available Rust Web Frameworks: hyper vs gotham vs actix-web vs warp vs rocket
Rust
106
star
3

linkedin-auto-connect

πŸ’₯ An automation tool to automate the connection requests on LinkedIn
JavaScript
106
star
4

npmf

Fetch quick info of a npm pacakge using terminal
JavaScript
63
star
5

electron-with-rust

An example file transfer app showing how to create a very performant Electron app with Rust and Tokio.rs
JavaScript
42
star
6

upfy

A bash script to populate a fresh unix system with useful commands and aliases
Shell
38
star
7

sl

🍻 An utility tool to list npm scripts from package.json file
JavaScript
24
star
8

comet

A http long polling comet implementation for nodejs and browser
JavaScript
20
star
9

symbol-es6

β›„ ES6 Symbol polyfill in pure ES5
JavaScript
18
star
10

releez

An utility tool to run application release-checklist safely
Rust
14
star
11

git-npm

Tool for lazy developers, run npm commands directly through git and be more lazy 😎
Shell
14
star
12

AndroidWithRust

An example Android app showing two-way communication bridge with Rust backed by Tokio.rs
Rust
14
star
13

samples-viewer-generator

πŸŽ‰ A CLI utility tool to generate web app of data visualization samples for presentation purpose
CSS
13
star
14

belofte.js

πŸŒ‹ A lightweight Promises/A+ compliant implementation of ECMAScript Promise API
JavaScript
11
star
15

settimeout-rs

A Rust library to create a std::future::Future implementation to be used in any async function
Rust
8
star
16

vector.svg

🎨 A Javascript library for manipulating and animating SVG
JavaScript
8
star
17

collections-es6

🎁 ES6 Map, Set, WeakMap and WeakSet polyfill in pure ES5
JavaScript
6
star
18

es6-harmony

⚑ ES6 equivalent implimentation in ES5 for old JavaScript engines
JavaScript
6
star
19

read-all

Read all data from a Readable stream with Promise
JavaScript
4
star
20

maui

A fast TCP connection tunneling/port-forwarding tool, useful for any TCP protocol e.g. http, https, ftp, websocket, mysql etc.
Rust
4
star
21

sendify-rs

An unsafe crate to wrap a reference to make it Send + Sync to be able to transfer it between threads
Rust
3
star
22

ByteVault

A command line application that stores sensitive data as key-value pair securely in local machine
C
3
star
23

gpromise

A helper library to create a promise to be resolved/rejected from your other parts of codebase
TypeScript
3
star
24

instalify

Installation script for any executable file
Shell
3
star
25

no-more-anony-msg

A DDoS attack hacking tool to create message flood to the recipient of Sarahah or Stulish app
Go
2
star
26

TheMatrix

A little POC to simulate our World according to the franchise The Matrix.
1
star
27

scripts

A list of bash scripts needed in daily development
Shell
1
star
28

vADB

An application that helps to debug android app on real devices over Wi-Fi
Java
1
star
29

anonymouskiller

A web application to force a user to uninstall Stulish or Sarahah app from their phone
Go
1
star
30

rousan.github.io

My portfolio & bog
HTML
1
star
31

tulip

A Golang utility library of many commonly used functions
1
star
32

rust-cli-boilerplate

A boilerplate for the Rust command line applications
Shell
1
star
33

go-react-ssr-ts-wasm-example

An example project which uses Golang as backend, NextJS as frontend, also it uses TypeScript and WebAssembly(Golang).
JavaScript
1
star
34

es6-promise-shim

A lightweight implementation of Promise in pure ES5 code for older JS engines
JavaScript
1
star
35

server-long-conn

The strange server implementation whose full response can't be accessed at once
HTML
1
star
36

streamify-rs

Conversions from Rust values to Stream
Rust
1
star
37

WeShare

An application that transfers files between devices
C#
1
star
38

Sristi

Sristi: Techfest app for Jalaliguri Government Engineering College
Java
1
star
39

etp-rs

ETP(Event Transfer Protocol) Protocol in Rust
1
star
40

asyncer-rs

Some async extensions to the Rust type: Iterator, Options, Result etc.
1
star
41

reduce-image

A helpful tool to make an image smaller in size and quality
Rust
1
star
42

hippo

Send or receive files from anywhere right from your terminal or command prompt (Supports macOS, Linux and Windows).
1
star