[Rust Server] Allow configuration of multipart/form attachment size limit (#19371)

* [Rust Server] Allow configuration of multipart/form attachment size limit

multipart 0.14+ imposes a 8MB size limit on multipart/form bodies.

This allows that limit to be configured. The default is left as is.

This also improves error messages produced when handling multipart/form bodies.

* Update samples
This commit is contained in:
Richard Whitehouse 2024-08-17 09:02:20 +01:00 committed by GitHub
parent bb831dad9a
commit 0a5c99739a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 432 additions and 172 deletions

View File

@ -19,7 +19,7 @@ use mime_multipart::{read_multipart_body, Node, Part};
{{/apiUsesMultipartRelated}}
{{#apiUsesMultipartFormData}}
use multipart::server::Multipart;
use multipart::server::save::SaveResult;
use multipart::server::save::{PartialReason, SaveResult};
{{/apiUsesMultipartFormData}}
#[allow(unused_imports)]

View File

@ -4,6 +4,9 @@ pub struct MakeService<T, C> where
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + Send + Sync + 'static
{
api_impl: T,
{{#apiUsesMultipartFormData}}
multipart_form_size_limit: Option<u64>,
{{/apiUsesMultipartFormData}}
marker: PhantomData<C>,
}
@ -14,11 +17,25 @@ impl<T, C> MakeService<T, C> where
pub fn new(api_impl: T) -> Self {
MakeService {
api_impl,
{{#apiUsesMultipartFormData}}
multipart_form_size_limit: Some(8 * 1024 * 1024),
{{/apiUsesMultipartFormData}}
marker: PhantomData
}
}
}
{{#apiUsesMultipartFormData}}
/// Configure size limit when inspecting a multipart/form body.
///
/// Default is 8 MiB.
///
/// Set to None for no size limit, which presents a Denial of Service attack risk.
pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option<u64>) -> Self {
self.multipart_form_size_limit = multipart_form_size_limit;
self
}
{{/apiUsesMultipartFormData}}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
@ -33,8 +50,11 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone()){{^apiUsesMultipartFormData}};{{/apiUsesMultipartFormData}}
{{#apiUsesMultipartFormData}}
.multipart_form_size_limit(self.multipart_form_size_limit);
{{/apiUsesMultipartFormData}}
future::ok(service)
}
}

View File

@ -9,15 +9,43 @@
use std::io::Read;
// Read Form Parameters from body
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary)
.save()
.size_limit(multipart_form_size_limit)
.temp()
{
SaveResult::Full(entries) => {
entries
},
_ => {
SaveResult::Partial(_, PartialReason::CountLimit) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process all message parts".to_string()))
.expect("Unable to create Bad Request response due to failure to process all message"))
.body(Body::from("Unable to process message part due to excessive parts".to_string()))
.expect("Unable to create Bad Request response due to excessive parts"))
},
SaveResult::Partial(_, PartialReason::SizeLimit) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process message part due to excessive data".to_string()))
.expect("Unable to create Bad Request response due to excessive data"))
},
SaveResult::Partial(_, PartialReason::Utf8Error(_)) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process message part due to invalid data".to_string()))
.expect("Unable to create Bad Request response due to invalid data"))
},
SaveResult::Partial(_, PartialReason::IoError(_)) => {
return Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from("Failed to process message part due an internal error".to_string()))
.expect("Unable to create Internal Server Error response due to an internal errror"))
},
SaveResult::Error(e) => {
return Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from("Failed to process all message parts due to an internal error".to_string()))
.expect("Unable to create Internal Server Error response due to an internal error"))
},
};
{{#formParams}}

View File

@ -2,5 +2,13 @@
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
{{#apiUsesMultipartFormData}}
self.multipart_form_size_limit,
{{/apiUsesMultipartFormData}}
))
}
}

View File

