forked from helidon-io/helidon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add CORS support for SE and MP applications to 2.x (helidon-io#1633)
- Loading branch information
Showing
41 changed files
with
4,777 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
Copyright (c) 2019, 2020 Oracle and/or its affiliates. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>io.helidon.microprofile</groupId> | ||
<artifactId>helidon-microprofile-project</artifactId> | ||
<version>2.0.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>helidon-microprofile-cors</artifactId> | ||
<name>Helidon Microprofile CORS</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>javax.ws.rs</groupId> | ||
<artifactId>javax.ws.rs-api</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.helidon.jersey</groupId> | ||
<artifactId>helidon-jersey-common</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.helidon.webserver</groupId> | ||
<artifactId>helidon-webserver</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.helidon.webserver</groupId> | ||
<artifactId>helidon-webserver-jersey</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.helidon.microprofile.config</groupId> | ||
<artifactId>helidon-microprofile-config</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.helidon.webserver</groupId> | ||
<artifactId>helidon-webserver-cors</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.helidon.microprofile.bundles</groupId> | ||
<artifactId>internal-test-libs</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.helidon.microprofile.server</groupId> | ||
<artifactId>helidon-microprofile-server</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
184 changes: 184 additions & 0 deletions
184
microprofile/cors/src/main/java/io/helidon/microprofile/cors/CorsSupportMp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
/* | ||
* Copyright (c) 2020 Oracle and/or its affiliates. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*/ | ||
package io.helidon.microprofile.cors; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.function.Supplier; | ||
|
||
import javax.ws.rs.container.ContainerRequestContext; | ||
import javax.ws.rs.container.ContainerResponseContext; | ||
import javax.ws.rs.core.MultivaluedHashMap; | ||
import javax.ws.rs.core.MultivaluedMap; | ||
import javax.ws.rs.core.Response; | ||
|
||
import io.helidon.webserver.cors.CorsSupportBase; | ||
import io.helidon.webserver.cors.CrossOriginConfig; | ||
|
||
/** | ||
* MP implementation of {@link CorsSupportBase}. | ||
*/ | ||
class CorsSupportMp extends CorsSupportBase { | ||
|
||
/** | ||
* | ||
* @return a new builder of CorsSupportMp | ||
*/ | ||
static Builder builder() { | ||
return new Builder(); | ||
} | ||
|
||
private CorsSupportMp(Builder builder) { | ||
super(builder); | ||
} | ||
|
||
/** | ||
* <em>Not for developer use.</em> Submits a request adapter and response adapter for CORS processing. | ||
* | ||
* @param requestAdapter wrapper around the request | ||
* @param responseAdapter wrapper around the response | ||
* @return Optional of the response type U; present if the response should be returned, empty if request processing should | ||
* continue | ||
*/ | ||
@Override | ||
protected <T, U> Optional<U> processRequest(RequestAdapter<T> requestAdapter, | ||
ResponseAdapter<U> responseAdapter) { | ||
return super.processRequest(requestAdapter, responseAdapter); | ||
} | ||
|
||
/** | ||
* <em>Not for developer user.</em> Gets a response ready to participate in the CORS protocol. | ||
* | ||
* @param requestAdapter wrapper around the request | ||
* @param responseAdapter wrapper around the response | ||
*/ | ||
@Override | ||
protected <T, U> void prepareResponse(RequestAdapter<T> requestAdapter, ResponseAdapter<U> responseAdapter) { | ||
super.prepareResponse(requestAdapter, responseAdapter); | ||
} | ||
|
||
static class Builder extends CorsSupportBase.Builder<CorsSupportMp, Builder> { | ||
|
||
@Override | ||
public CorsSupportMp build() { | ||
return new CorsSupportMp(this); | ||
} | ||
|
||
@Override | ||
protected Builder me() { | ||
return this; | ||
} | ||
|
||
@Override | ||
protected Builder secondaryLookupSupplier( | ||
Supplier<Optional<CrossOriginConfig>> secondaryLookupSupplier) { | ||
super.secondaryLookupSupplier(secondaryLookupSupplier); | ||
return this; | ||
} | ||
} | ||
|
||
static class RequestAdapterMp implements RequestAdapter<ContainerRequestContext> { | ||
|
||
private final ContainerRequestContext requestContext; | ||
|
||
RequestAdapterMp(ContainerRequestContext requestContext) { | ||
this.requestContext = requestContext; | ||
} | ||
|
||
@Override | ||
public String path() { | ||
return requestContext.getUriInfo().getPath(); | ||
} | ||
|
||
@Override | ||
public Optional<String> firstHeader(String s) { | ||
return Optional.ofNullable(requestContext.getHeaders().getFirst(s)); | ||
} | ||
|
||
@Override | ||
public boolean headerContainsKey(String s) { | ||
return requestContext.getHeaders().containsKey(s); | ||
} | ||
|
||
@Override | ||
public List<String> allHeaders(String s) { | ||
return requestContext.getHeaders().get(s); | ||
} | ||
|
||
@Override | ||
public String method() { | ||
return requestContext.getMethod(); | ||
} | ||
|
||
@Override | ||
public ContainerRequestContext request() { | ||
return requestContext; | ||
} | ||
|
||
@Override | ||
public void next() { | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return String.format("RequestAdapterMp{path=%s, method=%s, headers=%s}", path(), method(), | ||
requestContext.getHeaders()); | ||
} | ||
} | ||
|
||
static class ResponseAdapterMp implements ResponseAdapter<Response> { | ||
|
||
private final MultivaluedMap<String, Object> headers; | ||
|
||
ResponseAdapterMp(ContainerResponseContext responseContext) { | ||
headers = responseContext.getHeaders(); | ||
} | ||
|
||
ResponseAdapterMp() { | ||
headers = new MultivaluedHashMap<>(); | ||
} | ||
|
||
@Override | ||
public ResponseAdapter<Response> header(String key, String value) { | ||
headers.add(key, value); | ||
return this; | ||
} | ||
|
||
@Override | ||
public ResponseAdapter<Response> header(String key, Object value) { | ||
headers.add(key, value); | ||
return this; | ||
} | ||
|
||
@Override | ||
public Response forbidden(String message) { | ||
return Response.status(Response.Status.FORBIDDEN).entity(message).build(); | ||
} | ||
|
||
@Override | ||
public Response ok() { | ||
Response.ResponseBuilder builder = Response.ok(); | ||
/* | ||
* The Helidon CORS support code invokes ok() only for creating a CORS preflight response. In these cases no user | ||
* code will have a chance to set headers in the response. That means we can use replaceAll here because the only | ||
* headers needed in the response are the ones set using this adapter. | ||
*/ | ||
builder.replaceAll(headers); | ||
return builder.build(); | ||
} | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
microprofile/cors/src/main/java/io/helidon/microprofile/cors/CrossOrigin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* Copyright (c) 2020 Oracle and/or its affiliates. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.helidon.microprofile.cors; | ||
|
||
import java.lang.annotation.Documented; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.Target; | ||
|
||
import static io.helidon.webserver.cors.CrossOriginConfig.DEFAULT_AGE; | ||
import static java.lang.annotation.ElementType.METHOD; | ||
import static java.lang.annotation.RetentionPolicy.RUNTIME; | ||
|
||
/** | ||
* CrossOrigin annotation. | ||
*/ | ||
@Target(METHOD) | ||
@Retention(RUNTIME) | ||
@Documented | ||
public @interface CrossOrigin { | ||
|
||
/** | ||
* A list of origins that are allowed such as {@code "http://foo.com"} or | ||
* {@code "*"} to allow all origins. Corresponds to header {@code | ||
* Access-Control-Allow-Origin}. | ||
* | ||
* @return Allowed origins. | ||
*/ | ||
String[] value() default {"*"}; | ||
|
||
/** | ||
* A list of request headers that are allowed or {@code "*"} to allow all headers. | ||
* Corresponds to {@code Access-Control-Allow-Headers}. | ||
* | ||
* @return Allowed headers. | ||
*/ | ||
String[] allowHeaders() default {"*"}; | ||
|
||
/** | ||
* A list of response headers allowed for clients other than the "standard" | ||
* ones. Corresponds to {@code Access-Control-Expose-Headers}. | ||
* | ||
* @return Exposed headers. | ||
*/ | ||
String[] exposeHeaders() default {}; | ||
|
||
/** | ||
* A list of supported HTTP request methods. In response to pre-flight | ||
* requests. Corresponds to {@code Access-Control-Allow-Methods}. | ||
* | ||
* @return Allowed methods. | ||
*/ | ||
String[] allowMethods() default {"*"}; | ||
|
||
/** | ||
* Whether the client can send cookies or credentials. Corresponds to {@code | ||
* Access-Control-Allow-Credentials}. | ||
* | ||
* @return Allowed credentials. | ||
*/ | ||
boolean allowCredentials() default false; | ||
|
||
/** | ||
* Pre-flight response duration in seconds. After time expires, a new pre-flight | ||
* request is required. Corresponds to {@code Access-Control-Max-Age}. | ||
* | ||
* @return Max age. | ||
*/ | ||
long maxAge() default DEFAULT_AGE; | ||
} |
Oops, something went wrong.