Skip to content

port #2899 to 7.X#2900

Merged
rrayst merged 2 commits intomasterfrom
7-X-path-prefix-trailing-slash
Mar 31, 2026
Merged

port #2899 to 7.X#2900
rrayst merged 2 commits intomasterfrom
7-X-path-prefix-trailing-slash

Conversation

@christiangoerdes
Copy link
Copy Markdown
Collaborator

@christiangoerdes christiangoerdes commented Mar 31, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Normalized OpenAPI server/base paths to consistently include trailing slashes, improving duplicate-path detection and base-path routing.
    • Improved path-segment boundary checks to prevent incorrect matches (e.g., treat "/foo/" as distinct from "/foobar").
  • Tests

    • Added and updated tests covering trailing-slash normalization and exact base-path matching scenarios.

@christiangoerdes
Copy link
Copy Markdown
Collaborator Author

/ok-to-test

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 81f9df10-c8cd-4864-add7-56666a8ee5ae

📥 Commits

Reviewing files that changed from the base of the PR and between bf3f8c9 and 97f3005.

📒 Files selected for processing (1)
  • distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/OfflineExampleTest.java
✅ Files skipped from review due to trivial changes (1)
  • distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/OfflineExampleTest.java

📝 Walkthrough

Walkthrough

Normalized OpenAPI server/base paths to always include a trailing slash for duplicate-path detection and base-path storage; added UriUtil.ensureTrailingSlash(...); updated APIProxy usage and tests to expect trailing-slash-normalized paths.

Changes

Cohort / File(s) Summary
Path normalization logic
core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java, core/src/main/java/com/predic8/membrane/core/openapi/util/UriUtil.java
Replaced path extraction with getServerPathPrefix(...) and applied ensureTrailingSlash(...) when deriving server/OpenAPI base paths and when inserting keys into internal paths map.
Unit tests — API proxy / interceptor
core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxyKeyComplexMatchTest.java, core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptorTest.java
Added test for complex match with base path ending in /; updated expected base-path values to include trailing /; added new exact-match test for server path with trailing slash.
Unit tests — URI util
core/src/test/java/com/predic8/membrane/core/openapi/util/UriUtilTest.java
Added test rootTrailingSlash to validate ensureTrailingSlash for non-root, root, and empty inputs.
Integration/example test
distribution/src/test/java/com/predic8/membrane/examples/withoutinternet/OfflineExampleTest.java
Adjusted request URL in test from /shop/v2 to /shop/v2/ to match normalized trailing-slash behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Add tests for offline example #2465 — modifies the same offline example test URL (OfflineExampleTest) to use a trailing slash; closely related to trailing-slash test adjustments.

Suggested reviewers

  • predic8
  • rrayst

Poem

🐰
I hopped through paths both short and long,
Gave every route a trailing song,
A slash at end to mark the place,
Now routes align in tidy grace,
Hooray — keep hopping, code and pace!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'port #2899 to 7.X' is vague and does not clearly convey what changes are being made. It references a previous issue number but provides no meaningful description of the actual modifications. Revise the title to describe the actual change, such as 'Normalize server path prefixes with trailing slash handling' or 'Ensure trailing slashes in OpenAPI base path URLs'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 7-X-path-prefix-trailing-slash

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@membrane-ci-server
Copy link
Copy Markdown

This pull request needs "/ok-to-test" from an authorized committer.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java (1)

203-209: ⚠️ Potential issue | 🟡 Minor

Verify that requests to exact base path without trailing slash are intentionally rejected.

The test suite explicitly covers requests to /foo/ matching base path /foo/ (OpenAPIInterceptorTest.getMatchingBasePathExactServerPath), but provides no test case for requests to /foo (without trailing slash) against the same base path. Since OpenAPIInterceptor.getMatchingBasePath() uses startsWith() without normalizing the incoming request URI, a request to /foo will not match /foo/ and will return 404.

