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 bb05e0d6ad fix: fix path-variable off-by-one and guard placeholder
substitution in rewrite plugin (#6882) (#6951)
bb05e0d6ad is described below
commit bb05e0d6ad94f599f523421ed1bce4067aa4d518
Author: Southern <[email protected]>
AuthorDate: Wed Sep 30 09:56:13 2026 +0800
fix: fix path-variable off-by-one and guard placeholder substitution in
rewrite plugin (#6882) (#6951)
1. Remove the "+1" when extracting the path-variable value from the URI, so
the
first character of the value is no longer truncated
(e.g. /http/findById/123 was rewritten to .../23, now .../123).
2. Only enter the placeholder-substitution branch when the regex also
contains
'{', so a replace template with '{' combined with a plain regex no
longer
throws StringIndexOutOfBoundsException (regex.substring(-1)) that
returned 500.
Co-authored-by: aias00 <[email protected]>
Co-authored-by: xiaoyu <[email protected]>
---
.../shenyu/plugin/rewrite/RewritePlugin.java | 2 +-
.../shenyu/plugin/rewrite/RewritePluginTest.java | 26 ++++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git
a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
index 486764f1e7..398443bd0e 100644
---
a/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
+++
b/shenyu-plugin/shenyu-plugin-rewrite/src/main/java/org/apache/shenyu/plugin/rewrite/RewritePlugin.java
@@ -76,7 +76,7 @@ public class RewritePlugin extends AbstractShenyuPlugin {
&& ThreadLocalRandom.current().nextInt(100) < percentage) {
rewriteUri = rewriteHandle.getReplace().contains("{") &&
rewriteHandle.getRegex().contains("{")
? PathMatchUtils.replaceAll(rewriteHandle.getReplace(),
rewriteHandle.getRegex().substring(rewriteHandle.getRegex().indexOf("{")),
-
rewriteUri.substring(rewriteHandle.getRegex().indexOf("{")))
+
rewriteUri.substring(rewriteHandle.getRegex().indexOf("{")))
: rewriteUri.replaceAll(rewriteHandle.getRegex(),
rewriteHandle.getReplace());
Map<String, Object> attributes = exchange.getAttributes();
if
(Optional.ofNullable(rewriteHandle.getRewriteMetaData()).orElse(false)) {
diff --git
a/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
b/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
index 3d9f75a3dc..5b5ec80bfc 100644
---
a/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-rewrite/src/test/java/org/apache/shenyu/plugin/rewrite/RewritePluginTest.java
@@ -88,6 +88,32 @@ public final class RewritePluginTest {
assertEquals("/shenyu/rewrite",
exchange.getAttributes().get(Constants.REWRITE_URI));
}
+ @Test
+ public void shouldRewritePathVariableWithCompleteValue() {
+ RuleData data = new RuleData();
+
data.setHandle("{\"regex\":\"/shenyu/{id}\",\"replace\":\"/shenyu/{id}\"}");
+ RewriteHandle rewriteHandle =
GsonUtils.getGson().fromJson(data.getHandle(), RewriteHandle.class);
+
RewritePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(data),
rewriteHandle);
+ ServerWebExchange rewriteExchange =
MockServerWebExchange.from(MockServerHttpRequest.get("/shenyu/123").build());
+ rewriteExchange.getAttributes().put(Constants.CONTEXT, new
ShenyuContext());
+ when(chain.execute(rewriteExchange)).thenReturn(Mono.empty());
+ SelectorData selectorData = mock(SelectorData.class);
+ StepVerifier.create(rewritePlugin.doExecute(rewriteExchange, chain,
selectorData, data)).expectSubscription().verifyComplete();
+ assertEquals("/shenyu/123",
rewriteExchange.getAttributes().get(Constants.REWRITE_URI));
+ }
+
+ @Test
+ public void shouldNotThrowWhenOnlyReplaceContainsPlaceholder() {
+ RuleData data = new RuleData();
+ data.setHandle("{\"regex\":\"/shenyu/.*\",\"replace\":\"/new/{id}\"}");
+ RewriteHandle rewriteHandle =
GsonUtils.getGson().fromJson(data.getHandle(), RewriteHandle.class);
+
RewritePluginDataHandler.CACHED_HANDLE.get().cachedHandle(CacheKeyUtils.INST.getKey(data),
rewriteHandle);
+ when(chain.execute(exchange)).thenReturn(Mono.empty());
+ SelectorData selectorData = mock(SelectorData.class);
+ StepVerifier.create(rewritePlugin.doExecute(exchange, chain,
selectorData, data)).expectSubscription().verifyComplete();
+ assertEquals("/new/{id}",
exchange.getAttributes().get(Constants.REWRITE_URI));
+ }
+
@Test
public void testSkip() {
final boolean result = rewritePlugin.skip(exchange);