@ -11,6 +11,9 @@ pub struct Service<T, C> where
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + Send + Sync + 'static
{
api_impl: T,
{{#apiUsesMultipart}}
multipart_form_size_limit: Option<u64>,
{{/apiUsesMultipart}}
marker: PhantomData<C>,
}
@ -21,9 +24,24 @@ impl<T, C> Service<T, C> where
pub fn new(api_impl: T) -> Self {
Service {
api_impl,
{{#apiUsesMultipart}}
multipart_form_size_limit: Some(8 * 1024 * 1024),
{{/apiUsesMultipart}}
marker: PhantomData
}
}
{{#apiUsesMultipart}}
/// Configure size limit when extracting a multipart/form body.
///
/// Default is 8 MiB.
///
/// Set to None for no size limit, which presents a Denial of Service attack risk.
pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option<u64>) -> Self {
self.multipart_form_size_limit = multipart_form_size_limit;
self
}
{{/apiUsesMultipart}}
}
impl<T, C> Clone for Service<T, C> where
@ -33,6 +51,9 @@ impl<T, C> Clone for Service<T, C> where
fn clone(&self) -> Self {
Service {
api_impl: self.api_impl.clone(),
{{#apiUsesMultipart}}
multipart_form_size_limit: Some(8 * 1024 * 1024),
{{/apiUsesMultipart}}
marker: self.marker,
}
}
@ -50,7 +71,14 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
{{#apiUsesMultipartFormData}}
multipart_form_size_limit: Option<u64>,
{{/apiUsesMultipartFormData}}
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + Send + Sync + 'static
{

View File

@ -16,7 +16,7 @@ use hyper_0_10::header::{Headers, ContentType};
use mime_0_2::{TopLevel, SubLevel, Mime as Mime2};
use mime_multipart::{read_multipart_body, Node, Part};
use multipart::server::Multipart;
use multipart::server::save::SaveResult;
use multipart::server::save::{PartialReason, SaveResult};
#[allow(unused_imports)]
use crate::{models, header, AuthenticationApi};
@ -55,6 +55,7 @@ pub struct MakeService<T, C> where
C: Has<XSpanIdString> + Send + Sync + 'static
{
api_impl: T,
multipart_form_size_limit: Option<u64>,
marker: PhantomData<C>,
}
@ -65,11 +66,21 @@ impl<T, C> MakeService<T, C> where
pub fn new(api_impl: T) -> Self {
MakeService {
api_impl,
multipart_form_size_limit: Some(8 * 1024 * 1024),
marker: PhantomData
}
}
}
/// Configure size limit when inspecting a multipart/form body.
///
/// Default is 8 MiB.
///
/// Set to None for no size limit, which presents a Denial of Service attack risk.
pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option<u64>) -> Self {
self.multipart_form_size_limit = multipart_form_size_limit;
self
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
@ -84,9 +95,10 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone())
.multipart_form_size_limit(self.multipart_form_size_limit);
future::ok(service)
}
}
@ -103,6 +115,7 @@ pub struct Service<T, C> where
C: Has<XSpanIdString> + Send + Sync + 'static
{
api_impl: T,
multipart_form_size_limit: Option<u64>,
marker: PhantomData<C>,
}
@ -113,9 +126,20 @@ impl<T, C> Service<T, C> where
pub fn new(api_impl: T) -> Self {
Service {
api_impl,
multipart_form_size_limit: Some(8 * 1024 * 1024),
marker: PhantomData
}
}
/// Configure size limit when extracting a multipart/form body.
///
/// Default is 8 MiB.
///
/// Set to None for no size limit, which presents a Denial of Service attack risk.
pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option<u64>) -> Self {
self.multipart_form_size_limit = multipart_form_size_limit;
self
}
}
impl<T, C> Clone for Service<T, C> where
@ -125,6 +149,7 @@ impl<T, C> Clone for Service<T, C> where
fn clone(&self) -> Self {
Service {
api_impl: self.api_impl.clone(),
multipart_form_size_limit: Some(8 * 1024 * 1024),
marker: self.marker,
}
}
@ -142,7 +167,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
multipart_form_size_limit: Option<u64>,
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Send + Sync + 'static
{
@ -303,15 +333,43 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
use std::io::Read;
// Read Form Parameters from body
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary)
.save()
.size_limit(multipart_form_size_limit)
.temp()
{
SaveResult::Full(entries) => {
entries
},
_ => {
SaveResult::Partial(_, PartialReason::CountLimit) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process all message parts".to_string()))
.expect("Unable to create Bad Request response due to failure to process all message"))
.body(Body::from("Unable to process message part due to excessive parts".to_string()))
.expect("Unable to create Bad Request response due to excessive parts"))
},
SaveResult::Partial(_, PartialReason::SizeLimit) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process message part due to excessive data".to_string()))
.expect("Unable to create Bad Request response due to excessive data"))
},
SaveResult::Partial(_, PartialReason::Utf8Error(_)) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process message part due to invalid data".to_string()))
.expect("Unable to create Bad Request response due to invalid data"))
},
SaveResult::Partial(_, PartialReason::IoError(_)) => {
return Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from("Failed to process message part due an internal error".to_string()))
.expect("Unable to create Internal Server Error response due to an internal errror"))
},
SaveResult::Error(e) => {
return Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from("Failed to process all message parts due to an internal error".to_string()))
.expect("Unable to create Internal Server Error response due to an internal error"))
},
};
let field_string_field = entries.fields.remove("string_field");
@ -557,7 +615,13 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
self.multipart_form_size_limit,
))
}
}
/// Request parser for `Api`.

