change escape way into encode

pull/251/head
cheese8 3 years ago
parent 30f57c527d
commit de8bdc3711

@ -18,10 +18,6 @@
package com.tencent.cloud.polaris.router.feign;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.reactive.LoadBalancerCommand;
@ -31,11 +27,17 @@ import com.tencent.cloud.common.util.ExpressionLabelUtils;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.RouterConstants;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer;
import org.springframework.util.CollectionUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* In order to pass router context for {@link com.tencent.cloud.polaris.router.PolarisLoadBalancerCompositeRule}.
*
@ -69,19 +71,16 @@ public class PolarisFeignLoadBalancer extends FeignLoadBalancer {
routerContext.setLabels(PolarisRouterContext.TRANSITIVE_LABELS, MetadataContextHolder.get()
.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE));
labelHeaderValues.forEach(labelHeaderValue -> {
Map<String, String> labels = JacksonUtils.deserialize2Map(labelHeaderValue);
if (!CollectionUtils.isEmpty(labels)) {
Map<String, String> unescapeLabels = new HashMap<>(labels.size());
for (Map.Entry<String, String> entry : labels.entrySet()) {
String escapedKey = ExpressionLabelUtils.unescape(entry.getKey());
String escapedValue = ExpressionLabelUtils.unescape(entry.getValue());
unescapeLabels.put(escapedKey, escapedValue);
}
routerContext.setLabels(PolarisRouterContext.RULE_ROUTER_LABELS, unescapeLabels);
}
});
Map<String, String> labelHeaderValuesMap = new HashMap<>();
try{
String labelHeaderValuesContent = labelHeaderValues.stream().findFirst().get();
labelHeaderValuesMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(labelHeaderValuesContent,
StandardCharsets.UTF_8.name())));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name());
}
routerContext.setLabels(PolarisRouterContext.RULE_ROUTER_LABELS, labelHeaderValuesMap);
return routerContext;
}

@ -18,17 +18,9 @@
package com.tencent.cloud.polaris.router.feign;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
import com.tencent.cloud.common.util.ExpressionLabelUtils;
import com.tencent.cloud.common.util.JacksonUtils;
import com.tencent.cloud.polaris.router.RouterConstants;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
@ -37,10 +29,19 @@ import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.util.CollectionUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Resolver labels from request.
*
@ -102,22 +103,19 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered
.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE);
labels.putAll(transitiveLabels);
// Because when the label is placed in RequestTemplate.header,
// RequestTemplate will parse the header according to the regular, which conflicts with the expression.
// Avoid conflicts by escaping.
Map<String, String> escapeLabels = new HashMap<>(labels.size());
for (Map.Entry<String, String> entry : labels.entrySet()) {
String escapedKey = ExpressionLabelUtils.escape(entry.getKey());
String escapedValue = ExpressionLabelUtils.escape(entry.getValue());
escapeLabels.put(escapedKey, escapedValue);
}
// pass label by header
if (escapeLabels.size() == 0) {
if (labels.size() == 0) {
requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER);
return;
}
requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER, JacksonUtils.serialize2Json(escapeLabels));
String encodedLabels;
try{
encodedLabels = URLEncoder.encode(JacksonUtils.serialize2Json(labels), StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name());
}
requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER, encodedLabels);
}
private Map<String, String> getRuleExpressionLabels(RequestTemplate requestTemplate, String peerService) {

@ -18,13 +18,6 @@
package com.tencent.cloud.polaris.router.feign;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.tencent.cloud.common.metadata.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
@ -44,6 +37,16 @@ import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
@ -114,19 +117,23 @@ public class RouterLabelFeignInterceptorTest {
when(metadataLocalProperties.getContent()).thenReturn(localMetadata);
routerLabelFeignInterceptor.apply(requestTemplate);
Collection<String> routerLabels = requestTemplate.headers().get(RouterConstants.ROUTER_LABEL_HEADER);
Assert.assertNotNull(routerLabels);
for (String value : routerLabels) {
Map<String, String> labels = unescape(JacksonUtils.deserialize2Map(value));
Assert.assertEquals("v1", labels.get("k1"));
Assert.assertEquals("v22", labels.get("k2"));
Assert.assertEquals("v3", labels.get("k3"));
Assert.assertEquals("v4", labels.get("k4"));
Assert.assertEquals(headerUidValue, labels.get("${http.header.uid}"));
Assert.assertEquals("", labels.get("${http.header.name}"));
Map<String, String> routerLabelsMap = new HashMap<>();
try{
String routerLabelContent = routerLabels.stream().findFirst().get();
routerLabelsMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(routerLabelContent, StandardCharsets.UTF_8.name())));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name());
}
Assert.assertNotNull(routerLabelsMap);
for (String value : routerLabelsMap.values()) {
Assert.assertEquals("v1", routerLabelsMap.get("k1"));
Assert.assertEquals("v22", routerLabelsMap.get("k2"));
Assert.assertEquals("v3", routerLabelsMap.get("k3"));
Assert.assertEquals("v4", routerLabelsMap.get("k4"));
Assert.assertEquals(headerUidValue, routerLabelsMap.get("${http.header.uid}"));
Assert.assertEquals("", routerLabelsMap.get("${http.header.name}"));
}
}
}

@ -18,17 +18,7 @@
package com.tencent.cloud.common.util;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
@ -37,6 +27,14 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* the utils for parse label expression.
*

Loading…
Cancel
Save