Skip to content

Commit

Permalink
fix:fix header validation when using Chinese char.
Browse files Browse the repository at this point in the history
  • Loading branch information
SkyeBeFreeman committed Oct 13, 2023
1 parent eea8d3b commit 37cce7c
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@
@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 {
Expand Down Expand Up @@ -77,7 +76,7 @@ public String test() {
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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
*/
@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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
@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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
@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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -51,14 +53,16 @@
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.
*
* @author Haotian Zhang, lepdou, cheese8, kaiy
*/
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;

Expand Down Expand Up @@ -122,22 +126,28 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -50,6 +52,8 @@
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.
*
Expand Down Expand Up @@ -115,8 +119,15 @@ protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull Ht
}
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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
*/
@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 {

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

}
Expand Down Expand Up @@ -216,7 +217,15 @@ static String getActiveRuleNameFromRequest(HttpHeaders headers) {
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 "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -46,6 +48,7 @@
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;
Expand Down Expand Up @@ -324,13 +327,14 @@ public void testGetRetStatusFromRequest() {
}

@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");
}
Expand Down

0 comments on commit 37cce7c

Please sign in to comment.