diff --git a/crates/service/web/storyteller_web/src/http_server/web_utils/handle_multipart_error.rs b/crates/service/web/storyteller_web/src/http_server/web_utils/handle_multipart_error.rs new file mode 100644 index 0000000000..ebc2685fd2 --- /dev/null +++ b/crates/service/web/storyteller_web/src/http_server/web_utils/handle_multipart_error.rs @@ -0,0 +1,9 @@ +use actix_multipart::MultipartError; +use actix_web::HttpRequest; +use log::error; +use actix_web::Error; + +pub fn handle_multipart_error(err: MultipartError, req: &HttpRequest) -> Error { + error!("Multipart error: {}", err); + Error::from(err) +} diff --git a/crates/service/web/storyteller_web/src/http_server/web_utils/mod.rs b/crates/service/web/storyteller_web/src/http_server/web_utils/mod.rs index dac4c5bf45..0124eb8b68 100644 --- a/crates/service/web/storyteller_web/src/http_server/web_utils/mod.rs +++ b/crates/service/web/storyteller_web/src/http_server/web_utils/mod.rs @@ -1,4 +1,5 @@ pub mod get_host_header; +pub mod handle_multipart_error; pub mod read_multipart_field_bytes; pub mod redis_rate_limiter; pub mod response_error_helpers; diff --git a/crates/service/web/storyteller_web/src/main.rs b/crates/service/web/storyteller_web/src/main.rs index 9e09f30d88..d89b612463 100644 --- a/crates/service/web/storyteller_web/src/main.rs +++ b/crates/service/web/storyteller_web/src/main.rs @@ -20,6 +20,7 @@ use std::sync::Arc; use std::time::Duration; +use actix_multipart::form::MultipartFormConfig; use actix_web::{App, HttpServer, middleware, web}; use actix_web::middleware::{DefaultHeaders, Logger}; @@ -77,6 +78,7 @@ use crate::billing::stripe_internal_user_lookup_impl::StripeInternalUserLookupIm use crate::configs::app_startup::redis_rate_limiters::configure_redis_rate_limiters; use crate::configs::static_api_tokens::StaticApiTokenSet; use crate::http_server::middleware::pushback_filter_middleware::PushbackFilter; +use crate::http_server::web_utils::handle_multipart_error::handle_multipart_error; use crate::memory_cache::model_token_to_info_cache::ModelTokenToInfoCache; use crate::routes::add_routes::add_routes; use crate::server_state::{DurableInMemoryCaches, EnvConfig, EphemeralInMemoryCaches, InMemoryCaches, ServerInfo, ServerState, StaticFeatureFlags, StripeSettings, TrollBans, TwitchOauth, TwitchOauthSecrets}; @@ -614,6 +616,13 @@ pub async fn serve(server_state: ServerState) -> AnyhowResult<()> .app_data(web::Data::from(user_lookup)) // NB: Data::from(Arc) for dynamic dispatch .app_data(web::Data::from(session_cache_purge)) // NB: Data::from(Arc) for dynamic dispatch .app_data(server_state_arc.clone()) + .app_data( + // NB: https://stackoverflow.com/a/78399675 + MultipartFormConfig::default() + .total_limit(10 *1024 * 1024 * 1024) // 10 GB + .memory_limit(10 * 1024 * 1024) // 10 MB + .error_handler(handle_multipart_error) + ) .wrap(build_cors_config(old_server_environment)) .wrap(shared_array_buffer_cors()) .wrap(DefaultHeaders::new()