This is an automated email from the ASF dual-hosted git repository.

Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new e27895d710 [ISSUE #6628] Preserve query when collapsing URI slashes 
(#7194)
e27895d710 is described below

commit e27895d710ab9ef188a6bb2fd186f67b270e4968
Author: Liming Deng <[email protected]>
AuthorDate: Wed Sep 30 12:12:52 2026 +0800

    [ISSUE #6628] Preserve query when collapsing URI slashes (#7194)
    
    * fix(web): preserve query when collapsing slashes
    
    * perf(web): reuse the repeated-slash pattern
---
 .../apache/shenyu/web/filter/CollapseSlashesFilter.java  | 11 +++++++++--
 .../shenyu/web/filter/CollapseSlashesFilterTest.java     | 16 +++++++++++++++-
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git 
a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CollapseSlashesFilter.java
 
b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CollapseSlashesFilter.java
index a8c4c1b840..60a7c7b27a 100644
--- 
a/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CollapseSlashesFilter.java
+++ 
b/shenyu-web/src/main/java/org/apache/shenyu/web/filter/CollapseSlashesFilter.java
@@ -21,21 +21,28 @@ import 
org.springframework.http.server.reactive.ServerHttpRequest;
 import org.springframework.web.server.ServerWebExchange;
 import org.springframework.web.server.WebFilter;
 import org.springframework.web.server.WebFilterChain;
+import org.springframework.web.util.UriComponentsBuilder;
 import reactor.core.publisher.Mono;
 
 import java.net.URI;
+import java.util.regex.Pattern;
 
 /**
  * The type Collapse slashes filter.
  */
 public class CollapseSlashesFilter implements WebFilter {
+
+    private static final Pattern REPEATED_SLASHES = Pattern.compile("/{2,}");
     
     @Override
     public Mono<Void> filter(final ServerWebExchange exchange, final 
WebFilterChain chain) {
         ServerHttpRequest request = exchange.getRequest();
-        String newPath = request.getURI().getRawPath().replaceAll("/{2,}", 
"/");
+        String newPath = 
REPEATED_SLASHES.matcher(request.getURI().getRawPath()).replaceAll("/");
         if (!request.getURI().getRawPath().equals(newPath)) {
-            URI newUri = request.getURI().resolve(newPath);
+            URI newUri = UriComponentsBuilder.fromUri(request.getURI())
+                    .replacePath(newPath)
+                    .build(true)
+                    .toUri();
             ServerHttpRequest newRequest = 
request.mutate().uri(newUri).build();
             return chain.filter(exchange.mutate().request(newRequest).build());
         }
diff --git 
a/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CollapseSlashesFilterTest.java
 
b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CollapseSlashesFilterTest.java
index 18331812a2..1acfe7141a 100644
--- 
a/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CollapseSlashesFilterTest.java
+++ 
b/shenyu-web/src/test/java/org/apache/shenyu/web/filter/CollapseSlashesFilterTest.java
@@ -19,6 +19,8 @@ package org.apache.shenyu.web.filter;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.springframework.http.HttpMethod;
 import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
 import org.springframework.mock.web.server.MockServerWebExchange;
 import org.springframework.web.server.ServerWebExchange;
@@ -26,8 +28,12 @@ import org.springframework.web.server.WebFilterChain;
 import reactor.core.publisher.Mono;
 import reactor.test.StepVerifier;
 
+import java.net.URI;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 /**
@@ -48,8 +54,16 @@ public final class CollapseSlashesFilterTest {
 
     @Test
     public void filter() {
-        ServerWebExchange webExchange = 
MockServerWebExchange.from(MockServerHttpRequest.post("http://localhost:8080///////test";));
+        ServerWebExchange webExchange = MockServerWebExchange.from(
+                MockServerHttpRequest.method(HttpMethod.POST,
+                        
URI.create("http://localhost:8080///////test?name=shenyu%20gateway#section";)));
         Mono<Void> filter = collapseSlashesFilter.filter(webExchange, 
webFilterChain);
         StepVerifier.create(filter).verifyComplete();
+
+        ArgumentCaptor<ServerWebExchange> exchangeCaptor = 
ArgumentCaptor.forClass(ServerWebExchange.class);
+        verify(webFilterChain).filter(exchangeCaptor.capture());
+        assertEquals("/test", 
exchangeCaptor.getValue().getRequest().getURI().getRawPath());
+        assertEquals("name=shenyu%20gateway", 
exchangeCaptor.getValue().getRequest().getURI().getRawQuery());
+        assertEquals("section", 
exchangeCaptor.getValue().getRequest().getURI().getRawFragment());
     }
 }

Reply via email to