This is an automated email from the ASF dual-hosted git repository.

yui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 13a236a76 [type: refactor] support custom origins for cors 
'Acess-Control-Allow-Origin'. (#3663)
13a236a76 is described below

commit 13a236a765ec24f5056d22cf8962b800f51f290e
Author: Qicz <[email protected]>
AuthorDate: Tue Jul 5 14:09:14 2022 +0800

    [type: refactor] support custom origins for cors 
'Acess-Control-Allow-Origin'. (#3663)
    
    * [type: refactor] support custom origins for cors 
'Acess-Control-Allow-Origin'.
    
    * trim origin item
    
    * code polish
    
    * optimize cors logic
---
 .../src/main/resources/application.yml             | 18 ++++---
 .../apache/shenyu/common/config/ShenyuConfig.java  | 28 +++++++---
 .../org/apache/shenyu/web/filter/CrossFilter.java  | 60 +++++++++++++---------
 .../apache/shenyu/web/filter/CrossFilterTest.java  |  1 +
 4 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/shenyu-bootstrap/src/main/resources/application.yml 
b/shenyu-bootstrap/src/main/resources/application.yml
index 16e7c0b13..b396fbb39 100644
--- a/shenyu-bootstrap/src/main/resources/application.yml
+++ b/shenyu-bootstrap/src/main/resources/application.yml
@@ -160,15 +160,19 @@ shenyu:
     enabled: true
     allowedHeaders:
     allowedMethods: "*"
-    allowedAnyOrigin: false
-    allowedOrigin:
+    allowedAnyOrigin: true # the same of Access-Control-Allow-Origin: "*"
+#    allowedOrigin:
       # format : schema://prefix spacer domain
       # Access-Control-Allow-Origin: "http://a.apache.org,http://b.apache.org";
-      spacer: "."
-      domain: apache.org
-      prefixes:
-        - a # a.apache.org
-        - b # b.apache.org
+#      spacer: "."
+#      domain: apache.org
+#      prefixes:
+#        - a # a.apache.org
+#        - b # b.apache.org
+#      origins:
+#        - c.apache.org
+#        - d.apache.org
+#        - http://e.apache.org
     allowedExpose: ""
     maxAge: "18000"
     allowCredentials: true
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
index 6e2e06cda..b03206f51 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/config/ShenyuConfig.java
@@ -23,7 +23,6 @@ import org.springframework.util.StringUtils;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 import java.util.Properties;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -1144,6 +1143,8 @@ public class ShenyuConfig {
 
             private Set<String> prefixes = new HashSet<>();
 
+            private String origins;
+
             /**
              * Gets the spacer.
              *
@@ -1174,7 +1175,7 @@ public class ShenyuConfig {
             /**
              * Sets the enabled.
              *
-             * @param domain enabled
+             * @param domain domain
              */
             public void setDomain(final String domain) {
                 this.domain = domain;
@@ -1186,20 +1187,35 @@ public class ShenyuConfig {
              * @return the value of prefixes
              */
             public Set<String> getPrefixes() {
-                if (Objects.isNull(prefixes)) {
-                    prefixes = new HashSet<>();
-                }
                 return prefixes;
             }
 
             /**
              * Sets the enabled.
              *
-             * @param prefixes enabled
+             * @param prefixes prefixes
              */
             public void setPrefixes(final Set<String> prefixes) {
                 this.prefixes = prefixes;
             }
+
+            /**
+             * Gets the prefixes.
+             *
+             * @return the value of prefixes
+             */
+            public String getOrigins() {
+                return origins;
+            }
+
+            /**
+             * Sets the origins.
+             *
+             * @param origins origins
+             */
+            public void setOrigins(final String origins) {
+                this.origins = origins;
+            }
         }
     }
     
diff --git 
a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java 
b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java
index b4a179b54..6a9a81d37 100644
--- a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java
+++ b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CrossFilter.java
@@ -32,8 +32,10 @@ import org.springframework.web.server.WebFilter;
 import org.springframework.web.server.WebFilterChain;
 import reactor.core.publisher.Mono;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -58,15 +60,13 @@ public class CrossFilter implements WebFilter {
         if (CorsUtils.isCorsRequest(request)) {
             ServerHttpResponse response = exchange.getResponse();
             HttpHeaders headers = response.getHeaders();
-            // "Access-Control-Allow-Origin"
+            // finger allow origins
             final String origin = request.getHeaders().getOrigin();
-            if (this.filterConfig.isAllowedAnyOrigin()) {
-                headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
-            } else if (Objects.nonNull(this.filterConfig.getAllowedOrigin())
-                    && 
CollectionUtils.isNotEmpty(this.filterConfig.getAllowedOrigin().getPrefixes())) 
{
+            boolean allowCors = this.filterConfig.isAllowedAnyOrigin();
+            if (!allowCors && 
Objects.nonNull(this.filterConfig.getAllowedOrigin())) {
                 final String scheme = 
exchange.getRequest().getURI().getScheme();
                 final CrossFilterConfig.AllowedOriginConfig 
allowedOriginConfig = this.filterConfig.getAllowedOrigin();
-                Set<String> allowedOrigin = allowedOriginConfig.getPrefixes()
+                Set<String> allowedOrigin = 
Optional.ofNullable(allowedOriginConfig.getPrefixes()).orElse(Collections.emptySet())
                         .stream()
                         .filter(StringUtils::isNoneBlank)
                         // scheme://prefix spacer domain
@@ -75,25 +75,37 @@ public class CrossFilter implements WebFilter {
                                 
StringUtils.defaultString(allowedOriginConfig.getSpacer(), ".").trim(),
                                 
StringUtils.defaultString(allowedOriginConfig.getDomain(), "").trim()))
                         .collect(Collectors.toSet());
-                if (allowedOrigin.contains(origin)) {
-                    headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, 
origin);
-                }
+                // add all origin domains
+                
allowedOrigin.addAll(Stream.of(StringUtils.defaultString(allowedOriginConfig.getOrigins(),
 "").split(","))
+                        .filter(StringUtils::isNoneBlank)
+                        .map(oneOrigin -> {
+                            if (ALL.equals(oneOrigin) || 
oneOrigin.startsWith(String.format("%s://", scheme))) {
+                                return oneOrigin.trim();
+                            }
+                            return String.format("%s://%s", scheme, 
oneOrigin.trim());
+                        })
+                        .collect(Collectors.toSet()));
+                allowCors = allowedOrigin.contains(origin) || 
allowedOrigin.contains(ALL);
+            }
+            if (allowCors) {
+                // "Access-Control-Allow-Origin"
+                headers.set(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
+                // "Access-Control-Allow-Methods"
+                this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
+                        this.filterConfig.getAllowedMethods());
+                // "Access-Control-Max-Age"
+                this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_MAX_AGE,
+                        this.filterConfig.getMaxAge());
+                // "Access-Control-Allow-Headers"
+                this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
+                        this.filterConfig.getAllowedHeaders());
+                // "Access-Control-Expose-Headers"
+                this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
+                        this.filterConfig.getAllowedExpose());
+                // "Access-Control-Allow-Credentials"
+                this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS,
+                        
String.valueOf(this.filterConfig.isAllowCredentials()));
             }
