Skip to content

Commit

Permalink
Merge pull request #9 from Rawven/3.3-triple-cors
Browse files Browse the repository at this point in the history
3.3 triple cors
  • Loading branch information
Rawven authored Apr 24, 2024
2 parents 7264e00 + e1b4a7f commit 4aa3faa
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 422 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -120,6 +121,7 @@ public class ExtensionLoader<T> {

private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();

private final ReentrantLock loadExtensionClassesLock = new ReentrantLock();
private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();

private final Map<String, Object> cachedActivates = Collections.synchronizedMap(new LinkedHashMap<>());
Expand Down Expand Up @@ -951,7 +953,8 @@ private Class<?> getExtensionClass(String name) {
private Map<String, Class<?>> getExtensionClasses() {
Map<String, Class<?>> classes = cachedClasses.get();
if (classes == null) {
synchronized (cachedClasses) {
loadExtensionClassesLock.lock();
try {
classes = cachedClasses.get();
if (classes == null) {
try {
Expand All @@ -968,6 +971,8 @@ private Map<String, Class<?>> getExtensionClasses() {
}
cachedClasses.set(classes);
}
} finally {
loadExtensionClassesLock.unlock();
}
}
return classes;
Expand Down
44 changes: 12 additions & 32 deletions dubbo-common/src/main/java/org/apache/dubbo/config/CorsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,73 +21,53 @@
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;
}

public void setMaxAge(Long maxAge) {
this.maxAge = maxAge;
}

public Boolean getAllowPrivateNetWork() {
return allowPrivateNetWork;
}

public void setAllowPrivateNetWork(Boolean allowPrivateNetWork) {
this.allowPrivateNetWork = allowPrivateNetWork;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

Expand All @@ -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();
}

Expand All @@ -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());
Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,6 @@ public class CorsMeta {
@Nullable
private List<String> exposedHeaders;

@Nullable
private Boolean allowCredentials;

@Nullable
private Boolean allowPrivateNetwork;

@Nullable
private Long maxAge;

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand All @@ -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
Expand All @@ -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);
}
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
Loading

0 comments on commit 4aa3faa

Please sign in to comment.