-
Notifications
You must be signed in to change notification settings - Fork 564
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
Add CORS support for SE and MP applications to 2.x #1633
Conversation
…notation. Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
… for compatibility. Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
…er types of requests. Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericas-Geertsen <santiago.pericasgeertsen@oracle.com>
Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com>
…quests and responses
… request() method to RequestAdapter
The header abstraction can just be Maybe the shared API could be something like this? CorsResult CorsSupport.processRequest(String path, Map<String,List<String>> headers);
class CorsResult {
Map<String,List<String>> headers;
int status;
String message;
} BTW, it is possible to inject the SE request and response in the filter ? maybe that removes the need for an abstraction. |
…; also remove the need for the 'internal' subpackage
Re: your latest, Romain...
|
At least for the MP scenario, the input map would not require copying headers into a new map. The result map would contain the headers to set, so I was thinking the cost would be minimal. I guess this is the cost of a no-side-effect function: the return value needs to be passed back to the caller.
I meant the first scenario.
The key difference between the two is that one returns a value and does not have side effects, where-as the other one does not have a return value but works by creating side-effects. The no-side-effect approach is simpler with a minor extra cost (few more objects). |
I missed that I agree that there certainly are ways to avoid having the two adapters. I guess I am not convinced it's worth it. With the latest refactoring earlier today they are not public, so we are not committed to supporting them. I understand the advantages of devising more broadly useful adapters which other components could use, but let's not delay this PR for that unification to take place. We could revisit that later on and do some refactoring in CORS as needed. I will spend a little time looking into exactly what the full adapter-less API might look like. First I need to follow up on some other things Joe brought up earlier today. |
…late a CORSSupportSE from config, typically for use as a handler passed to Routing.Rules methods
I spent some time trying to work on a usable abstraction for headers that would work with both SE and MP, but it actually added code and complexity over the code in the PR. So at least for now I've kept the request and response adapter approach. The latest push involves significant refactoring. It also contains changes that make it quite easy for SE developers to load CORS set-up from a config file and apply that to endpoints with But we still support the path-included format for MP support. |
microprofile/cors/src/main/java/io/helidon/microprofile/cors/CORSSupportMP.java
Outdated
Show resolved
Hide resolved
microprofile/cors/src/main/java/io/helidon/microprofile/cors/CORSSupportMP.java
Outdated
Show resolved
Hide resolved
microprofile/cors/src/main/java/io/helidon/microprofile/cors/CrossOriginAutoDiscoverable.java
Show resolved
Hide resolved
microprofile/cors/src/main/java/io/helidon/microprofile/cors/CrossOriginAutoDiscoverable.java
Outdated
Show resolved
Hide resolved
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
cors.paths.0.path-prefix=/cors3 |
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.
In MP - shouldn't we map this to resource class and resource method?
Maybe the approach of fully qualified classname + method name + CORS parameters would be easier for MP users?
Such as:
io.helidon.microprofile.cors.CrossOriginTest.CorsResource2.options.value=http://foo.bar,http://bar.foo
io.helidon.microprofile.cors.CrossOriginTest.CorsResource2.options.allowHeaders=X-foo,X-bar
io.helidon.microprofile.cors.CrossOriginTest.CorsResource2.options.allowMethods=DELETE,PUT
io.helidon.microprofile.cors.CrossOriginTest.CorsResource2.options.allowCredentials=true
io.helidon.microprofile.cors.CrossOriginTest.CorsResource2.options.maxAge=-1
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.
The existing format has several advantages:
- Much less verbose.
- Immune to refactoring of the code.
- Supports use cases that the alternative does not. (see below)
- Matches more closely to the mental model for the person setting up the configuration.
The existing format allows path expressions for the path. This lets users easily configure multiple related endpoints in one CORS setting, including using a single entry for the entire app (which seems to be what's often done in the wild).
Also, the alternative described here does not allow for one resource to have multiple endpoints at different paths with the same HTTP method. To support that the alternative format would have to also include either the Java method name or the URI path. In that case why not just use path expressions as in the existing format?
Paths are likely to be more stable than implementation packages and class names because paths are used externally; code is subject to refactoring.
microprofile/cors/src/main/java/io/helidon/microprofile/cors/CrossOrigin.java
Show resolved
Hide resolved
webserver/cors/src/main/java/io/helidon/webserver/cors/LogHelper.java
Outdated
Show resolved
Hide resolved
webserver/cors/src/main/java/io/helidon/webserver/cors/LogHelper.java
Outdated
Show resolved
Hide resolved
webserver/cors/src/main/java/io/helidon/webserver/cors/MappedCrossOriginConfig.java
Outdated
Show resolved
Hide resolved
webserver/cors/src/main/java/io/helidon/webserver/cors/MappedCrossOriginConfig.java
Outdated
Show resolved
Hide resolved
…ackage-local also
…lement interface methods remain public
…further clean-up of builder/config/'from'
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.
If it is possible to register cors on the root, such as:
routing.register(CorsSupport.create(config.get("cors"))
.register("/greet", new GreetService);
where the "cors" configuration takes care of all the paths of this webserver, then LGTM.
Resolves #931 (adding CORS support to the built-in Helidon services will be separate)
This PR refactors lots of earlier MP work into SE and builds on that to support CORS for SE applications. The previous MP code was also changed to layer on CORS SE.
See the SE
package-info.java
file where I captured -- at least for the moment -- quite a bit of how-to information from the SE developer's perspective.Brief overview:
SE:
CrossOriginHelper
does most of the heavy lifting. Much of this was harvested from the earlier MP-only work and refactored. This class does all the header checking and addition needed to implement CORS. It ispublic
so the MP module can see it but developers should not use it themselves. (They should not need to.) This class also defines very simple abstractions of HTTP requests and responses which SE and MP implement separately.CrossOriginConfig
represents the information we need to make CORS work for a given endpoint: allowed origins, allowed methods, etc.CORSSupport
is the SE developer's entry point to CORS. An instance behaves as both a service and a handler so developers can pass it toRouting.Rules#register
and also the various method-specific methods (any
,put
,get
, etc.).MP:
CrossOrigin
is the annotation which MP developers can use on their JAX-RSoptions
method to set up CORS.CrossOriginFilter
is invoked as requests arrive at endpoints annotated with@CrossOrigin
and as response flow back. It relies heavily on the SE classCrossOriginHelper
.