Skip to content

Commit 1956b56

Browse files
author
Gary Pennington
authored
migrate cors configuration from server to top level (#1586)
from: ``` server: cors: ``` to: ``` cors: ``` fixes: #1483
1 parent f48ccc7 commit 1956b56

14 files changed

+262
-289
lines changed

NEXT_CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ By [@USERNAME](https://github.com/USERNAME) in https://github.com/apollographql/
2727

2828
## ❗ BREAKING ❗
2929

30+
### Move cors configuration from `server` to top level ([PR #1586](https://github.com/apollographql/router/pull/1586))
31+
32+
The cors configuration is now located at the top level of the configuration file.
33+
34+
By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/1586
35+
3036
### Exit the router after logging panic details ([PR #1602](https://github.com/apollographql/router/pull/1602))
3137

3238
If the router panics, it can leave the router in an unuseable state.

apollo-router/src/axum_http_server_factory.rs

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,9 @@ pub(crate) fn make_axum_router<RF>(
8787
where
8888
RF: SupergraphServiceFactory,
8989
{
90-
let cors = configuration
91-
.server
92-
.cors
93-
.clone()
94-
.into_layer()
95-
.map_err(|e| {
96-
ApolloRouterError::ServiceCreationError(format!("CORS configuration error: {e}").into())
97-
})?;
90+
let cors = configuration.cors.clone().into_layer().map_err(|e| {
91+
ApolloRouterError::ServiceCreationError(format!("CORS configuration error: {e}").into())
92+
})?;
9893
let graphql_endpoint = if configuration.server.endpoint.ends_with("/*") {
9994
// Needed for axum (check the axum docs for more information about wildcards https://docs.rs/axum/latest/axum/struct.Router.html#wildcards)
10095
format!("{}router_extra_path", configuration.server.endpoint)
@@ -1268,14 +1263,14 @@ mod tests {
12681263
))
12691264
});
12701265
let conf = Configuration::builder()
1266+
.cors(
1267+
Cors::builder()
1268+
.origins(vec!["http://studio".to_string()])
1269+
.build(),
1270+
)
12711271
.server(
12721272
crate::configuration::Server::builder()
12731273
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
1274-
.cors(
1275-
Cors::builder()
1276-
.origins(vec!["http://studio".to_string()])
1277-
.build(),
1278-
)
12791274
.endpoint(String::from("/graphql"))
12801275
.build(),
12811276
)
@@ -1337,14 +1332,14 @@ mod tests {
13371332
))
13381333
});
13391334
let conf = Configuration::builder()
1335+
.cors(
1336+
Cors::builder()
1337+
.origins(vec!["http://studio".to_string()])
1338+
.build(),
1339+
)
13401340
.server(
13411341
crate::configuration::Server::builder()
13421342
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
1343-
.cors(
1344-
Cors::builder()
1345-
.origins(vec!["http://studio".to_string()])
1346-
.build(),
1347-
)
13481343
.endpoint(String::from("/:my_prefix/graphql"))
13491344
.build(),
13501345
)
@@ -1406,14 +1401,14 @@ mod tests {
14061401
))
14071402
});
14081403
let conf = Configuration::builder()
1404+
.cors(
1405+
Cors::builder()
1406+
.origins(vec!["http://studio".to_string()])
1407+
.build(),
1408+
)
14091409
.server(
14101410
crate::configuration::Server::builder()
14111411
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
1412-
.cors(
1413-
Cors::builder()
1414-
.origins(vec!["http://studio".to_string()])
1415-
.build(),
1416-
)
14171412
.endpoint(String::from("/graphql/*"))
14181413
.build(),
14191414
)
@@ -1629,10 +1624,10 @@ mod tests {
16291624
async fn cors_preflight() -> Result<(), ApolloRouterError> {
16301625
let expectations = MockSupergraphService::new();
16311626
let conf = Configuration::builder()
1627+
.cors(Cors::builder().build())
16321628
.server(
16331629
crate::configuration::Server::builder()
16341630
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
1635-
.cors(Cors::builder().build())
16361631
.endpoint(String::from("/graphql/*"))
16371632
.build(),
16381633
)
@@ -1855,14 +1850,14 @@ Content-Type: application/json\r
18551850
async fn it_doesnt_display_disabled_home_page() -> Result<(), ApolloRouterError> {
18561851
let expectations = MockSupergraphService::new();
18571852
let conf = Configuration::builder()
1853+
.cors(
1854+
Cors::builder()
1855+
.origins(vec!["http://studio".to_string()])
1856+
.build(),
1857+
)
18581858
.server(
18591859
crate::configuration::Server::builder()
18601860
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
1861-
.cors(
1862-
Cors::builder()
1863-
.origins(vec!["http://studio".to_string()])
1864-
.build(),
1865-
)
18661861
.landing_page(false)
18671862
.build(),
18681863
)
@@ -1901,14 +1896,14 @@ Content-Type: application/json\r
19011896
);
19021897

19031898
let conf = Configuration::builder()
1899+
.cors(
1900+
Cors::builder()
1901+
.origins(vec!["http://studio".to_string()])
1902+
.build(),
1903+
)
19041904
.server(
19051905
crate::configuration::Server::builder()
19061906
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
1907-
.cors(
1908-
Cors::builder()
1909-
.origins(vec!["http://studio".to_string()])
1910-
.build(),
1911-
)
19121907
.build(),
19131908
)
19141909
.build();
@@ -2044,10 +2039,10 @@ Content-Type: application/json\r
20442039
#[tokio::test]
20452040
async fn cors_allow_any_origin() -> Result<(), ApolloRouterError> {
20462041
let conf = Configuration::builder()
2042+
.cors(Cors::builder().allow_any_origin(true).build())
20472043
.server(
20482044
crate::configuration::Server::builder()
20492045
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
2050-
.cors(Cors::builder().allow_any_origin(true).build())
20512046
.build(),
20522047
)
20532048
.build();
@@ -2067,14 +2062,14 @@ Content-Type: application/json\r
20672062
let valid_origin = "https://thisoriginisallowed.com";
20682063

20692064
let conf = Configuration::builder()
2065+
.cors(
2066+
Cors::builder()
2067+
.origins(vec![valid_origin.to_string()])
2068+
.build(),
2069+
)
20702070
.server(
20712071
crate::configuration::Server::builder()
20722072
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
2073-
.cors(
2074-
Cors::builder()
2075-
.origins(vec![valid_origin.to_string()])
2076-
.build(),
2077-
)
20782073
.build(),
20792074
)
20802075
.build();
@@ -2097,15 +2092,15 @@ Content-Type: application/json\r
20972092
let apollo_subdomains = "https://([a-z0-9]+[.])*apollographql[.]com";
20982093

20992094
let conf = Configuration::builder()
2095+
.cors(
2096+
Cors::builder()
2097+
.origins(vec!["https://anexactmatchorigin.com".to_string()])
2098+
.match_origins(vec![apollo_subdomains.to_string()])
2099+
.build(),
2100+
)
21002101
.server(
21012102
crate::configuration::Server::builder()
21022103
.listen(SocketAddr::from_str("127.0.0.1:0").unwrap())
2103-
.cors(
2104-
Cors::builder()
2105-
.origins(vec!["https://anexactmatchorigin.com".to_string()])
2106-
.match_origins(vec![apollo_subdomains.to_string()])
2107-
.build(),
2108-
)
21092104
.build(),
21102105
)
21112106
.build();

apollo-router/src/configuration/mod.rs

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ pub struct Configuration {
6868
#[serde(default)]
6969
pub(crate) server: Server,
7070

71+
/// Cross origin request headers.
72+
#[serde(default)]
73+
pub(crate) cors: Cors,
74+
7175
/// Plugin configuration
7276
#[serde(default)]
7377
plugins: UserPlugins,
@@ -90,11 +94,13 @@ impl Configuration {
9094
#[builder]
9195
pub(crate) fn new(
9296
server: Option<Server>,
97+
cors: Option<Cors>,
9398
plugins: Map<String, Value>,
9499
apollo_plugins: Map<String, Value>,
95100
) -> Self {
96101
Self {
97102
server: server.unwrap_or_default(),
103+
cors: cors.unwrap_or_default(),
98104
plugins: UserPlugins {
99105
plugins: Some(plugins),
100106
},
@@ -246,10 +252,6 @@ pub(crate) struct Server {
246252
#[serde(default = "default_listen")]
247253
pub(crate) listen: ListenAddr,
248254

249-
/// Cross origin request headers.
250-
#[serde(default)]
251-
pub(crate) cors: Cors,
252-
253255
/// introspection queries
254256
/// enabled by default
255257
#[serde(default = "default_introspection")]
@@ -287,7 +289,6 @@ impl Server {
287289
#[allow(clippy::too_many_arguments)] // Used through a builder, not directly
288290
pub(crate) fn new(
289291
listen: Option<ListenAddr>,
290-
cors: Option<Cors>,
291292
introspection: Option<bool>,
292293
landing_page: Option<bool>,
293294
endpoint: Option<String>,
@@ -297,7 +298,6 @@ impl Server {
297298
) -> Self {
298299
Self {
299300
listen: listen.unwrap_or_else(default_listen),
300-
cors: cors.unwrap_or_default(),
301301
introspection: introspection.unwrap_or_else(default_introspection),
302302
landing_page: landing_page.unwrap_or_else(default_landing_page),
303303
endpoint: endpoint.unwrap_or_else(default_endpoint),
@@ -1145,8 +1145,8 @@ server:
11451145
# The socket address and port to listen on
11461146
# Defaults to 127.0.0.1:4000
11471147
listen: 127.0.0.1:4000
1148-
cors:
1149-
allow_headers: [ Content-Type, 5 ]
1148+
cors:
1149+
allow_headers: [ Content-Type, 5 ]
11501150
"#,
11511151
)
11521152
.expect_err("should have resulted in an error");
@@ -1161,10 +1161,10 @@ server:
11611161
# The socket address and port to listen on
11621162
# Defaults to 127.0.0.1:4000
11631163
listen: 127.0.0.1:4000
1164-
cors:
1165-
allow_headers:
1166-
- Content-Type
1167-
- 5
1164+
cors:
1165+
allow_headers:
1166+
- Content-Type
1167+
- 5
11681168
"#,
11691169
)
11701170
.expect_err("should have resulted in an error");
@@ -1175,15 +1175,13 @@ server:
11751175
fn it_does_not_allow_invalid_cors_headers() {
11761176
let cfg = validate_configuration(
11771177
r#"
1178-
server:
1179-
cors:
1180-
allow_credentials: true
1181-
allow_headers: [ "*" ]
1178+
cors:
1179+
allow_credentials: true
1180+
allow_headers: [ "*" ]
11821181
"#,
11831182
)
11841183
.expect("should not have resulted in an error");
11851184
let error = cfg
1186-
.server
11871185
.cors
11881186
.into_layer()
11891187
.expect_err("should have resulted in an error");
@@ -1194,15 +1192,13 @@ server:
11941192
fn it_does_not_allow_invalid_cors_methods() {
11951193
let cfg = validate_configuration(
11961194
r#"
1197-
server:
1198-
cors:
1199-
allow_credentials: true
1200-
methods: [ GET, "*" ]
1195+
cors:
1196+
allow_credentials: true
1197+
methods: [ GET, "*" ]
12011198
"#,
12021199
)
12031200
.expect("should not have resulted in an error");
12041201
let error = cfg
1205-
.server
12061202
.cors
12071203
.into_layer()
12081204
.expect_err("should have resulted in an error");
@@ -1213,15 +1209,13 @@ server:
12131209
fn it_does_not_allow_invalid_cors_origins() {
12141210
let cfg = validate_configuration(
12151211
r#"
1216-
server:
1217-
cors:
1218-
allow_credentials: true
1219-
allow_any_origin: true
1212+
cors:
1213+
allow_credentials: true
1214+
allow_any_origin: true
12201215
"#,
12211216
)
12221217
.expect("should not have resulted in an error");
12231218
let error = cfg
1224-
.server
12251219
.cors
12261220
.into_layer()
12271221
.expect_err("should have resulted in an error");
@@ -1307,8 +1301,8 @@ server:
13071301
# The socket address and port to listen on
13081302
# Defaults to 127.0.0.1:4000
13091303
listen: 127.0.0.1:4000
1310-
cors:
1311-
allow_headers: [ Content-Type, "${TEST_CONFIG_NUMERIC_ENV_UNIQUE}" ]
1304+
cors:
1305+
allow_headers: [ Content-Type, "${TEST_CONFIG_NUMERIC_ENV_UNIQUE}" ]
13121306
"#,
13131307
)
13141308
.expect_err("should have resulted in an error");
@@ -1325,10 +1319,10 @@ server:
13251319
# The socket address and port to listen on
13261320
# Defaults to 127.0.0.1:4000
13271321
listen: 127.0.0.1:4000
1328-
cors:
1329-
allow_headers:
1330-
- Content-Type
1331-
- "${TEST_CONFIG_NUMERIC_ENV_UNIQUE:true}"
1322+
cors:
1323+
allow_headers:
1324+
- Content-Type
1325+
- "${TEST_CONFIG_NUMERIC_ENV_UNIQUE:true}"
13321326
"#,
13331327
)
13341328
.expect_err("should have resulted in an error");

apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__line_precise_config_errors_with_inline_sequence.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ source: apollo-router/src/configuration/mod.rs
33
expression: error.to_string()
44
---
55
configuration had errors:
6-
1. /server/cors/allow_headers/1
6+
1. /cors/allow_headers/1
77

88
# The socket address and port to listen on
99
# Defaults to 127.0.0.1:4000
1010
listen: 127.0.0.1:4000
11-
cors:
12-
allow_headers: [ Content-Type, 5 ]
13-
^----- 5 is not of type "string"
11+
cors:
12+
allow_headers: [ Content-Type, 5 ]
13+
^----- 5 is not of type "string"

apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__line_precise_config_errors_with_inline_sequence_env_expansion.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ source: apollo-router/src/configuration/mod.rs
33
expression: error.to_string()
44
---
55
configuration had errors:
6-
1. /server/cors/allow_headers/1
6+
1. /cors/allow_headers/1
77

88
# The socket address and port to listen on
99
# Defaults to 127.0.0.1:4000
1010
listen: 127.0.0.1:4000
11-
cors:
12-
allow_headers: [ Content-Type, "${TEST_CONFIG_NUMERIC_ENV_UNIQUE}" ]
13-
^----- "${TEST_CONFIG_NUMERIC_ENV_UNIQUE}" is not of type "string"
11+
cors:
12+
allow_headers: [ Content-Type, "${TEST_CONFIG_NUMERIC_ENV_UNIQUE}" ]
13+
^----- "${TEST_CONFIG_NUMERIC_ENV_UNIQUE}" is not of type "string"

0 commit comments

Comments
 (0)