Skip to main content

ordinary_config/http/
cors.rs

1// Copyright (C) 2026 The Ordinary Authors.
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5use serde::{Deserialize, Serialize};
6
7#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
8#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
9#[derive(Deserialize, Serialize, Debug, Clone)]
10pub enum HttpCorsAllowHeaders {
11    Any,
12    /// <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers>
13    Headers(Vec<String>),
14}
15
16#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
17#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
18#[derive(Deserialize, Serialize, Debug, Clone)]
19pub enum HttpCorsExposeHeaders {
20    Any,
21    /// <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers>
22    Headers(Vec<String>),
23}
24
25#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
26#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
27#[derive(Deserialize, Serialize, Debug, Clone)]
28pub enum HttpCorsAllowMethods {
29    Any,
30    /// <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods>
31    Methods(Vec<String>),
32}
33
34#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
35#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
36#[derive(Deserialize, Serialize, Debug, Clone)]
37pub enum HttpCorsAllowOrigin {
38    Any,
39    /// <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin>
40    Origins(Vec<String>),
41}
42
43#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
44#[cfg_attr(feature = "docs", derive(schemars::JsonSchema))]
45#[derive(Deserialize, Serialize, Debug, Clone, Default)]
46pub struct HttpCors {
47    pub allow_credentials: Option<bool>,
48
49    pub allow_headers: Option<HttpCorsAllowHeaders>,
50
51    /// unit: Seconds
52    pub max_age: Option<u32>,
53
54    pub allow_methods: Option<HttpCorsAllowMethods>,
55
56    pub allow_origin: Option<HttpCorsAllowOrigin>,
57
58    pub expose_headers: Option<HttpCorsExposeHeaders>,
59
60    pub allow_private_network: Option<bool>,
61}
62
63impl HttpCors {
64    #[must_use]
65    pub fn overwrite(&self, base: &Self) -> Self {
66        Self {
67            allow_credentials: if self.allow_credentials.is_none() {
68                base.allow_credentials
69            } else {
70                self.allow_credentials
71            },
72            allow_headers: if self.allow_headers.is_none() {
73                base.allow_headers.clone()
74            } else {
75                self.allow_headers.clone()
76            },
77            max_age: if self.max_age.is_none() {
78                base.max_age
79            } else {
80                self.max_age
81            },
82            allow_methods: if self.allow_methods.is_none() {
83                base.allow_methods.clone()
84            } else {
85                self.allow_methods.clone()
86            },
87            allow_origin: if self.allow_origin.is_none() {
88                base.allow_origin.clone()
89            } else {
90                self.allow_origin.clone()
91            },
92            expose_headers: if self.expose_headers.is_none() {
93                base.expose_headers.clone()
94            } else {
95                self.expose_headers.clone()
96            },
97            allow_private_network: if self.allow_private_network.is_none() {
98                base.allow_private_network
99            } else {
100                self.allow_private_network
101            },
102        }
103    }
104}