View File

@ -59,7 +59,6 @@ impl<T, C> MakeService<T, C> where
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Send + Sync + 'static
@ -73,9 +72,9 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone());
future::ok(service)
}
}
@ -131,7 +130,11 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Send + Sync + 'static
{
@ -221,7 +224,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
))
}
}
/// Request parser for `Api`.

View File

@ -72,7 +72,6 @@ impl<T, C> MakeService<T, C> where
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
@ -86,9 +85,9 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone());
future::ok(service)
}
}
@ -145,7 +144,11 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
{
@ -265,7 +268,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
))
}
}
/// Request parser for `Api`.

View File

@ -144,7 +144,6 @@ impl<T, C> MakeService<T, C> where
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
@ -158,9 +157,9 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone());
future::ok(service)
}
}
@ -216,7 +215,11 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
{
@ -1935,7 +1938,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
))
}
}
/// Request parser for `Api`.

View File

@ -167,7 +167,6 @@ impl<T, C> MakeService<T, C> where
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Send + Sync + 'static
@ -181,9 +180,9 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone());
future::ok(service)
}
}
@ -239,7 +238,11 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Send + Sync + 'static
{
@ -1401,7 +1404,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
))
}
}
/// Request parser for `Api`.

View File

@ -13,7 +13,7 @@ pub use swagger::auth::Authorization;
use swagger::auth::Scopes;
use url::form_urlencoded;
use multipart::server::Multipart;
use multipart::server::save::SaveResult;
use multipart::server::save::{PartialReason, SaveResult};
#[allow(unused_imports)]
use crate::{models, header, AuthenticationApi};
@ -162,6 +162,7 @@ pub struct MakeService<T, C> where
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
{
api_impl: T,
multipart_form_size_limit: Option<u64>,
marker: PhantomData<C>,
}
@ -172,11 +173,21 @@ impl<T, C> MakeService<T, C> where
pub fn new(api_impl: T) -> Self {
MakeService {
api_impl,
multipart_form_size_limit: Some(8 * 1024 * 1024),
marker: PhantomData
}
}
}
/// Configure size limit when inspecting a multipart/form body.
///
/// Default is 8 MiB.
///
/// Set to None for no size limit, which presents a Denial of Service attack risk.
pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option<u64>) -> Self {
self.multipart_form_size_limit = multipart_form_size_limit;
self
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
@ -191,9 +202,10 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone())
.multipart_form_size_limit(self.multipart_form_size_limit);
future::ok(service)
}
}
@ -210,6 +222,7 @@ pub struct Service<T, C> where
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
{
api_impl: T,
multipart_form_size_limit: Option<u64>,
marker: PhantomData<C>,
}
@ -220,9 +233,20 @@ impl<T, C> Service<T, C> where
pub fn new(api_impl: T) -> Self {
Service {
api_impl,
multipart_form_size_limit: Some(8 * 1024 * 1024),
marker: PhantomData
}
}
/// Configure size limit when extracting a multipart/form body.
///
/// Default is 8 MiB.
///
/// Set to None for no size limit, which presents a Denial of Service attack risk.
pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option<u64>) -> Self {
self.multipart_form_size_limit = multipart_form_size_limit;
self
}
}
impl<T, C> Clone for Service<T, C> where
@ -232,6 +256,7 @@ impl<T, C> Clone for Service<T, C> where
fn clone(&self) -> Self {
Service {
api_impl: self.api_impl.clone(),
multipart_form_size_limit: Some(8 * 1024 * 1024),
marker: self.marker,
}
}
@ -249,7 +274,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
multipart_form_size_limit: Option<u64>,
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
{
@ -2148,15 +2178,43 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
use std::io::Read;
// Read Form Parameters from body
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary)
.save()
.size_limit(multipart_form_size_limit)
.temp()
{
SaveResult::Full(entries) => {
entries
},
_ => {
SaveResult::Partial(_, PartialReason::CountLimit) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process all message parts".to_string()))
.expect("Unable to create Bad Request response due to failure to process all message"))
.body(Body::from("Unable to process message part due to excessive parts".to_string()))
.expect("Unable to create Bad Request response due to excessive parts"))
},
SaveResult::Partial(_, PartialReason::SizeLimit) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process message part due to excessive data".to_string()))
.expect("Unable to create Bad Request response due to excessive data"))
},
SaveResult::Partial(_, PartialReason::Utf8Error(_)) => {
return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Unable to process message part due to invalid data".to_string()))
.expect("Unable to create Bad Request response due to invalid data"))
},
SaveResult::Partial(_, PartialReason::IoError(_)) => {
return Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from("Failed to process message part due an internal error".to_string()))
.expect("Unable to create Internal Server Error response due to an internal errror"))
},
SaveResult::Error(e) => {
return Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from("Failed to process all message parts due to an internal error".to_string()))
.expect("Unable to create Internal Server Error response due to an internal error"))
},
};
let field_additional_metadata = entries.fields.remove("additional_metadata");
@ -3171,7 +3229,13 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
self.multipart_form_size_limit,
))
}
}
/// Request parser for `Api`.

