Add admin configurable Access-Control-Allow-Origin.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-11-19 10:54:39 +00:00
parent b924412efb
commit 5260912c3b
3 changed files with 47 additions and 9 deletions

View File

@@ -2044,6 +2044,17 @@ pub struct Config {
#[serde(default)] #[serde(default)]
pub allow_invalid_tls_certificates: bool, pub allow_invalid_tls_certificates: bool,
/// Sets the `Access-Control-Allow-Origin` header included by this server in
/// all responses. A list of multiple values can be specified. The default
/// is an empty list. The actual header defaults to `*` upon an empty list.
///
/// There is no reason to configure this without specific intent. Incorrect
/// values may degrade or disrupt clients.
///
/// default: []
#[serde(default)]
pub access_control_allow_origin: BTreeSet<String>,
/// Backport state-reset security fixes to all room versions. /// Backport state-reset security fixes to all room versions.
/// ///
/// This option applies the State Resolution 2.1 mitigation developed during /// This option applies the State Resolution 2.1 mitigation developed during

View File

@@ -12,7 +12,7 @@ use http::{
use tower::ServiceBuilder; use tower::ServiceBuilder;
use tower_http::{ use tower_http::{
catch_panic::CatchPanicLayer, catch_panic::CatchPanicLayer,
cors::{self, CorsLayer}, cors::{AllowOrigin, CorsLayer},
sensitive_headers::SetSensitiveHeadersLayer, sensitive_headers::SetSensitiveHeadersLayer,
set_header::SetResponseHeaderLayer, set_header::SetResponseHeaderLayer,
timeout::{RequestBodyTimeoutLayer, ResponseBodyTimeoutLayer, TimeoutLayer}, timeout::{RequestBodyTimeoutLayer, ResponseBodyTimeoutLayer, TimeoutLayer},
@@ -138,30 +138,48 @@ fn compression_layer(server: &Server) -> tower_http::compression::CompressionLay
compression_layer compression_layer
} }
fn cors_layer(_server: &Server) -> CorsLayer { fn cors_layer(server: &Server) -> CorsLayer {
const METHODS: [Method; 7] = [ const METHODS: [Method; 7] = [
Method::DELETE,
Method::GET, Method::GET,
Method::HEAD, Method::HEAD,
Method::OPTIONS,
Method::PATCH, Method::PATCH,
Method::POST, Method::POST,
Method::PUT, Method::PUT,
Method::DELETE,
Method::OPTIONS,
]; ];
let headers: [HeaderName; 5] = [ let headers: [HeaderName; 5] = [
header::ORIGIN,
HeaderName::from_lowercase(b"x-requested-with").unwrap(),
header::CONTENT_TYPE,
header::ACCEPT, header::ACCEPT,
header::AUTHORIZATION, header::AUTHORIZATION,
header::CONTENT_TYPE,
header::ORIGIN,
HeaderName::from_lowercase(b"x-requested-with").unwrap(),
]; ];
let allow_origin_list = server
.config
.access_control_allow_origin
.iter()
.map(AsRef::as_ref)
.map(HeaderValue::from_str)
.filter_map(Result::ok);
let allow_origin = if !server
.config
.access_control_allow_origin
.is_empty()
{
AllowOrigin::list(allow_origin_list)
} else {
AllowOrigin::any()
};
CorsLayer::new() CorsLayer::new()
.allow_origin(cors::Any) .max_age(Duration::from_secs(86400))
.allow_methods(METHODS) .allow_methods(METHODS)
.allow_headers(headers) .allow_headers(headers)
.max_age(Duration::from_secs(86400)) .allow_origin(allow_origin)
} }
fn body_limit_layer(server: &Server) -> DefaultBodyLimit { fn body_limit_layer(server: &Server) -> DefaultBodyLimit {

View File

@@ -1754,6 +1754,15 @@
# #
#config_reload_signal = true #config_reload_signal = true
# Sets the `Access-Control-Allow-Origin` header included by this server in
# all responses. A list of multiple values can be specified. The default
# is an empty list. The actual header defaults to `*` upon an empty list.
#
# There is no reason to configure this without specific intent. Incorrect
# values may degrade or disrupt clients.
#
#access_control_allow_origin = []
# Backport state-reset security fixes to all room versions. # Backport state-reset security fixes to all room versions.
# #
# This option applies the State Resolution 2.1 mitigation developed during # This option applies the State Resolution 2.1 mitigation developed during