fix:fix header validation when using Chinese char. (#1167)

pull/1172/head
Haotian Zhang 1 year ago committed by GitHub
parent eea8d3b0c6
commit fd9ebd09ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,3 +11,4 @@
- [feat:add swagger report switch.](https://github.com/Tencent/spring-cloud-tencent/pull/1147)
- [fix: dynamic routing using cookies.](https://github.com/Tencent/spring-cloud-tencent/pull/1152)
- [fix:fix retry loadbalancer not working bug.](https://github.com/Tencent/spring-cloud-tencent/pull/1157)
- [fix:fix header validation when using Chinese char.](https://github.com/Tencent/spring-cloud-tencent/pull/1167)

@ -47,8 +47,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT,
classes = EncodeTransferMedataFeignInterceptorTest.TestApplication.class,
properties = {"server.port=18081",
"spring.config.location = classpath:application-test.yml",
properties = {"server.port=48081", "spring.config.location = classpath:application-test.yml",
"spring.main.web-application-type = servlet",
"spring.cloud.gateway.enabled = false"})
public class EncodeTransferMedataFeignInterceptorTest {
@ -77,7 +76,7 @@ public class EncodeTransferMedataFeignInterceptorTest {
return MetadataContextHolder.get().getContext(MetadataContext.FRAGMENT_TRANSITIVE, "b");
}
@FeignClient(name = "test-feign", url = "http://localhost:18081")
@FeignClient(name = "test-feign", url = "http://localhost:48081")
public interface TestFeign {
@RequestMapping("/test")

@ -47,7 +47,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT, classes = ConfigChangeListenerTest.TestApplication.class,
properties = {"server.port=8081", "spring.config.location = classpath:application-test.yml"})
properties = {"server.port=48081", "spring.config.location = classpath:application-test.yml"})
public class ConfigChangeListenerTest {
private static final CountDownLatch hits = new CountDownLatch(2);

@ -58,7 +58,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT, classes = PolarisConfigRefreshOptimizationListenerNotTriggeredTest.TestApplication.class,
properties = {
"server.port=8081",
"server.port=48081",
"spring.cloud.polaris.address=grpc://127.0.0.1:10081",
"spring.cloud.polaris.config.connect-remote-server=false",
"spring.cloud.polaris.config.refresh-type=reflect",

@ -59,7 +59,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT, classes = PolarisConfigRefreshOptimizationListenerTriggeredTest.TestApplication.class,
properties = {
"server.port=8081",
"server.port=48081",
"spring.cloud.polaris.address=grpc://127.0.0.1:10081",
"spring.cloud.polaris.config.connect-remote-server=false",
"spring.cloud.polaris.config.refresh-type=reflect",

@ -18,6 +18,8 @@
package com.tencent.cloud.polaris.ratelimit.filter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Objects;
@ -51,6 +53,8 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* Reactive filter to check quota.
*
@ -58,7 +62,7 @@ import org.springframework.web.server.WebFilterChain;
*/
public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
private static final Logger LOGGER = LoggerFactory.getLogger(QuotaCheckReactiveFilter.class);
private static final Logger LOG = LoggerFactory.getLogger(QuotaCheckReactiveFilter.class);
private final LimitAPI limitAPI;
@ -122,22 +126,28 @@ public class QuotaCheckReactiveFilter implements WebFilter, Ordered {
response.getHeaders()
.add(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc());
if (Objects.nonNull(quotaResponse.getActiveRule())) {
response.getHeaders()
.add(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, quotaResponse.getActiveRule().getName()
.getValue());
try {
String encodedActiveRuleName = URLEncoder.encode(
quotaResponse.getActiveRule().getName().getValue(), UTF_8);
response.getHeaders().add(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, encodedActiveRuleName);
}
catch (UnsupportedEncodingException e) {
LOG.error("Cannot encode {} for header internal-callee-activerule.",
quotaResponse.getActiveRule().getName().getValue(), e);
}
}
return response.writeWith(Mono.just(dataBuffer));
}
// Unirate
if (quotaResponse.getCode() == QuotaResultCode.QuotaResultOk && quotaResponse.getWaitMs() > 0) {
LOGGER.debug("The request of [{}] will waiting for {}ms.", path, quotaResponse.getWaitMs());
LOG.debug("The request of [{}] will waiting for {}ms.", path, quotaResponse.getWaitMs());
waitMs = quotaResponse.getWaitMs();
}
}
catch (Throwable t) {
// An exception occurs in the rate limiting API call,
// which should not affect the call of the business process.
LOGGER.error("fail to invoke getQuota, service is " + localService, t);
LOG.error("fail to invoke getQuota, service is " + localService, t);
}
if (waitMs > 0) {

@ -19,6 +19,8 @@
package com.tencent.cloud.polaris.ratelimit.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Objects;
import java.util.Set;
@ -50,6 +52,8 @@ import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.filter.OncePerRequestFilter;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
/**
* Servlet filter to check quota.
*
@ -115,8 +119,15 @@ public class QuotaCheckServletFilter extends OncePerRequestFilter {
}
response.addHeader(HeaderConstant.INTERNAL_CALLEE_RET_STATUS, RetStatus.RetFlowControl.getDesc());
if (Objects.nonNull(quotaResponse.getActiveRule())) {
response.addHeader(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, quotaResponse.getActiveRule().getName()
.getValue());
try {
String encodedActiveRuleName = URLEncoder.encode(
quotaResponse.getActiveRule().getName().getValue(), UTF_8);
response.addHeader(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, encodedActiveRuleName);
}
catch (UnsupportedEncodingException e) {
LOG.error("Cannot encode {} for header internal-callee-activerule.",
quotaResponse.getActiveRule().getName().getValue(), e);
}
}
return;
}

@ -45,7 +45,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = DEFINED_PORT, classes = SCGPluginsAutoConfigurationTest.TestApplication.class,
properties = {"server.port=8081", "spring.config.location = classpath:application-test.yml",
properties = {"server.port=48081", "spring.config.location = classpath:application-test.yml",
"spring.cloud.tencent.plugin.scg.staining.rule-staining.enabled = true"})
public class SCGPluginsAutoConfigurationTest {

@ -79,6 +79,7 @@ public final class PolarisEnhancedPluginUtils {
private static final List<HttpStatus> HTTP_STATUSES = toList(NOT_IMPLEMENTED, BAD_GATEWAY,
SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, HTTP_VERSION_NOT_SUPPORTED, VARIANT_ALSO_NEGOTIATES,
INSUFFICIENT_STORAGE, LOOP_DETECTED, BANDWIDTH_LIMIT_EXCEEDED, NOT_EXTENDED, NETWORK_AUTHENTICATION_REQUIRED);
private PolarisEnhancedPluginUtils() {
}
@ -216,7 +217,15 @@ public final class PolarisEnhancedPluginUtils {
if (headers != null && headers.containsKey(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME)) {
Collection<String> values = headers.get(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME);
if (CollectionUtils.isNotEmpty(values)) {
return com.tencent.polaris.api.utils.StringUtils.defaultString(new ArrayList<>(values).get(0));
String decodedActiveRuleName = "";
try {
decodedActiveRuleName = URLDecoder.decode(new ArrayList<>(values).get(0), UTF_8);
}
catch (UnsupportedEncodingException e) {
LOG.error("Cannot decode {} from header internal-callee-activerule.",
headers.get(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME).get(0), e);
}
return com.tencent.polaris.api.utils.StringUtils.defaultString(decodedActiveRuleName);
}
}
return "";

@ -17,9 +17,11 @@
package com.tencent.cloud.rpc.enhancement.plugin;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
@ -46,6 +48,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import static com.tencent.cloud.common.constant.ContextConstant.UTF_8;
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER;
import static org.assertj.core.api.Assertions.assertThat;
@ -324,13 +327,14 @@ public class PolarisEnhancedPluginUtilsTest {
}
@Test
public void testGetActiveRuleNameFromRequest() {
public void testGetActiveRuleNameFromRequest() throws UnsupportedEncodingException {
HttpHeaders headers = new HttpHeaders();
String ruleName = PolarisEnhancedPluginUtils.getActiveRuleNameFromRequest(headers);
assertThat(ruleName).isEqualTo("");
headers.set(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, "mock_rule");
String encodedRuleName = URLEncoder.encode("mock_rule", UTF_8);
headers.set(HeaderConstant.INTERNAL_ACTIVE_RULE_NAME, encodedRuleName);
ruleName = PolarisEnhancedPluginUtils.getActiveRuleNameFromRequest(headers);
assertThat(ruleName).isEqualTo("mock_rule");
}

Loading…
Cancel
Save