mirror of
https://github.com/actix/examples
synced 2024-11-30 17:14:35 +01:00
Updated forms/multipart to v4. (#503)
This commit is contained in:
parent
e903184a12
commit
5df5bd10ea
@ -2,7 +2,7 @@
|
|||||||
name = "multipart-example"
|
name = "multipart-example"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
authors = ["Bevan Hunt <bevan@bevanhunt.com>"]
|
authors = ["Bevan Hunt <bevan@bevanhunt.com>"]
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "Simple file uploader in Actix Web with Async/Await"
|
description = "Simple file uploader in Actix Web with Async/Await"
|
||||||
keywords = ["actix", "actix-web", "multipart"]
|
keywords = ["actix", "actix-web", "multipart"]
|
||||||
@ -10,9 +10,9 @@ repository = "https://github.com/actix/examples"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-multipart = "0.3"
|
actix-multipart = "0.4.0-beta.12"
|
||||||
actix-web = "3"
|
actix-web = "4.0.0-beta.21"
|
||||||
|
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
sanitize-filename = "0.2"
|
sanitize-filename = "0.3"
|
||||||
uuid = { version = "0.8", features = ["v4"] }
|
uuid = { version = "0.8", features = ["v4"] }
|
||||||
|
@ -7,7 +7,7 @@ cd forms/multipart
|
|||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
``` open web browser to localhost:3000 and upload file(s) ```
|
``` open web browser to localhost:8080 and upload file(s) ```
|
||||||
|
|
||||||
### Result
|
### Result
|
||||||
|
|
||||||
|
@ -9,23 +9,20 @@ async fn save_file(mut payload: Multipart) -> Result<HttpResponse, Error> {
|
|||||||
// iterate over multipart stream
|
// iterate over multipart stream
|
||||||
while let Some(mut field) = payload.try_next().await? {
|
while let Some(mut field) = payload.try_next().await? {
|
||||||
// A multipart/form-data stream has to contain `content_disposition`
|
// A multipart/form-data stream has to contain `content_disposition`
|
||||||
let content_disposition = field
|
let content_disposition = field.content_disposition();
|
||||||
.content_disposition()
|
|
||||||
.ok_or_else(|| HttpResponse::BadRequest().finish())?;
|
|
||||||
|
|
||||||
let filename = content_disposition.get_filename().map_or_else(
|
let filename = content_disposition
|
||||||
|| Uuid::new_v4().to_string(),
|
.get_filename()
|
||||||
|f| sanitize_filename::sanitize(f),
|
.map_or_else(|| Uuid::new_v4().to_string(), sanitize_filename::sanitize);
|
||||||
);
|
|
||||||
let filepath = format!("./tmp/{}", filename);
|
let filepath = format!("./tmp/{}", filename);
|
||||||
|
|
||||||
// File::create is blocking operation, use threadpool
|
// File::create is blocking operation, use threadpool
|
||||||
let mut f = web::block(|| std::fs::File::create(filepath)).await?;
|
let mut f = web::block(|| std::fs::File::create(filepath)).await??;
|
||||||
|
|
||||||
// Field in turn is stream of *Bytes* object
|
// Field in turn is stream of *Bytes* object
|
||||||
while let Some(chunk) = field.try_next().await? {
|
while let Some(chunk) = field.try_next().await? {
|
||||||
// filesystem operations are blocking, we have to use threadpool
|
// filesystem operations are blocking, we have to use threadpool
|
||||||
f = web::block(move || f.write_all(&chunk).map(|_| f)).await?;
|
f = web::block(move || f.write_all(&chunk).map(|_| f)).await??;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user