Skip to content

Commit 8514601

Browse files
authored
doc: example on CORS and multipart for Rust (#112)
* doc: example on CORS and multipart for Rust * doc: linking to the example from the main README
1 parent 84d2abb commit 8514601

File tree

6 files changed

+137
-0
lines changed

6 files changed

+137
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Table of Contents:
3636
| **[CORS Node](functions/cors-node/README.md)** <br/> A Node function which allows CORS requests. | node18 | [Serverless Framework] |
3737
| **[CORS Python](functions/cors-python/README.md)** <br/> A Python function which allows CORS requests. | python310 | [Serverless Framework] |
3838
| **[CORS Rust](functions/cors-rust/README.md)** <br/> A Rust function which allows CORS requests. | rust185 | [Serverless Framework] |
39+
| **[CORS Multipart Rust](functions/cors-rust-multipart/README.md)** <br/> A Rust function which allows multipart requests with CORS. | rust185 | [Serverless Framework] |
3940
| **[Go Hello World](functions/go-hello-world/README.md)** <br/> A simple "hello world" example for Go | go121 | [Serverless Framework] |
4041
| **[Go SQS Publish](functions/go-mnq-sqs-publish/README.md)** <br/> A Go function to publish messages to SQS. | go121 | [Serverless Framework] |
4142
| **[Go MultiPart Upload to S3](functions/go-upload-file-s3-multipart)** <br/> A function to upload file from form-data to S3. | go120 | [Serverless Framework] |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "cors-rust-multipart"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
axum = { version = "0.8.4", features = ["multipart"] }
10+
http = "1.3.1"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Rust CORS multipart example
2+
3+
This function shows how to handle preflight CORS requests that will be sent by a browser when invoking a _multipart_ function.
4+
5+
The example uses totally permissive, open CORS, you will may want to modify this to make it more secure.
6+
7+
## Setup
8+
9+
This examples uses the [Scaleway Serverless Framework Plugin](https://github.com/scaleway/serverless-scaleway-functions).
10+
11+
Once this is set up, you can run:
12+
13+
```console
14+
npm install
15+
16+
serverless deploy
17+
```
18+
19+
Then, from the given URL, you can run:
20+
21+
```console
22+
# Options request
23+
curl -i -X OPTIONS <function URL>
24+
25+
# Get request
26+
curl -i -X GET <function URL>
27+
```
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "cors-rust-multipart",
3+
"version": "1.0.0",
4+
"main": "index.js",
5+
"scripts": {
6+
"test": "echo \"Error: no test specified\" && exit 1"
7+
},
8+
"keywords": [],
9+
"author": "",
10+
"license": "ISC",
11+
"dependencies": {},
12+
"devDependencies": {
13+
"serverless-scaleway-functions": "^0.4.4"
14+
},
15+
"description": ""
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
service: cors-rust-multipart
2+
configValidationMode: off
3+
provider:
4+
name: scaleway
5+
runtime: rust185
6+
7+
plugins:
8+
- serverless-scaleway-functions
9+
10+
package:
11+
patterns:
12+
- "!node_modules/**"
13+
- "!.gitignore"
14+
- "!.git/**"
15+
16+
functions:
17+
cors-permissive:
18+
handler: handler_with_cors
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use axum::{
2+
body::Body, extract::FromRequest, extract::Multipart, extract::Request, response::Response,
3+
};
4+
use http::StatusCode;
5+
6+
// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#the_http_response_headers
7+
pub fn with_permissive_cors(r: http::response::Builder) -> http::response::Builder {
8+
r.header("Access-Control-Allow-Headers", "*")
9+
.header("Access-Control-Allow-Methods", "*")
10+
.header("Access-Control-Allow-Origin", "*")
11+
}
12+
13+
pub async fn handler_with_cors(req: Request<Body>) -> Response<Body> {
14+
println!("{:?}", req);
15+
16+
// Check if this is an OPTIONS request
17+
if req.method() == http::Method::OPTIONS {
18+
return with_permissive_cors(Response::builder())
19+
.status(StatusCode::OK)
20+
.header("Content-Type", "text/plain")
21+
.body(Body::from("This is allowing most CORS requests"))
22+
.unwrap();
23+
}
24+
25+
// For POST requests, extract multipart data
26+
let (parts, body) = req.into_parts();
27+
let body_stream = axum::body::Body::new(body);
28+
29+
// Reconstruct the request for multipart extraction
30+
let request = Request::from_parts(parts, body_stream);
31+
32+
// Use Axum's built-in multipart extractor
33+
match Multipart::from_request(request, &()).await {
34+
Ok(multipart) => process_multipart(multipart).await,
35+
Err(err) => with_permissive_cors(Response::builder())
36+
.status(StatusCode::BAD_REQUEST)
37+
.body(Body::from(format!(
38+
"Failed to extract multipart data: {}",
39+
err
40+
)))
41+
.unwrap(),
42+
}
43+
}
44+
45+
// Process the multipart data, using Axum's multipart exmaple
46+
// See: https://github.com/tokio-rs/axum/blob/main/examples/multipart-form/src/main.rs
47+
async fn process_multipart(mut multipart: Multipart) -> Response<Body> {
48+
while let Some(field) = multipart.next_field().await.unwrap() {
49+
let name = field.name().unwrap().to_string();
50+
let file_name = field.file_name().unwrap().to_string();
51+
let content_type = field.content_type().unwrap().to_string();
52+
let data = field.bytes().await.unwrap();
53+
54+
println!(
55+
"Length of `{name}` (`{file_name}`: `{content_type}`) is {} bytes",
56+
data.len()
57+
);
58+
}
59+
60+
with_permissive_cors(Response::builder())
61+
.status(StatusCode::OK)
62+
.header("Content-Type", "text/plain")
63+
.body(Body::from("Multipart data processed successfully"))
64+
.unwrap()
65+
}

0 commit comments

Comments
 (0)