-
-
Notifications
You must be signed in to change notification settings - Fork 254
feat(martin-server): add support for basic CORS configuration #1815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
enable/disable in config file uses same defaults as before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces configurable CORS support to the Martin server while preserving existing default behavior. Key changes include:
- Adding a new CorsConfig and its make_cors_middleware method.
- Updating server.rs to conditionally apply CORS middleware based on configuration.
- Incorporating new tests and updating configuration documentation.
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
martin/tests/cors_test.rs | Added tests to validate the new CORS configuration behavior. |
martin/src/srv/server.rs | Updated middleware setup to wrap the app conditionally with the CORS middleware. |
martin/src/srv/mod.rs | Imported the new CORS module. |
martin/src/srv/cors.rs | Introduced CorsConfig struct with middleware creation logic for CORS handling. |
martin/src/srv/config.rs | Integrated CorsConfig into SrvConfig and added a YAML parsing test for CORS settings. |
docs/src/config-file.md | Updated the configuration documentation to include CORS setup examples. |
Comments suppressed due to low confidence (2)
docs/src/config-file.md:53
- The configuration documentation uses 'allowed_origins' while the code uses 'origin'. Consider aligning these names for consistency.
allowed_origins:
martin/src/srv/cors.rs:8
- Consider renaming the field 'origin' to 'allowed_origins' to match the configuration documentation and improve clarity.
pub origin: Vec<String>,
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
The PR adds configurable CORS support to the martin-server, ensuring backward compatibility while allowing deployment-specific CORS configuration via the server config and YAML file. It also includes updated tests and documentation for the new CORS feature.
- Introduces a new CorsConfig with middleware generation in its own module.
- Updates the server initialization to conditionally wrap the app with CORS middleware based on configuration.
- Adds relevant tests and documentation for the configurable CORS settings.
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
martin/tests/cors_test.rs | Adds tests to verify CORS behavior under various configurations. |
martin/src/srv/server.rs | Updates server creation to use the new configurable CORS middleware. |
martin/src/srv/mod.rs | Registers the new CORS module. |
martin/src/srv/cors.rs | Implements CorsConfig and middleware generation logic. |
martin/src/srv/config.rs | Updates SrvConfig to include CorsConfig and tests YAML parsing. |
docs/src/config-file.md | Enhances documentation with new CORS configuration options. |
Comments suppressed due to low confidence (1)
martin/src/srv/server.rs:187
- [nitpick] Consider caching the result of cors_middleware.unwrap_or_default() in a variable to avoid calling it twice, which can improve readability and reduce the chance of future errors if the unwrap logic evolves.
app.wrap(Condition::new(cors_middleware.is_some(), cors_middleware.unwrap_or_default(),))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request adds configurable CORS support to the Martin server while preserving existing functionality. The changes include updating the server to conditionally apply CORS middleware based on configuration, introducing the new cors module for middleware generation, and adding tests and documentation for the new CORS settings.
- Integrates CORS middleware creation in the server setup.
- Adds new tests to verify different CORS configurations.
- Updates the configuration parsing and docs to include CORS settings.
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
martin/tests/cors_test.rs | Adds tests for verifying behavior when CORS is enabled/disabled or set with a specific origin. |
martin/src/srv/server.rs | Refactors server initialization to derive and conditionally apply CORS middleware. |
martin/src/srv/mod.rs | Registers the new cors module for managing CORS configuration. |
martin/src/srv/cors.rs | Implements the CorsConfig structure and middleware generation method. |
martin/src/srv/config.rs | Updates configuration parsing to include optional CORS settings. |
docs/src/config-file.md | Documents the new CORS configuration options. |
docs/src/config-file.md
Outdated
# CORS configuration | ||
cors: | ||
# enable/disable CORS [default: true] | ||
enable: true | ||
# sets the Access-Control-Allow-Origin header [default: *] | ||
# '*' will use the requests ORIGIN header | ||
origin: | ||
- https://example.org | ||
# sets Access-Control-Max-Age Header. Remove to use default. [default: None] | ||
max_age: 3600 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly, this is great work ❤️
I don't quite like the enable: true
part of the config.
If CORS is entirely unconfigured, the rest of the options don't quite make sense.
What about below?
# CORS configuration | |
cors: | |
# enable/disable CORS [default: true] | |
enable: true | |
# sets the Access-Control-Allow-Origin header [default: *] | |
# '*' will use the requests ORIGIN header | |
origin: | |
- https://example.org | |
# sets Access-Control-Max-Age Header. Remove to use default. [default: None] | |
max_age: 3600 | |
# CORS configuration | |
# | |
# Can also be disabled via `cors: false` | |
cors: | |
# Sets the Access-Control-Allow-Origin header [default: *] | |
# '*' will use the requests ORIGIN header | |
origin: | |
- https://example.org | |
# Sets Access-Control-Max-Age Header. [default: null] | |
# null means not seting the header | |
max_age: 3600 |
(And changing the CorsConfig
to be an enum and with #[serde(transparent)]
on the variant with configuration)
adds a few more tests (e.g for CORS preflight requests -> max-age)
for more information, see https://pre-commit.ci
.gitignore
Outdated
@@ -23,3 +23,4 @@ tmp/ | |||
#### | |||
#### Above content must match .dockerignore #### | |||
#### | |||
.aider* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please move this above the comment, and also add it to the .dockerignore
@@ -44,6 +44,17 @@ preferred_encoding: gzip | |||
# Enable or disable Martin web UI. At the moment, only allows `enable-for-all` which enables the web UI for all connections. This may be undesirable in a production environment. [default: disable] | |||
web_ui: disable | |||
|
|||
# CORS Configuration | |||
# Can also be disabled via `cors: false` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to document what does true
means, and what happens if not set at all (default). Note that default here and in sub-items is a bit confusing, i.e. does cors: {}
equal to cors: ~
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point - i'll expand on that and double check what happens. might even add some tests
never seen ~
or {}
in the wild though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now, both cors: {}
and cors: ~
seem to enable CORS using our defaults.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As it stands right now, it'll always fall back to the defaults.
- no
cors
option at all -> Enable using defaults cors: true
-> Enable using defaults- only configuring a subset and omitting certain properties-> use defaults for properties that are not explicitly set.
this...
cors:
max_age: 3600
would translate to this:
cors:
origin: ["*"]
max_age: 3600
The only way to disable CORS right now, is to explicitly set cors: false
.
I guess cors: ~
should also disable it? What would you prefer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, null is the same as skipped, so it should be the default
# CORS Configuration | ||
# Can also be disabled via `cors: false` | ||
cors: | ||
# Sets the `Access-Control-Allow-Origin` header [default: *] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to double check -- does the default of *
mean exactly the same as the current default behavior - i.e. allow all? I.e. currently it "will use the requests ORIGIN
header" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, "will use the requests ORIGIN header", is the current default .
docs.rs
send_wildcard()
is disabled by default in actix_cors
.
When all origins are allowed and send_wildcard is set, * will be sent in the Access-Control-Allow-Origin response header. If send_wildcard is not set, the client’s Origin request header will be echoed back in the Access-Control-Allow-Origin response header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To expand on this a bit, this is the current CORS initialization on main
:
let cors_middleware = Cors::default()
.allow_any_origin()
.allowed_methods(vec!["GET"]);
default()
: sets restrictive defaults
No allowed origins, methods, request headers or exposed headers. Credentials
not supported. No max age (will use browser's default).allow_any_origin()
: allows any origin, either by returning*
in the header or by just returning the requestsORIGIN
(this is the default in actix_cors assend_wildcard()
is NOT enabled). .allowed_methods(vec!["GET"])
setsAccess-Control-Allow-Methods
, only used in OPTIONS/preflight requests.
This PR keeps the exact same defaults for now, but allows disabling CORS altogether and dynamically setting ACCESS_CONTROL_ALLOW_ORIGIN
and ACCESS_CONTROL_MAX_AGE
.
If the defaults were to change at some point (this would be a breaking change), we could think about making it a bit more restrictive by default.
Maybe enable CORS by default, but require users to set specific origins. This would also ensure that an informed decision is made when opting out of "security" by allowing any origin or disabling it.
As mentioned in #931, I've tried to come up with a basic implementation/spec which allows configuration of CORS..
Before:
Static CORS configuration in
server.rs
.This translates to the following logic:
Origin
Header, the value of this Headers is used to setAccess-Control-Allow-Origin
(not*
)Origin
Header,Access-Control-Allow-Origin
is not set, howevervary
headers are still being sentAfter:
GET
methods allowed). There should be no breaking changes for existing deployments.Adds tests for CORS
Config is nested under
SrvConfig
. I think this is fitting, as it's not a source.Let me know if you have any suggestions, changes that should be applied or if you'd like to take this over. 🦀
@CommanderStorm im gonna ping you here, hope that's okay