View File

@ -59,7 +59,6 @@ impl<T, C> MakeService<T, C> where
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
@ -73,9 +72,9 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone());
future::ok(service)
}
}
@ -131,7 +130,11 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Has<Option<Authorization>> + Send + Sync + 'static
{
@ -187,7 +190,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
))
}
}
/// Request parser for `Api`.

View File

@ -81,7 +81,6 @@ impl<T, C> MakeService<T, C> where
}
}
impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Send + Sync + 'static
@ -95,9 +94,9 @@ impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
}
fn call(&mut self, target: Target) -> Self::Future {
future::ok(Service::new(
self.api_impl.clone(),
))
let service = Service::new(self.api_impl.clone());
future::ok(service)
}
}
@ -153,7 +152,11 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
self.api_impl.poll_ready(cx)
}
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
fn call(&mut self, req: (Request<Body>, C)) -> Self::Future {
async fn run<T, C>(
mut api_impl: T,
req: (Request<Body>, C),
) -> Result<Response<Body>, crate::ServiceError> where
T: Api<C> + Clone + Send + 'static,
C: Has<XSpanIdString> + Send + Sync + 'static
{
@ -640,7 +643,12 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
.body(Body::empty())
.expect("Unable to create Not Found response"))
}
} Box::pin(run(self.api_impl.clone(), req)) }
}
Box::pin(run(
self.api_impl.clone(),
req,
))
}
}
/// Request parser for `Api`.