[Bug]: request-rewrite ReplacePrefixMatch treats "/api" as a prefix of "/api2/...", and drops a slash when the operation path ends with "/"
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- go
- Domain
- backend-api-design
Research direction
The issue points to policies/request-rewrite/requestrewrite.go and provides two regression tests for applyPathRewrite. Start by reading that function and run the shown go test command under policies/request-rewrite. Done means /api leaves /api2/users unchanged and /api/ rewrites /api/users to /v2/users; add tests for both cases.
Written by the indexing model from the issue text.
Description
Description
applyPathRewrite for ReplacePrefixMatch (wso2/gateway-controllers, policies/request-rewrite/requestrewrite.go) decides whether to rewrite with a raw string prefix check:
if !strings.HasPrefix(currentPath, operationPath) {
return currentPath
}
remainder := strings.TrimPrefix(currentPath, operationPath)
return cfg.ReplacePrefixMatch + remainder
That is not path-segment aware. Measured failures on main (4cf9570):
| operationPath | currentPath | ReplacePrefixMatch | Actual result | Expected |
|---|---|---|---|---|
/api |
/api2/users |
/v2 |
/v22/users |
unchanged /api2/users |
/api |
/api/users |
/v2 |
/v2/users |
/v2/users (OK) |
/api/ |
/api/users |
/v2 |
/v2users |
/v2/users |
So a short resource prefix silently rewrites longer sibling paths (/api vs /api2), and an operation path that ends with / concatenates without keeping a path separator. Envoy and most gateways treat prefix rewrite as a path-prefix match that ends on a / or end-of-path boundary.
Steps to Reproduce
Under policies/request-rewrite on 4cf9570:
func TestReplacePrefixMatchOverlappingPath(t *testing.T) {
cfg := &pathRewrite{Type: "REPLACEPREFIXMATCH", ReplacePrefixMatch: "/v2"}
got := applyPathRewrite("/api", "/api2/users", cfg)
if got != "/api2/users" {
t.Fatalf("prefix /api must not match /api2/users; got %q", got)
}
}
func TestReplacePrefixMatchTrailingSlashOnOperation(t *testing.T) {
cfg := &pathRewrite{Type: "REPLACEPREFIXMATCH", ReplacePrefixMatch: "/v2"}
got := applyPathRewrite("/api/", "/api/users", cfg)
if got != "/v2/users" {
t.Fatalf("got %q want /v2/users", got)
}
}
go test -run 'TestReplacePrefixMatchOverlapping|TestReplacePrefixMatchTrailing' -v .
Severity Level of the Issue
Severity/Major (Important functionality is broken. Should be prioritized. Doesn't need immediate attention)
Environment Details (with versions)
- wso2/gateway-controllers main
4cf9570(request-rewrite policy; sdk/core as in that module'sgo.mod) - Go 1.26.x, Linux x86_64
Related Issues
#1297 covers invalid regex / unsupported type silent no-op and query reordering. It does not mention prefix-boundary or trailing-slash concatenation. No other open issue found for ReplacePrefixMatch overlapping paths.
Possible Solution
- Match only when
currentPath == operationPathorcurrentPathcontinues with/after the operation prefix (after normalizing a trailing/on the operation path). - When joining
ReplacePrefixMatchand the remainder, ensure exactly one/between them. - Add the two regression tests above.
op := strings.TrimSuffix(operationPath, "/")
if currentPath != op && !strings.HasPrefix(currentPath, op+"/") {
return currentPath
}
remainder := strings.TrimPrefix(currentPath, op)
repl := strings.TrimSuffix(cfg.ReplacePrefixMatch, "/")
if remainder == "" {
return repl
}
return repl + remainder
I'm happy to send a PR.
- Dominant language
- Go
- Stars
- 79
- Forks
- 130
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 165
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from wso2/api-platform
-
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
wso2/api-platform#3917 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
wso2/api-platform#3916 ·
Maintainers usually reply within 1 day
-
[Bug]: ap gateway image build cannot find local policies on WindowsPossibly taken @Jayzilva claimed this 1 day ago. OpenAspect/Configuration Severity/Major
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
wso2/api-platform#3912 ·
Maintainers usually reply within 1 day
-
Aspect/API Severity/Minor
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
wso2/api-platform#3909 ·
Maintainers usually reply within 1 day
-
Aspect/API Aspect/UI Severity/Minor Type/Bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
wso2/api-platform#3904 ·
Maintainers usually reply within 1 day
All issues in wso2/api-platform
Similar issues
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 61/100
Maintainers usually reply within 1 day
-
stage-fail
Difficulty 1/5 Under an hour Newbie friendliness 72/100
siyuan-note/bazaar#2405 ·
Maintainers usually reply within 1 day
-
bug priority: high workstream:cache
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
rossoctl/context-guru#707 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
prime-radiant-inc/evener#5028 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
Maintainers usually reply within 1 day