This is likely intentional for correct path segment boundary detection, but confirm this doesn't break existing clients that access the base path without a trailing slash and whether a redirect or fallback behavior is needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java`
around lines 203 - 209, The code currently enforces a trailing slash for server
base paths via getServerPathPrefix (ensureTrailingSlash(new
URIFactory(true).create(server.getUrl()).getPath())), which causes
OpenAPIInterceptor.getMatchingBasePath() (which uses startsWith() on the raw
request URI) to reject requests to the exact base without a trailing slash;
update behavior by either normalizing incoming request paths before matching or
by treating the base prefix both with and without the trailing slash as valid
matches and/or emitting a redirect for the slash-missing case; add a unit test
covering a request to "/foo" against a base path "/foo/" and modify
getMatchingBasePath to compare normalized paths (or implement a 301 redirect) so
clients hitting the base without trailing slash are handled consistently.
🧹 Nitpick comments (1)
core/src/test/java/com/predic8/membrane/core/openapi/util/UriUtilTest.java (1)

60-65: Consider adding test cases for null input and paths already ending with /.

The ensureTrailingSlash implementation handles null input (returning "/") and paths that already end with / (returning unchanged), but these scenarios aren't tested.

🧪 Suggested additional assertions
 `@Test`
 public void rootTrailingSlash() {
     assertEquals("/foo/bar/", ensureTrailingSlash("/foo/bar"));
     assertEquals("/", ensureTrailingSlash("/"));
     assertEquals("/", ensureTrailingSlash(""));
+    assertEquals("/", ensureTrailingSlash(null));
+    assertEquals("/foo/bar/", ensureTrailingSlash("/foo/bar/"));  // already has trailing slash
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/src/test/java/com/predic8/membrane/core/openapi/util/UriUtilTest.java`
around lines 60 - 65, Add test assertions in UriUtilTest for the
ensureTrailingSlash method to cover null input and inputs already ending with a
slash: call ensureTrailingSlash(null) and assert it returns "/" and call
ensureTrailingSlash("/foo/") (and maybe "/" again) and assert it returns the
same string unchanged; place these new assertions inside the existing
rootTrailingSlash test or a new test method to ensure null and
already-trailing-slash cases are verified.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java`:
- Around line 203-209: The code currently enforces a trailing slash for server
base paths via getServerPathPrefix (ensureTrailingSlash(new
URIFactory(true).create(server.getUrl()).getPath())), which causes
OpenAPIInterceptor.getMatchingBasePath() (which uses startsWith() on the raw
request URI) to reject requests to the exact base without a trailing slash;
update behavior by either normalizing incoming request paths before matching or
by treating the base prefix both with and without the trailing slash as valid
matches and/or emitting a redirect for the slash-missing case; add a unit test
covering a request to "/foo" against a base path "/foo/" and modify
getMatchingBasePath to compare normalized paths (or implement a 301 redirect) so
clients hitting the base without trailing slash are handled consistently.

---

Nitpick comments:
In `@core/src/test/java/com/predic8/membrane/core/openapi/util/UriUtilTest.java`:
- Around line 60-65: Add test assertions in UriUtilTest for the
ensureTrailingSlash method to cover null input and inputs already ending with a
slash: call ensureTrailingSlash(null) and assert it returns "/" and call
ensureTrailingSlash("/foo/") (and maybe "/" again) and assert it returns the
same string unchanged; place these new assertions inside the existing
rootTrailingSlash test or a new test method to ensure null and
already-trailing-slash cases are verified.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2cd7478d-3312-4aaa-939d-1b1042bf557d

📥 Commits

Reviewing files that changed from the base of the PR and between 005aa54 and bf3f8c9.

📒 Files selected for processing (5)
  • core/src/main/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxy.java
  • core/src/main/java/com/predic8/membrane/core/openapi/util/UriUtil.java
  • core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/APIProxyKeyComplexMatchTest.java
  • core/src/test/java/com/predic8/membrane/core/openapi/serviceproxy/OpenAPIInterceptorTest.java
  • core/src/test/java/com/predic8/membrane/core/openapi/util/UriUtilTest.java

@rrayst rrayst merged commit bb6a3b8 into master Mar 31, 2026
5 checks passed
@rrayst rrayst deleted the 7-X-path-prefix-trailing-slash branch March 31, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants