diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java index 35c190b5f8a..a9a529a8ca1 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java @@ -75,6 +75,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -120,6 +121,7 @@ public class ExtensionLoader { private final ConcurrentMap, String> cachedNames = new ConcurrentHashMap<>(); + private final ReentrantLock loadExtensionClassesLock = new ReentrantLock(); private final Holder>> cachedClasses = new Holder<>(); private final Map cachedActivates = Collections.synchronizedMap(new LinkedHashMap<>()); @@ -951,7 +953,8 @@ private Class getExtensionClass(String name) { private Map> getExtensionClasses() { Map> classes = cachedClasses.get(); if (classes == null) { - synchronized (cachedClasses) { + loadExtensionClassesLock.lock(); + try { classes = cachedClasses.get(); if (classes == null) { try { @@ -968,6 +971,8 @@ private Map> getExtensionClasses() { } cachedClasses.set(classes); } + } finally { + loadExtensionClassesLock.unlock(); } } return classes; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/CorsConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/CorsConfig.java index 3c8eeec4d6e..06446861594 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/CorsConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/CorsConfig.java @@ -21,60 +21,48 @@ public class CorsConfig implements Serializable { private static final long serialVersionUID = 1L; - private String allowedOrigins; + private String[] allowedOrigins; - private String allowedMethods; + private String[] allowedMethods; - private String allowedHeaders; + private String[] allowedHeaders; - private String exposedHeaders; - - private Boolean allowCredentials; - - private Boolean allowPrivateNetWork; + private String[] exposedHeaders; private Long maxAge; - public String getAllowedOrigins() { + public String[] getAllowedOrigins() { return allowedOrigins; } - public void setAllowedOrigins(String allowedOrigins) { + public void setAllowedOrigins(String[] allowedOrigins) { this.allowedOrigins = allowedOrigins; } - public String getAllowedMethods() { + public String[] getAllowedMethods() { return allowedMethods; } - public void setAllowedMethods(String allowedMethods) { + public void setAllowedMethods(String[] allowedMethods) { this.allowedMethods = allowedMethods; } - public String getAllowedHeaders() { + public String[] getAllowedHeaders() { return allowedHeaders; } - public void setAllowedHeaders(String allowedHeaders) { + public void setAllowedHeaders(String[] allowedHeaders) { this.allowedHeaders = allowedHeaders; } - public String getExposedHeaders() { + public String[] getExposedHeaders() { return exposedHeaders; } - public void setExposedHeaders(String exposedHeaders) { + public void setExposedHeaders(String[] exposedHeaders) { this.exposedHeaders = exposedHeaders; } - public Boolean getAllowCredentials() { - return allowCredentials; - } - - public void setAllowCredentials(Boolean allowCredentials) { - this.allowCredentials = allowCredentials; - } - public Long getMaxAge() { return maxAge; } @@ -82,12 +70,4 @@ public Long getMaxAge() { public void setMaxAge(Long maxAge) { this.maxAge = maxAge; } - - public Boolean getAllowPrivateNetWork() { - return allowPrivateNetWork; - } - - public void setAllowPrivateNetWork(Boolean allowPrivateNetWork) { - this.allowPrivateNetWork = allowPrivateNetWork; - } } diff --git a/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRequestMappingResolver.java b/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRequestMappingResolver.java index 9d7dc5a1432..b446966b4c1 100644 --- a/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRequestMappingResolver.java +++ b/dubbo-plugin/dubbo-rest-jaxrs/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/jaxrs/JaxrsRequestMappingResolver.java @@ -18,6 +18,7 @@ import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsUtils; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping.Builder; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver; @@ -69,6 +70,7 @@ public RequestMapping resolve(MethodMeta methodMeta) { .name(methodMeta.getMethod().getName()) .contextPath(methodMeta.getServiceMeta().getContextPath()) .custom(new ServiceVersionCondition(serviceMeta.getServiceGroup(), serviceMeta.getServiceVersion())) + .cors(CorsUtils.getGlobalCorsMeta()) .build(); } diff --git a/dubbo-plugin/dubbo-rest-spring/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/spring/SpringMvcRequestMappingResolver.java b/dubbo-plugin/dubbo-rest-spring/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/spring/SpringMvcRequestMappingResolver.java index 18abefce169..b8e481be496 100644 --- a/dubbo-plugin/dubbo-rest-spring/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/spring/SpringMvcRequestMappingResolver.java +++ b/dubbo-plugin/dubbo-rest-spring/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/support/spring/SpringMvcRequestMappingResolver.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsMeta; +import org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsUtils; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping.Builder; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver; @@ -70,7 +71,7 @@ public RequestMapping resolve(ServiceMeta serviceMeta) { return builder(requestMapping, responseStatus) .name(serviceMeta.getType().getSimpleName()) .contextPath(serviceMeta.getContextPath()) - .cors(createCorsMeta(crossOrigin)) + .cors(buildCorsMetaWithGlobal(crossOrigin)) .build(); } @@ -92,7 +93,7 @@ public RequestMapping resolve(MethodMeta methodMeta) { .name(methodMeta.getMethod().getName()) .contextPath(serviceMeta.getContextPath()) .custom(new ServiceVersionCondition(serviceMeta.getServiceGroup(), serviceMeta.getServiceVersion())) - .cors(createCorsMeta(crossOrigin)) + .cors(buildCorsMeta(crossOrigin)) .build(); } @@ -114,10 +115,10 @@ private Builder builder(AnnotationMeta requestMapping, AnnotationMeta resp .produce(requestMapping.getStringArray("produces")); } - private CorsMeta createCorsMeta(AnnotationMeta crossOrigin) { + private CorsMeta buildCorsMeta(AnnotationMeta crossOrigin) { CorsMeta meta = new CorsMeta(); if (crossOrigin == null) { - return meta; + return null; } String[] allowedHeaders = crossOrigin.getStringArray("allowedHeaders"); meta.setAllowedHeaders(allowedHeaders != null ? Arrays.asList(allowedHeaders) : Collections.emptyList()); @@ -129,15 +130,14 @@ private CorsMeta createCorsMeta(AnnotationMeta crossOrigin) { meta.setExposedHeaders(exposedHeaders != null ? Arrays.asList(exposedHeaders) : Collections.emptyList()); String maxAge = crossOrigin.getString("maxAge"); meta.setMaxAge(maxAge != null ? Long.valueOf(maxAge) : null); - String allowCredentials = crossOrigin.getString("allowCredentials"); - meta.setAllowCredentials(allowCredentials != null ? Boolean.valueOf(allowCredentials) : null); - // Because allowPrivateNetwork does not exist in some spring versions, we need to catch the exception - try { - String allowPrivateNetwork = crossOrigin.getString("allowPrivateNetwork"); - meta.setAllowPrivateNetwork(allowPrivateNetwork != null ? Boolean.valueOf(allowPrivateNetwork) : null); - } catch (IllegalArgumentException e) { - meta.setAllowPrivateNetwork(null); - } return meta; } + + private CorsMeta buildCorsMetaWithGlobal(AnnotationMeta crossOrigin) { + CorsMeta corsMeta = buildCorsMeta(crossOrigin); + if (corsMeta != null) { + return CorsMeta.combine(corsMeta, CorsUtils.getGlobalCorsMeta()); + } + return CorsUtils.getGlobalCorsMeta(); + } } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/RestConstants.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/RestConstants.java index 101e13390ac..94154f29a87 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/RestConstants.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/RestConstants.java @@ -59,10 +59,6 @@ public final class RestConstants { public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"; public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"; public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; - public static final String HTTP = "http"; - public static final String HTTPS = "https"; - public static final String WS = "ws"; - public static final String WSS = "wss"; public static final String ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK = "Access-Control-Request-Private-Network"; public static final String ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK = "Access-Control-Allow-Private-Network"; @@ -80,8 +76,6 @@ public final class RestConstants { public static final String ALLOWED_HEADERS = CORS_CONFIG_PREFIX + "allowed-headers"; public static final String EXPOSED_HEADERS = CORS_CONFIG_PREFIX + "exposed-headers"; public static final String MAX_AGE = CORS_CONFIG_PREFIX + "max-age"; - public static final String ALLOW_CREDENTIALS = CORS_CONFIG_PREFIX + "allow-credentials"; - public static final String ALLOW_PRIVATE_NETWORK = CORS_CONFIG_PREFIX + "allow-private-network"; private RestConstants() {} } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMeta.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMeta.java index 3d2c7a847f2..842ce6ef347 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMeta.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMeta.java @@ -72,12 +72,6 @@ public class CorsMeta { @Nullable private List exposedHeaders; - @Nullable - private Boolean allowCredentials; - - @Nullable - private Boolean allowPrivateNetwork; - @Nullable private Long maxAge; @@ -90,8 +84,6 @@ public CorsMeta(CorsMeta other) { this.resolvedMethods = other.resolvedMethods; this.allowedHeaders = other.allowedHeaders; this.exposedHeaders = other.exposedHeaders; - this.allowCredentials = other.allowCredentials; - this.allowPrivateNetwork = other.allowPrivateNetwork; this.maxAge = other.maxAge; } @@ -242,23 +234,6 @@ public void addExposedHeader(String exposedHeader) { this.exposedHeaders.add(exposedHeader); } - public void setAllowCredentials(@Nullable Boolean allowCredentials) { - this.allowCredentials = allowCredentials; - } - - @Nullable - public Boolean getAllowCredentials() { - return this.allowCredentials; - } - - public void setAllowPrivateNetwork(Boolean allowPrivateNetwork) { - this.allowPrivateNetwork = allowPrivateNetwork; - } - - public Boolean getAllowPrivateNetwork() { - return this.allowPrivateNetwork; - } - public void setMaxAge(@Nullable Long maxAge) { this.maxAge = maxAge; } @@ -283,38 +258,9 @@ public CorsMeta applyPermitDefaultValues() { if (this.maxAge == null) { this.maxAge = DEFAULT_MAX_AGE; } - if (this.allowCredentials == null) { - this.allowCredentials = false; - } - if (this.allowPrivateNetwork == null) { - this.allowPrivateNetwork = false; - } return this; } - public boolean validateAllowCredentials() { - // When allowCredentials is true, allowedOrigins cannot contain the special value \"*\" - // since that cannot be set on the \"Access-Control-Allow-Origin\" response header. - // To allow credentials to a set of origins, list them explicitly - // or consider using \"allowedOriginPatterns\" instead. - return this.allowCredentials != null - && this.allowCredentials.equals(Boolean.TRUE) - && this.allowedOrigins != null - && this.allowedOrigins.contains(ALL); - } - - public boolean validateAllowPrivateNetwork() { - - // When allowPrivateNetwork is true, allowedOrigins cannot contain the special value \"*\" - // as it is not recommended from a security perspective. - // To allow private network access to a set of origins, list them explicitly - // or consider using \"allowedOriginPatterns\" instead. - return this.allowPrivateNetwork != null - && this.allowPrivateNetwork.equals(Boolean.TRUE) - && this.allowedOrigins != null - && this.allowedOrigins.contains(ALL); - } - /** * Combines two lists of strings, with a priority on this * @param other other @@ -339,12 +285,6 @@ public static CorsMeta combine(@Nullable CorsMeta priority, @Nullable CorsMeta o config.setAllowedMethods(priority.combine(priority.getAllowedMethods(), other.getAllowedMethods())); config.setAllowedHeaders(priority.combine(priority.getAllowedHeaders(), other.getAllowedHeaders())); config.setExposedHeaders(priority.combine(priority.getExposedHeaders(), other.getExposedHeaders())); - if (priority.allowCredentials == null) { - config.setAllowCredentials(other.getAllowCredentials()); - } - if (priority.allowPrivateNetwork == null) { - config.setAllowPrivateNetwork(other.allowPrivateNetwork); - } if (priority.maxAge == null) { config.setMaxAge(other.maxAge); } @@ -420,7 +360,7 @@ public String checkOrigin(@Nullable String origin) { } private String allOriginAllowed() { - return (validateAllowCredentials() || validateAllowPrivateNetwork() ? null : ALL); + return ALL; } private boolean isOriginAllowed(String originToCheck) { diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessor.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessor.java index 66df5b934bc..3a49b422999 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessor.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessor.java @@ -32,9 +32,7 @@ import java.util.Objects; import java.util.stream.Collectors; -import static org.apache.dubbo.rpc.protocol.tri.rest.RestConstants.ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK; -import static org.apache.dubbo.rpc.protocol.tri.rest.RestConstants.ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK; -import static org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsUtil.getPort; +import static org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsUtils.getPort; public class CorsProcessor { private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(CorsProcessor.class); @@ -100,15 +98,6 @@ protected boolean handleInternal(HttpRequest request, HttpResponse response, Cor response.setHeader(RestConstants.ACCESS_CONTROL_EXPOSE_HEADERS, config.getExposedHeaders()); } - if (Boolean.TRUE.equals(config.getAllowCredentials())) { - response.setHeader(RestConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.TRUE.toString()); - } - - if (Boolean.TRUE.equals(config.getAllowPrivateNetwork()) - && Boolean.parseBoolean(request.header(ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK))) { - response.setHeader(ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK, Boolean.TRUE.toString()); - } - return true; } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtil.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtils.java similarity index 74% rename from dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtil.java rename to dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtils.java index 0401007e9ad..0abc24dca4d 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtil.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtils.java @@ -17,21 +17,29 @@ package org.apache.dubbo.rpc.protocol.tri.rest.cors; import org.apache.dubbo.common.config.Configuration; +import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.lang.Nullable; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.protocol.tri.rest.RestConstants; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -public class CorsUtil { - private CorsUtil() {} +public class CorsUtils { + private static CorsMeta globalCorsMeta; + public static final String HTTP = "http"; + public static final String HTTPS = "https"; + public static final String WS = "ws"; + public static final String WSS = "wss"; + + private CorsUtils() {} public static int getPort(String scheme, int port) { if (port == -1) { - if (RestConstants.HTTP.equals(scheme) || RestConstants.WS.equals(scheme)) { + if (HTTP.equals(scheme) || WS.equals(scheme)) { port = 80; - } else if (RestConstants.HTTPS.equals(scheme) || RestConstants.WSS.equals(scheme)) { + } else if (HTTPS.equals(scheme) || WSS.equals(scheme)) { port = 443; } } @@ -46,8 +54,6 @@ public static CorsMeta resolveGlobalMeta(Configuration config) { String allowHeaders = config.getString(RestConstants.ALLOWED_HEADERS); String exposeHeaders = config.getString(RestConstants.EXPOSED_HEADERS); String maxAge = config.getString(RestConstants.MAX_AGE); - String allowCredentials = config.getString(RestConstants.ALLOW_CREDENTIALS); - String allowPrivateNetwork = config.getString(RestConstants.ALLOW_PRIVATE_NETWORK); // Create a new CorsMeta object and set the properties. CorsMeta meta = new CorsMeta(); meta.setAllowedOrigins(parseList(allowOrigins)); @@ -55,8 +61,6 @@ public static CorsMeta resolveGlobalMeta(Configuration config) { meta.setAllowedHeaders(parseList(allowHeaders)); meta.setExposedHeaders(parseList(exposeHeaders)); meta.setMaxAge(maxAge == null ? null : Long.valueOf(maxAge)); - meta.setAllowCredentials(allowCredentials == null ? null : Boolean.valueOf(allowCredentials)); - meta.setAllowPrivateNetwork(allowPrivateNetwork == null ? null : Boolean.valueOf(allowPrivateNetwork)); // Return the CorsMeta object. return meta.applyPermitDefaultValues(); } @@ -68,4 +72,13 @@ private static List parseList(@Nullable String value) { } return Arrays.stream(value.split(",")).map(String::trim).collect(Collectors.toList()); } + + public static CorsMeta getGlobalCorsMeta() { + if (globalCorsMeta == null) { + Configuration globalConfiguration = + ConfigurationUtils.getGlobalConfiguration(ApplicationModel.defaultModel()); + globalCorsMeta = resolveGlobalMeta(globalConfiguration); + } + return globalCorsMeta; + } } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/filter/CorsHeaderFilterAdapter.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/filter/CorsHeaderFilterAdapter.java new file mode 100644 index 00000000000..d2ed7a06cda --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/filter/CorsHeaderFilterAdapter.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.rpc.protocol.tri.rest.filter; + +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.remoting.http12.HttpRequest; +import org.apache.dubbo.remoting.http12.HttpResponse; +import org.apache.dubbo.remoting.http12.HttpResult; +import org.apache.dubbo.remoting.http12.HttpStatus; +import org.apache.dubbo.remoting.http12.exception.HttpResultPayloadException; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.protocol.tri.rest.RestConstants; +import org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsProcessor; +import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping; + +@Activate(group = CommonConstants.PROVIDER, order = 1000) +public class CorsHeaderFilterAdapter extends RestHeaderFilterAdapter { + private CorsProcessor corsProcessor; + + public CorsHeaderFilterAdapter(FrameworkModel frameworkModel) { + corsProcessor = frameworkModel.getBeanFactory().getOrRegisterBean(CorsProcessor.class); + } + + @Override + protected RpcInvocation invoke( + Invoker invoker, RpcInvocation invocation, HttpRequest request, HttpResponse response) + throws RpcException { + RequestMapping mapping = request.attribute(RestConstants.MAPPING_ATTRIBUTE); + processCors(mapping, request, response); + return invocation; + } + + private void processCors(RequestMapping mapping, HttpRequest request, HttpResponse response) { + if (!corsProcessor.process(mapping.getCorsMeta(), request, response)) { + throw new HttpResultPayloadException(HttpResult.builder() + .status(HttpStatus.FORBIDDEN) + .body(response.body()) + .headers(response.headers()) + .build()); + } + } +} diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/filter/RestHeaderFilterAdapter.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/filter/RestHeaderFilterAdapter.java index abbf4a7a5ab..ebc08e6540b 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/filter/RestHeaderFilterAdapter.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/filter/RestHeaderFilterAdapter.java @@ -19,7 +19,6 @@ import org.apache.dubbo.remoting.http12.HttpRequest; import org.apache.dubbo.remoting.http12.HttpResponse; import org.apache.dubbo.rpc.HeaderFilter; -import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; @@ -38,5 +37,6 @@ public RpcInvocation invoke(Invoker invoker, RpcInvocation invocation) throws } protected abstract RpcInvocation invoke( - Invoker invoker, Invocation invocation, HttpRequest request, HttpResponse response) throws RpcException; + Invoker invoker, RpcInvocation invocation, HttpRequest request, HttpResponse response) + throws RpcException; } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/DefaultRequestMappingRegistry.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/DefaultRequestMappingRegistry.java index 217c01827b7..eabef994a59 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/DefaultRequestMappingRegistry.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/DefaultRequestMappingRegistry.java @@ -16,26 +16,16 @@ */ package org.apache.dubbo.rpc.protocol.tri.rest.mapping; -import org.apache.dubbo.common.config.Configuration; -import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.remoting.http12.HttpRequest; -import org.apache.dubbo.remoting.http12.HttpResponse; -import org.apache.dubbo.remoting.http12.HttpResult; -import org.apache.dubbo.remoting.http12.HttpStatus; -import org.apache.dubbo.remoting.http12.exception.HttpResultPayloadException; import org.apache.dubbo.remoting.http12.message.MethodMetadata; import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.MethodDescriptor; import org.apache.dubbo.rpc.model.ServiceDescriptor; import org.apache.dubbo.rpc.protocol.tri.DescriptorUtils; import org.apache.dubbo.rpc.protocol.tri.rest.RestConstants; import org.apache.dubbo.rpc.protocol.tri.rest.RestInitializeException; -import org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsMeta; -import org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsProcessor; -import org.apache.dubbo.rpc.protocol.tri.rest.cors.CorsUtil; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RadixTree.Match; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.condition.PathExpression; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.condition.ProducesCondition; @@ -62,12 +52,9 @@ public final class DefaultRequestMappingRegistry implements RequestMappingRegist private final RadixTree tree = new RadixTree<>(); private final ReadWriteLock lock = new ReentrantReadWriteLock(); - private CorsMeta globalCorsMeta; - private final CorsProcessor corsProcessor; public DefaultRequestMappingRegistry(FrameworkModel frameworkModel) { resolvers = frameworkModel.getActivateExtensions(RequestMappingResolver.class); - corsProcessor = frameworkModel.getBeanFactory().getOrRegisterBean(CorsProcessor.class); } @Override @@ -81,7 +68,6 @@ public void register(Invoker invoker) { continue; } RequestMapping classMapping = resolver.resolve(serviceMeta); - mergeGlobalCorsMeta(classMapping); consumer.accept((methods) -> { MethodMeta methodMeta = new MethodMeta(methods, serviceMeta); RequestMapping methodMapping = resolver.resolve(methodMeta); @@ -129,17 +115,6 @@ private HandlerMeta buildHandlerMeta(Invoker invoker, MethodMeta methodMeta) serviceDescriptor); } - private void mergeGlobalCorsMeta(RequestMapping mapping) { - if (mapping != null) { - CorsMeta corsMeta = mapping.getCorsMeta(); - if (corsMeta != null) { - mapping.setCorsMeta(CorsMeta.combine(corsMeta, getGlobalCorsMeta())); - } else { - mapping.setCorsMeta(getGlobalCorsMeta()); - } - } - } - @Override public void unregister(Invoker invoker) { lock.writeLock().lock(); @@ -160,7 +135,7 @@ public void destroy() { } } - public HandlerMeta lookup(HttpRequest request, HttpResponse response) { + public HandlerMeta lookup(HttpRequest request) { String path = PathUtils.normalize(request.rawPath()); request.setAttribute(RestConstants.PATH_ATTRIBUTE, path); List> matches = new ArrayList<>(); @@ -216,8 +191,6 @@ public HandlerMeta lookup(HttpRequest request, HttpResponse response) { Candidate winner = candidates.get(0); RequestMapping mapping = winner.mapping; - processCors(mapping, request, response); - HandlerMeta handler = winner.meta; request.setAttribute(RestConstants.MAPPING_ATTRIBUTE, mapping); request.setAttribute(RestConstants.HANDLER_ATTRIBUTE, handler); @@ -234,25 +207,6 @@ public HandlerMeta lookup(HttpRequest request, HttpResponse response) { return handler; } - private void processCors(RequestMapping mapping, HttpRequest request, HttpResponse response) { - if (!corsProcessor.process(mapping.getCorsMeta(), request, response)) { - throw new HttpResultPayloadException(HttpResult.builder() - .status(HttpStatus.FORBIDDEN) - .body(response.body()) - .headers(response.headers()) - .build()); - } - } - - private CorsMeta getGlobalCorsMeta() { - if (globalCorsMeta == null) { - Configuration globalConfiguration = - ConfigurationUtils.getGlobalConfiguration(ApplicationModel.defaultModel()); - globalCorsMeta = CorsUtil.resolveGlobalMeta(globalConfiguration); - } - return globalCorsMeta; - } - private static final class Registration { RequestMapping mapping; HandlerMeta meta; diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RequestMappingRegistry.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RequestMappingRegistry.java index e3046bad41d..b7dfb559946 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RequestMappingRegistry.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RequestMappingRegistry.java @@ -17,7 +17,6 @@ package org.apache.dubbo.rpc.protocol.tri.rest.mapping; import org.apache.dubbo.remoting.http12.HttpRequest; -import org.apache.dubbo.remoting.http12.HttpResponse; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.HandlerMeta; @@ -30,7 +29,7 @@ public interface RequestMappingRegistry { void unregister(Invoker invoker); - HandlerMeta lookup(HttpRequest request, HttpResponse response); + HandlerMeta lookup(HttpRequest request); void destroy(); } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RestRequestHandlerMapping.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RestRequestHandlerMapping.java index 7b3b81b9303..b3ceaa155b3 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RestRequestHandlerMapping.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/RestRequestHandlerMapping.java @@ -61,7 +61,7 @@ public RestRequestHandlerMapping(FrameworkModel frameworkModel) { @Override public RequestHandler getRequestHandler(URL url, HttpRequest request, HttpResponse response) { - HandlerMeta meta = requestMappingRegistry.lookup(request, response); + HandlerMeta meta = requestMappingRegistry.lookup(request); if (meta == null) { return null; } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-rpc/dubbo-rpc-triple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter index 204897e33ff..8821eb7a155 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter @@ -1,2 +1,2 @@ http-context=org.apache.dubbo.rpc.protocol.tri.HttpContextFilter -rest-extension=org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtensionExecutionFilter \ No newline at end of file +rest-extension=org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtensionExecutionFilter diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.HeaderFilter b/dubbo-rpc/dubbo-rpc-triple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.HeaderFilter new file mode 100644 index 00000000000..ad0dea4dc8c --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.HeaderFilter @@ -0,0 +1 @@ +rest-cors-extension=org.apache.dubbo.rpc.protocol.tri.rest.filter.CorsHeaderFilterAdapter diff --git a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMetaTest.java b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMetaTest.java index 55d2d2ed588..1e5e1453e76 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMetaTest.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsMetaTest.java @@ -34,16 +34,12 @@ void setNullValues() { config.setAllowedHeaders(null); config.setAllowedMethods(null); config.setExposedHeaders(null); - config.setAllowCredentials(null); config.setMaxAge(null); - config.setAllowPrivateNetwork(null); Assertions.assertNull(config.getAllowedOrigins()); Assertions.assertNull(config.getAllowedOriginPatterns()); Assertions.assertNull(config.getAllowedHeaders()); Assertions.assertNull(config.getAllowedMethods()); Assertions.assertNull(config.getExposedHeaders()); - Assertions.assertNull(config.getAllowCredentials()); - Assertions.assertNull(config.getAllowPrivateNetwork()); Assertions.assertNull(config.getMaxAge()); } @@ -57,8 +53,7 @@ void setValues() { config.addAllowedHeader("*"); config.addAllowedMethod("*"); config.addExposedHeader("*"); - config.setAllowCredentials(true); - config.setAllowPrivateNetwork(true); + config.setMaxAge(123L); Assertions.assertArrayEquals( new String[] {"*"}, config.getAllowedOrigins().toArray()); @@ -71,8 +66,6 @@ void setValues() { new String[] {"*"}, config.getAllowedMethods().toArray()); Assertions.assertArrayEquals( new String[] {"*"}, config.getExposedHeaders().toArray()); - Assertions.assertTrue(config.getAllowCredentials()); - Assertions.assertTrue(config.getAllowPrivateNetwork()); Assertions.assertEquals(123L, config.getMaxAge().longValue()); } @@ -96,8 +89,6 @@ void combineWithConfigWithNullProperties() { config.addExposedHeader("header3"); config.addAllowedMethod(HttpMethods.GET.name()); config.setMaxAge(123L); - config.setAllowCredentials(true); - config.setAllowPrivateNetwork(true); CorsMeta other = new CorsMeta(); config = CorsMeta.combine(config, other); // Assert the combined config @@ -115,8 +106,6 @@ void combineWithConfigWithNullProperties() { new String[] {HttpMethods.GET.name()}, config.getAllowedMethods().toArray()); Assertions.assertEquals(123L, config.getMaxAge().longValue()); - Assertions.assertTrue(config.getAllowCredentials()); - Assertions.assertTrue(config.getAllowPrivateNetwork()); } @Test @@ -348,8 +337,6 @@ void combine() { priority.addExposedHeader("header3"); priority.addAllowedMethod(HttpMethods.GET.name()); priority.setMaxAge(123L); - priority.setAllowCredentials(true); - priority.setAllowPrivateNetwork(true); // Create another config with some different values CorsMeta other = new CorsMeta(); @@ -359,8 +346,6 @@ void combine() { other.addExposedHeader("header4"); other.addAllowedMethod(HttpMethods.PUT.name()); other.setMaxAge(456L); - other.setAllowCredentials(false); - other.setAllowPrivateNetwork(false); // Combine the configs priority = CorsMeta.combine(priority, other); @@ -380,8 +365,7 @@ void combine() { new String[] {HttpMethods.GET.name(), HttpMethods.PUT.name()}, priority.getAllowedMethods().toArray()); Assertions.assertEquals(Long.valueOf(123L), priority.getMaxAge()); - Assertions.assertTrue(priority.getAllowCredentials()); - Assertions.assertTrue(priority.getAllowPrivateNetwork()); + Assertions.assertArrayEquals( new String[] {"http://*.domain1.com", "http://*.domain2.com"}, priority.getAllowedOriginPatterns().toArray()); @@ -394,10 +378,6 @@ void checkOriginAllowed() { config.addAllowedOrigin("*"); Assertions.assertEquals("*", config.checkOrigin("https://domain.com")); - // "*" does not match together with allowCredentials - config.setAllowCredentials(true); - Assertions.assertNull(config.checkOrigin("https://domain.com")); - // specific origin matches Origin header with or without trailing "/" config.setAllowedOrigins(Collections.singletonList("https://domain.com")); Assertions.assertEquals("https://domain.com", config.checkOrigin("https://domain.com")); @@ -408,7 +388,6 @@ void checkOriginAllowed() { Assertions.assertEquals("https://domain.com", config.checkOrigin("https://domain.com")); Assertions.assertEquals("https://domain.com/", config.checkOrigin("https://domain.com/")); - config.setAllowCredentials(false); Assertions.assertEquals("https://domain.com", config.checkOrigin("https://domain.com")); } @@ -436,8 +415,6 @@ void checkOriginPatternAllowed() { config.applyPermitDefaultValues(); Assertions.assertEquals("*", config.checkOrigin("https://domain.com")); - config.setAllowCredentials(true); - Assertions.assertNull(config.checkOrigin("https://domain.com")); config.addAllowedOriginPattern("https://*.domain.com"); Assertions.assertEquals("https://example.domain.com", config.checkOrigin("https://example.domain.com")); @@ -454,7 +431,6 @@ void checkOriginPatternAllowed() { "https://example.specific.port.com:8081", config.checkOrigin("https://example.specific.port.com:8081")); Assertions.assertNull(config.checkOrigin("https://example.specific.port.com:1234")); - config.setAllowCredentials(false); Assertions.assertEquals("https://example.domain.com", config.checkOrigin("https://example.domain.com")); } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessorTest.java b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessorTest.java index 7fadfb250f1..8920b7ac6f9 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessorTest.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsProcessorTest.java @@ -125,55 +125,6 @@ void actualRequestWithOriginHeaderAndAllowedOrigin() { Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); } - @Test - void actualRequestCredentials() { - Mockito.when(request.method()).thenReturn(HttpMethods.GET.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - this.conf.addAllowedOrigin("https://domain1.com"); - this.conf.addAllowedOrigin("https://domain2.com"); - this.conf.addAllowedOrigin("http://domain3.example"); - this.conf.setAllowCredentials(true); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertEquals("https://domain2.com", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assertions.assertEquals("true", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assertions.assertTrue(this.response.header(RestConstants.VARY).contains(RestConstants.ORIGIN)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } - - @Test - void actualRequestCredentialsWithWildcardOrigin() { - Mockito.when(request.method()).thenReturn(HttpMethods.GET.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - - this.conf.addAllowedOrigin("*"); - this.conf.setAllowCredentials(true); - Assertions.assertFalse(this.processor.process(this.conf, this.request, this.response)); - - this.response = new DefaultHttpResponse(); - this.response.setStatus(HttpStatus.OK.getCode()); - this.conf.setAllowedOrigins(null); - this.conf.addAllowedOriginPattern("*"); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertEquals("https://domain2.com", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assertions.assertEquals("true", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assertions.assertTrue(this.response.header(RestConstants.VARY).contains(RestConstants.ORIGIN)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } - @Test void actualRequestCaseInsensitiveOriginMatch() { Mockito.when(request.method()).thenReturn(HttpMethods.GET.name()); @@ -357,96 +308,6 @@ void preflightRequestValidRequestAndConfig() { Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); } - @Test - void preflightRequestCredentials() { - Mockito.when(request.method()).thenReturn(HttpMethods.OPTIONS.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)) - .thenReturn("GET"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)) - .thenReturn("Header1"); - this.conf.addAllowedOrigin("https://domain1.com"); - this.conf.addAllowedOrigin("https://domain2.com"); - this.conf.addAllowedOrigin("http://domain3.example"); - this.conf.addAllowedHeader("Header1"); - this.conf.setAllowCredentials(true); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertEquals("https://domain2.com", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assertions.assertEquals("true", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS)); - Assertions.assertTrue(this.response.header(RestConstants.VARY).contains(RestConstants.ORIGIN)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } - - @Test - void preflightRequestCredentialsWithWildcardOrigin() { - Mockito.when(request.method()).thenReturn(HttpMethods.OPTIONS.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)) - .thenReturn("GET"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)) - .thenReturn("Header1"); - this.conf.setAllowedOrigins(Arrays.asList("https://domain1.com", "*", "http://domain3.example")); - this.conf.addAllowedHeader("Header1"); - this.conf.setAllowCredentials(true); - - Assertions.assertFalse(this.processor.process(this.conf, this.request, this.response)); - - this.response = new DefaultHttpResponse(); - this.response.setStatus(HttpStatus.OK.getCode()); - this.conf.setAllowedOrigins(null); - this.conf.addAllowedOriginPattern("*"); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertEquals("https://domain2.com", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertTrue(this.response.header(RestConstants.VARY).contains(RestConstants.ORIGIN)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } - - @Test - void preflightRequestPrivateNetworkWithWildcardOrigin() { - Mockito.when(request.method()).thenReturn(HttpMethods.OPTIONS.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)) - .thenReturn("GET"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)) - .thenReturn("Header1"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK)) - .thenReturn("true"); - this.conf.setAllowedOrigins(Arrays.asList("https://domain1.com", "*", "http://domain3.example")); - this.conf.addAllowedHeader("Header1"); - this.conf.setAllowPrivateNetwork(true); - - Assertions.assertFalse(this.processor.process(this.conf, this.request, this.response)); - - this.response = new DefaultHttpResponse(); - this.response.setStatus(HttpStatus.OK.getCode()); - this.conf.setAllowedOrigins(null); - this.conf.addAllowedOriginPattern("*"); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK)); - Assertions.assertEquals("https://domain2.com", this.response.header(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertTrue(this.response.header(RestConstants.VARY).contains(RestConstants.ORIGIN)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)); - Assertions.assertTrue( - this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } - @Test void preflightRequestAllowedHeaders() { Mockito.when(request.method()).thenReturn(HttpMethods.OPTIONS.name()); @@ -560,54 +421,4 @@ void preventDuplicatedVaryHeaders() { Assertions.assertTrue( this.response.header(RestConstants.VARY).contains(RestConstants.ACCESS_CONTROL_REQUEST_HEADERS)); } - - @Test - void preflightRequestWithoutAccessControlRequestPrivateNetwork() { - Mockito.when(request.method()).thenReturn(HttpMethods.OPTIONS.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)) - .thenReturn("GET"); - this.conf.addAllowedHeader("*"); - this.conf.addAllowedOrigin("https://domain2.com"); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertFalse(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } - - @Test - void preflightRequestWithAccessControlRequestPrivateNetworkNotAllowed() { - Mockito.when(request.method()).thenReturn(HttpMethods.OPTIONS.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)) - .thenReturn("GET"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK)) - .thenReturn("true"); - this.conf.addAllowedHeader("*"); - this.conf.addAllowedOrigin("https://domain2.com"); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertFalse(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } - - @Test - void preflightRequestWithAccessControlRequestPrivateNetworkAllowed() { - Mockito.when(request.method()).thenReturn(HttpMethods.OPTIONS.name()); - Mockito.when(request.header(RestConstants.ORIGIN)).thenReturn("https://domain2.com"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_METHOD)) - .thenReturn("GET"); - Mockito.when(request.header(RestConstants.ACCESS_CONTROL_REQUEST_PRIVATE_NETWORK)) - .thenReturn("true"); - this.conf.addAllowedHeader("*"); - this.conf.addAllowedOrigin("https://domain2.com"); - this.conf.setAllowPrivateNetwork(true); - - this.processor.process(this.conf, this.request, this.response); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_ORIGIN)); - Assertions.assertTrue(this.response.hasHeader(RestConstants.ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK)); - Assertions.assertEquals(HttpStatus.OK.getCode(), this.response.status()); - } } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtilTest.java b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtilsTest.java similarity index 70% rename from dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtilTest.java rename to dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtilsTest.java index 635c23af9a0..f55c3fcbc71 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtilTest.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/rest/cors/CorsUtilsTest.java @@ -23,9 +23,7 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import static org.apache.dubbo.rpc.protocol.tri.rest.RestConstants.CORS_CONFIG_PREFIX; - -class CorsUtilTest { +class CorsUtilsTest { @Test void testResolveGlobalMetaInCommon() { @@ -35,11 +33,8 @@ void testResolveGlobalMetaInCommon() { Mockito.when(config.getString(RestConstants.ALLOWED_HEADERS)).thenReturn("Content-Type,Authorization"); Mockito.when(config.getString(RestConstants.EXPOSED_HEADERS)).thenReturn("Content-Type,Authorization"); Mockito.when(config.getString(RestConstants.MAX_AGE)).thenReturn("3600"); - Mockito.when(config.getString(RestConstants.ALLOW_CREDENTIALS)).thenReturn("true"); - Mockito.when(config.getString(RestConstants.ALLOW_PRIVATE_NETWORK)).thenReturn("true"); - Mockito.when(config.getString(CORS_CONFIG_PREFIX + RestConstants.ACCESS_CONTROL_ALLOW_PRIVATE_NETWORK)) - .thenReturn("true"); - CorsMeta meta = CorsUtil.resolveGlobalMeta(config); + Mockito.when(config.getString(RestConstants.MAX_AGE)).thenReturn("3600"); + CorsMeta meta = CorsUtils.resolveGlobalMeta(config); Assertions.assertTrue(meta.getAllowedOrigins().contains("http://localhost:8080")); Assertions.assertTrue(meta.getAllowedMethods().contains("GET")); Assertions.assertTrue(meta.getAllowedMethods().contains("POST")); @@ -50,8 +45,6 @@ void testResolveGlobalMetaInCommon() { Assertions.assertTrue(meta.getExposedHeaders().contains("Content-Type")); Assertions.assertTrue(meta.getExposedHeaders().contains("Authorization")); Assertions.assertEquals(3600, meta.getMaxAge()); - Assertions.assertTrue(meta.getAllowCredentials()); - Assertions.assertTrue(meta.getAllowPrivateNetwork()); } @Test @@ -62,13 +55,9 @@ void testResolveGlobalMetaWithNullConfig() { Mockito.when(config.getString(RestConstants.ALLOWED_HEADERS)).thenReturn(null); Mockito.when(config.getString(RestConstants.EXPOSED_HEADERS)).thenReturn(null); Mockito.when(config.getString(RestConstants.MAX_AGE)).thenReturn(null); - Mockito.when(config.getString(RestConstants.ALLOW_CREDENTIALS)).thenReturn(null); - Mockito.when(config.getString(RestConstants.ALLOW_PRIVATE_NETWORK)).thenReturn(null); - CorsMeta meta = CorsUtil.resolveGlobalMeta(config); + CorsMeta meta = CorsUtils.resolveGlobalMeta(config); Assertions.assertEquals(CorsMeta.DEFAULT_MAX_AGE, meta.getMaxAge()); - Assertions.assertFalse(meta.getAllowCredentials()); - Assertions.assertFalse(meta.getAllowPrivateNetwork()); Assertions.assertEquals(CorsMeta.DEFAULT_PERMIT_ALL, meta.getAllowedOrigins()); Assertions.assertEquals(CorsMeta.DEFAULT_PERMIT_METHODS, meta.getAllowedMethods()); Assertions.assertEquals(CorsMeta.DEFAULT_PERMIT_ALL, meta.getAllowedHeaders()); @@ -76,15 +65,15 @@ void testResolveGlobalMetaWithNullConfig() { @Test void testGetPortWithDefaultValues() { - Assertions.assertEquals(80, CorsUtil.getPort(RestConstants.HTTP, -1)); - Assertions.assertEquals(80, CorsUtil.getPort(RestConstants.WS, -1)); - Assertions.assertEquals(443, CorsUtil.getPort(RestConstants.HTTPS, -1)); - Assertions.assertEquals(443, CorsUtil.getPort(RestConstants.WSS, -1)); + Assertions.assertEquals(80, CorsUtils.getPort(CorsUtils.HTTP, -1)); + Assertions.assertEquals(80, CorsUtils.getPort(CorsUtils.WS, -1)); + Assertions.assertEquals(443, CorsUtils.getPort(CorsUtils.HTTPS, -1)); + Assertions.assertEquals(443, CorsUtils.getPort(CorsUtils.WSS, -1)); } @Test void testGetPortWithCustomValues() { - Assertions.assertEquals(8080, CorsUtil.getPort(RestConstants.HTTP, 8080)); - Assertions.assertEquals(8443, CorsUtil.getPort(RestConstants.HTTPS, 8443)); + Assertions.assertEquals(8080, CorsUtils.getPort(CorsUtils.HTTP, 8080)); + Assertions.assertEquals(8443, CorsUtils.getPort(CorsUtils.HTTPS, 8443)); } }