http-client-multipart
This crate provides multipart request support for the http-client crate, enabling you to easily create and send multipart HTTP requests with file uploads and form data. It is designed to be client-agnostic, working seamlessly with any HttpClient implementation.
Features
- Client Agnostic: Works with any HTTP client that implements the
http-client'sHttpClienttrait. - File Uploads: Easily add files to your multipart requests.
- Form Fields: Include standard form fields in your requests.
- Correct Headers: Automatically sets the
Content-Typeheader with the correct boundary. - Easy to Use: A simple and ergonomic API.
Installation
Add http-client-multipart to your Cargo.toml:
[]
= "0.1.0" # Replace with the latest version
= "6.5.3" # Ensure you have the base http-client crate
= "1.6.0" # Or tokio, or any async runtime you prefer
Note: You also need to include a concrete implementation of the http-client's HttpClient trait (if you haven't already). Some popular choices:
http-clientwithh1_client(default, usesasync-h1):= { = "6.5.3", = ["h1_client", "native-tls"] }http-clientwithisahc(curl_clientfeature):= { = "6.5.3", = ["curl_client"] }http-clientwithhyper(hyper_clientfeature):= { = "6.5.3", = ["hyper_client"] }
Usage
Here's a detailed guide on how to use the http-client-multipart crate:
1. Import the necessary crates and modules:
use ;
use ;
use Multipart; // Import the Multipart struct
use RequestMultipartExt; // Import the extension trait (Optional)
use task; // Or tokio, or any async runtime you prefer
2. Create a Multipart instance:
let mut multipart = new;
This creates a new multipart form with a randomly generated boundary. The boundary is used to separate each part of the multipart data.
3. Add fields to the Multipart form:
Adding Text Fields:
Use the add_text method to add standard form fields:
multipart.add_text;
multipart.add_text;
Adding File Fields (from Path - Simplest Approach):
Use the add_file (async version) method to add files from their paths on the filesystem:
multipart.add_file.await?; // requires an async context (.await)
This automatically infers the filename and content type based on the file's path. It reads the file asynchronously, making it suitable for async contexts. The add_file function needs to be awaited as it is an async function.
Adding File Fields (from Readers):
If you already have file data in memory or want more control over the filename and content type, you can add file fields using add_async_read or add_sync_read.
-
add_async_read(Asynchronous Reader - recommended for async contexts):use File as AsyncFile; use BufReader; let file = open.await?; let buf_reader = new; // Wrap the async file with a buffered reader multipart.add_async_read.await?;This method takes an asynchronous reader (
impl AsyncRead + Unpin + Send + 'static) as input, along with the desired filename and content type. The data is read asynchronously into the body. Theadd_async_readfunction needs to be awaited as it is an async function. -
add_sync_read(Synchronous Reader - use with caution in async contexts):use File; let file = open?; multipart.add_sync_read?;This method takes a synchronous reader (
impl Read + Seek + Send + 'static) as input, along with the desired filename and content type. Use this in synchronous contexts, or if you are very careful about thread blocking in async. -
add_file_from_sync(Convenience forFileobjects - synchronous):use File; let file = open?; multipart.add_file_from_sync?;This is a shorthand for creating a
Fileobject directly and adding it.
4. Create an http-client Request:
let url = "https://httpbin.org/post".?; // Replace with your API endpoint
let mut req = new;
5. Set the Multipart data as the request body:
There are two ways to do this:
Method 1: Using set_request(req: &mut Request) (Mutates Existing Request - Preferred):
This is the recommended approach because it encapsulates all the logic within the Multipart struct:
multipart.set_request?;
This method will:
- Convert the
Multipartform into aBody. - Set the
Content-Typeheader of the request tomultipart/form-datawith the correct boundary. - Set the body of the request to the converted body.
Method 2: Using the RequestMultipartExt trait (Extension Method):
This approach adds an extension method to the Request object:
use RequestMultipartExt;
req.set_multipart_body?;
Both achieve the same outcome, but set_request offers better encapsulation.
6. Create an HttpClient and send the request:
use H1Client as Client; // Example: Using h1_client
let client = new;
let mut response = client.send.await?;
Remember to choose a concrete HttpClient implementation based on your needs (e.g., H1Client, IsahcClient, HyperClient).
7. Handle the response:
let body = response.body_string.await?;
println!;
Complete Example (using async-std and h1_client):
use ;
use ;
use Multipart;
use RequestMultipartExt;
use task;
use H1Client as Client;
async
Notes
- Error Handling: The examples above use
?for error propagation. In a real application, handle errors gracefully. - File Paths: Ensure that the file paths you provide to
add_fileare correct and accessible. - Content Types: While automatic content type detection is provided, you might need to specify the content type explicitly for certain file types using
add_async_readoradd_sync_readif the automatic detection is inaccurate. - Performance: For very large files, consider streaming the file data instead of reading it all into memory at once, using
add_async_read.
License
This crate is licensed under the MIT License.