diff --git a/rfd-api/src/endpoints/mod.rs b/rfd-api/src/endpoints/mod.rs index 00f79f75..bbd18b5f 100644 --- a/rfd-api/src/endpoints/mod.rs +++ b/rfd-api/src/endpoints/mod.rs @@ -4,6 +4,17 @@ pub static UNLIMITED: i64 = 9999999; +/// Default request body limit. Endpoints that accept larger bodies opt in explicitly. +pub const DEFAULT_REQUEST_BODY_MAX_BYTES: usize = 16 * 1024; + +/// Request body limit for endpoints that accept full RFD documents +pub const LARGE_REQUEST_BODY_MAX_BYTES: usize = 1024 * 1024; + +/// GitHub caps webhook payloads at 25 MB, but observed push payloads are far smaller. The +/// signature can only be checked after the body is read, so keep this limit conservative. +/// https://docs.github.com/en/webhooks/webhook-events-and-payloads#payload-cap +pub const WEBHOOK_REQUEST_BODY_MAX_BYTES: usize = 1024 * 1024; + pub mod job; pub mod rfd; pub mod webhook; diff --git a/rfd-api/src/endpoints/rfd.rs b/rfd-api/src/endpoints/rfd.rs index ec8c8bae..648271d0 100644 --- a/rfd-api/src/endpoints/rfd.rs +++ b/rfd-api/src/endpoints/rfd.rs @@ -28,7 +28,7 @@ use crate::{ RfdContext, RfdRevisionIdentifier, RfdRevisionMeta, RfdRevisionMetadataChange, RfdWithPdf, RfdWithRaw, RfdWithoutContent, }, - endpoints::UNLIMITED, + endpoints::{LARGE_REQUEST_BODY_MAX_BYTES, UNLIMITED}, permissions::RfdPermission, search::{MeiliSearchResult, SearchRequest}, util::response::{client_error, internal_error, not_implemented, unauthorized}, @@ -631,6 +631,7 @@ pub struct RfdUpdateBody { #[endpoint { method = POST, path = "/rfd/{number}/raw", + request_body_max_bytes = LARGE_REQUEST_BODY_MAX_BYTES, }] pub async fn set_rfd_document( rqctx: RequestContext, @@ -679,6 +680,7 @@ pub struct RfdUpdateContentBody { #[endpoint { method = POST, path = "/rfd/{number}/content", + request_body_max_bytes = LARGE_REQUEST_BODY_MAX_BYTES, }] pub async fn set_rfd_content( rqctx: RequestContext, diff --git a/rfd-api/src/endpoints/webhook.rs b/rfd-api/src/endpoints/webhook.rs index b5c5648c..ac8172fb 100644 --- a/rfd-api/src/endpoints/webhook.rs +++ b/rfd-api/src/endpoints/webhook.rs @@ -18,11 +18,12 @@ use serde::{Deserialize, Serialize}; use tracing::instrument; use uuid::Uuid; -use crate::{context::RfdContext, error::ApiError}; +use crate::{context::RfdContext, endpoints::WEBHOOK_REQUEST_BODY_MAX_BYTES, error::ApiError}; #[endpoint { method = POST, path = "/github", + request_body_max_bytes = WEBHOOK_REQUEST_BODY_MAX_BYTES, tags = ["hidden"], }] #[instrument( diff --git a/rfd-api/src/server.rs b/rfd-api/src/server.rs index b701b68b..e61dff62 100644 --- a/rfd-api/src/server.rs +++ b/rfd-api/src/server.rs @@ -26,6 +26,7 @@ use crate::{ view_rfd_revision_meta, view_rfd_revision_pdf, }, webhook::github_webhook, + DEFAULT_REQUEST_BODY_MAX_BYTES, }, permissions::RfdPermission, }; @@ -149,7 +150,7 @@ pub fn server( ) -> Result, Box> { let config_dropshot = ConfigDropshot { bind_address: config.server_address, - default_request_body_max_bytes: 1024 * 1024, + default_request_body_max_bytes: DEFAULT_REQUEST_BODY_MAX_BYTES, ..Default::default() };