From d3bae7855c7244687af2ae2c379e7bc7f3c24d22 Mon Sep 17 00:00:00 2001 From: MasterPtato Date: Mon, 2 Feb 2026 16:20:32 -0800 Subject: [PATCH] chore(guard): centralize cors config --- .../packages/guard-core/src/proxy_service.rs | 22 +++++++++++++ .../guard-core/src/request_context.rs | 7 ++++ engine/packages/pegboard-gateway/src/lib.rs | 32 +++++++++---------- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/engine/packages/guard-core/src/proxy_service.rs b/engine/packages/guard-core/src/proxy_service.rs index 96b3c216b2..a63f53c6ca 100644 --- a/engine/packages/guard-core/src/proxy_service.rs +++ b/engine/packages/guard-core/src/proxy_service.rs @@ -581,6 +581,28 @@ impl ProxyService { HeaderValue::from_str(&cors.expose_headers)?, ); + if let Some(allow_methods) = &cors.allow_methods { + headers.insert( + "access-control-allow-methods", + HeaderValue::from_str(allow_methods)?, + ); + } + + if let Some(allow_headers) = &cors.allow_headers { + headers.insert( + "access-control-allow-headers", + HeaderValue::from_str(allow_headers)?, + ); + } + + if let Some(max_age) = &cors.max_age { + headers.insert( + "access-control-max-age", + HeaderValue::from_str(&max_age.to_string())?, + ); + } + + // Add Vary header to prevent cache poisoning when echoing origin if cors.allow_origin != "*" { headers.insert("vary", HeaderValue::from_static("Origin")); } diff --git a/engine/packages/guard-core/src/request_context.rs b/engine/packages/guard-core/src/request_context.rs index 63c9b8a4bd..7fd8a228b3 100644 --- a/engine/packages/guard-core/src/request_context.rs +++ b/engine/packages/guard-core/src/request_context.rs @@ -150,4 +150,11 @@ pub struct CorsConfig { pub allow_origin: String, pub allow_credentials: bool, pub expose_headers: String, + + // Only set for OPTIONS requests + // TODO: Vec of Method + pub allow_methods: Option, + pub allow_headers: Option, + // Seconds + pub max_age: Option, } diff --git a/engine/packages/pegboard-gateway/src/lib.rs b/engine/packages/pegboard-gateway/src/lib.rs index 88d6b9b932..7d7181f348 100644 --- a/engine/packages/pegboard-gateway/src/lib.rs +++ b/engine/packages/pegboard-gateway/src/lib.rs @@ -132,24 +132,18 @@ impl PegboardGateway { .and_then(|v| v.to_str().ok()) .unwrap_or("*"); - let mut response = Response::builder() + req_ctx.set_cors(CorsConfig { + allow_origin: origin.clone(), + allow_credentials: true, + expose_headers: "*".to_string(), + allow_methods: Some("GET, POST, PUT, DELETE, OPTIONS, PATCH".to_string()), + allow_headers: Some(requested_headers.to_string()), + max_age: Some(86400), + }); + + return Ok(Response::builder() .status(StatusCode::NO_CONTENT) - .header("access-control-allow-origin", &origin) - .header("access-control-allow-credentials", "true") - .header( - "access-control-allow-methods", - "GET, POST, PUT, DELETE, OPTIONS, PATCH", - ) - .header("access-control-allow-headers", requested_headers) - .header("access-control-expose-headers", "*") - .header("access-control-max-age", "86400"); - - // Add Vary header to prevent cache poisoning when echoing origin - if origin != "*" { - response = response.header("vary", "Origin"); - } - - return Ok(response.body(ResponseBody::Full(Full::new(Bytes::new())))?); + .body(ResponseBody::Full(Full::new(Bytes::new())))?); } // Set CORS headers through guard @@ -157,6 +151,10 @@ impl PegboardGateway { allow_origin: origin.clone(), allow_credentials: true, expose_headers: "*".to_string(), + // Not an options req, not required + allow_methods: None, + allow_headers: None, + max_age: None, }); let body_bytes = req