'actix-web: limit upload file size
I successfully uploaded the file referring to this example, but I don't know how to limit the size of the file, for example I can't save the file more than 5M
[dependencies]
actix-web = "4"
actix-multipart = "0.4"
I tried this, but it didn't work.
web::resource("/upload_file")
.app_data(web::PayloadConfig::new(1024 * 5))
.route(web::post().to(views::save_file)),
Solution 1:[1]
middleware
It is used in all requests by default, and can be used in a specified route using req.path()
use actix_web::Error;
use std::future::{ready, Ready};
use actix_web::dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform};
use futures_util::future::LocalBoxFuture;
pub struct ContentLengthLimit {
pub limit: u64, // byte
}
impl<S, B> Transform<S, ServiceRequest> for ContentLengthLimit
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Response = ServiceResponse<B>;
type Error = Error;
type InitError = ();
type Transform = ContentLengthLimitMiddleware<S>;
type Future = Ready<Result<Self::Transform, Self::InitError>>;
fn new_transform(&self, service: S) -> Self::Future {
ready(Ok(ContentLengthLimitMiddleware {
service,
limit: self.limit,
}))
}
}
impl Default for ContentLengthLimit {
fn default() -> Self {
Self {
limit: 1024 * 1024 * 5, /* 5M */
}
}
}
pub struct ContentLengthLimitMiddleware<S> {
service: S,
limit: u64,
}
impl<S, B> ContentLengthLimitMiddleware<S>
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
fn is_big(&self, req: &ServiceRequest) -> Result<bool, ()> {
Ok(req
.headers()
.get("content-length")
.ok_or(())?
.to_str()
.map_err(|_| ())?
.parse::<u64>()
.map_err(|_| ())?
> self.limit)
}
}
impl<S, B> Service<ServiceRequest> for ContentLengthLimitMiddleware<S>
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Response = ServiceResponse<B>;
type Error = Error;
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
forward_ready!(service);
fn call(&self, req: ServiceRequest) -> Self::Future {
if let Ok(r) = self.is_big(&req) {
if r {
return Box::pin(async { Err(hje("error").actix()) });
}
}
let fut = self.service.call(req);
Box::pin(async move {
let res = fut.await?;
Ok(res)
})
}
}
use
App::new().wrap(ContentLengthLimit::default())
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | januw a |
