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; 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.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.reactive.LoadBalancerCommand; 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.common.util.JacksonUtils;
import com.tencent.cloud.polaris.router.PolarisRouterContext; import com.tencent.cloud.polaris.router.PolarisRouterContext;
import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterConstants;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector; import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer; import org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer;
import org.springframework.util.CollectionUtils; 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}. * 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() routerContext.setLabels(PolarisRouterContext.TRANSITIVE_LABELS, MetadataContextHolder.get()
.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE)); .getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE));
labelHeaderValues.forEach(labelHeaderValue -> { Map<String, String> labelHeaderValuesMap = new HashMap<>();
Map<String, String> labels = JacksonUtils.deserialize2Map(labelHeaderValue); try{
if (!CollectionUtils.isEmpty(labels)) { String labelHeaderValuesContent = labelHeaderValues.stream().findFirst().get();
Map<String, String> unescapeLabels = new HashMap<>(labels.size()); labelHeaderValuesMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(labelHeaderValuesContent,
for (Map.Entry<String, String> entry : labels.entrySet()) { StandardCharsets.UTF_8.name())));
String escapedKey = ExpressionLabelUtils.unescape(entry.getKey()); } catch (UnsupportedEncodingException e) {
String escapedValue = ExpressionLabelUtils.unescape(entry.getValue()); throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name());
unescapeLabels.put(escapedKey, escapedValue); }
} routerContext.setLabels(PolarisRouterContext.RULE_ROUTER_LABELS, labelHeaderValuesMap);
routerContext.setLabels(PolarisRouterContext.RULE_ROUTER_LABELS, unescapeLabels);
}
});
return routerContext; return routerContext;
} }

@ -18,17 +18,9 @@
package com.tencent.cloud.polaris.router.feign; 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.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; 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.common.util.JacksonUtils;
import com.tencent.cloud.polaris.router.RouterConstants; import com.tencent.cloud.polaris.router.RouterConstants;
import com.tencent.cloud.polaris.router.RouterRuleLabelResolver; import com.tencent.cloud.polaris.router.RouterRuleLabelResolver;
@ -37,10 +29,19 @@ import feign.RequestInterceptor;
import feign.RequestTemplate; import feign.RequestTemplate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.util.CollectionUtils; 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. * Resolver labels from request.
* *
@ -102,22 +103,19 @@ public class RouterLabelFeignInterceptor implements RequestInterceptor, Ordered
.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); .getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE);
labels.putAll(transitiveLabels); 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 // pass label by header
if (escapeLabels.size() == 0) { if (labels.size() == 0) {
requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER); requestTemplate.header(RouterConstants.ROUTER_LABEL_HEADER);
return; 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) { private Map<String, String> getRuleExpressionLabels(RequestTemplate requestTemplate, String peerService) {

@ -18,13 +18,6 @@
package com.tencent.cloud.polaris.router.feign; 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.MetadataContext;
import com.tencent.cloud.common.metadata.MetadataContextHolder; import com.tencent.cloud.common.metadata.MetadataContextHolder;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
@ -44,6 +37,16 @@ import org.mockito.MockedStatic;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner; 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.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -114,19 +117,23 @@ public class RouterLabelFeignInterceptorTest {
when(metadataLocalProperties.getContent()).thenReturn(localMetadata); when(metadataLocalProperties.getContent()).thenReturn(localMetadata);
routerLabelFeignInterceptor.apply(requestTemplate); routerLabelFeignInterceptor.apply(requestTemplate);
Collection<String> routerLabels = requestTemplate.headers().get(RouterConstants.ROUTER_LABEL_HEADER); Collection<String> routerLabels = requestTemplate.headers().get(RouterConstants.ROUTER_LABEL_HEADER);
Map<String, String> routerLabelsMap = new HashMap<>();
Assert.assertNotNull(routerLabels); try{
for (String value : routerLabels) { String routerLabelContent = routerLabels.stream().findFirst().get();
Map<String, String> labels = unescape(JacksonUtils.deserialize2Map(value)); routerLabelsMap.putAll(JacksonUtils.deserialize2Map(URLDecoder.decode(routerLabelContent, StandardCharsets.UTF_8.name())));
} catch (UnsupportedEncodingException e) {
Assert.assertEquals("v1", labels.get("k1")); throw new RuntimeException("unsupported charset exception " + StandardCharsets.UTF_8.name());
Assert.assertEquals("v22", labels.get("k2")); }
Assert.assertEquals("v3", labels.get("k3")); Assert.assertNotNull(routerLabelsMap);
Assert.assertEquals("v4", labels.get("k4")); for (String value : routerLabelsMap.values()) {
Assert.assertEquals(headerUidValue, labels.get("${http.header.uid}")); Assert.assertEquals("v1", routerLabelsMap.get("k1"));
Assert.assertEquals("", labels.get("${http.header.name}")); 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; 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.apache.commons.lang.StringUtils;
import org.springframework.http.HttpCookie; import org.springframework.http.HttpCookie;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest; import org.springframework.http.HttpRequest;
@ -37,6 +27,14 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange; 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. * the utils for parse label expression.
* *

Loading…
Cancel
Save