-            // "Access-Control-Allow-Methods"
-            this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
-                    this.filterConfig.getAllowedMethods());
-            // "Access-Control-Max-Age"
-            this.filterSameHeader(headers, HttpHeaders.ACCESS_CONTROL_MAX_AGE,
-                    this.filterConfig.getMaxAge());
-            // "Access-Control-Allow-Headers"
-            this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
-                    this.filterConfig.getAllowedHeaders());
-            // "Access-Control-Expose-Headers"
-            this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
-                    this.filterConfig.getAllowedExpose());
-            // "Access-Control-Allow-Credentials"
-            this.filterSameHeader(headers, 
HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS,
-                    String.valueOf(this.filterConfig.isAllowCredentials()));
             if (request.getMethod() == HttpMethod.OPTIONS) {
                 response.setStatusCode(HttpStatus.OK);
                 return Mono.empty();
diff --git 
a/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java 
b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java
index ec942bc1c..d11503963 100644
--- a/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java
+++ b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CrossFilterTest.java
@@ -93,6 +93,7 @@ public final class CrossFilterTest {
                 add("a");
             }
         });
+        
allowedOriginConfig.setOrigins("b.apache.org,c.apache.org,http://d.apache.org,*";);
         filterConfig.setAllowedOrigin(allowedOriginConfig);
         CrossFilter filter = new CrossFilter(filterConfig);
         StepVerifier.create(filter.filter(exchange, chainNormal))

Reply via email to