Skip to content

🐛 bug: preserve mounted sub-app regex handler during mount prefixing#4308

Merged
ReneWerner87 merged 2 commits into
mainfrom
fix-mounted-routes-regex-engine-issue
May 22, 2026
Merged

🐛 bug: preserve mounted sub-app regex handler during mount prefixing#4308
ReneWerner87 merged 2 commits into
mainfrom
fix-mounted-routes-regex-engine-issue

Conversation

@gaby

@gaby gaby commented May 22, 2026

Copy link
Copy Markdown
Member

Motivation

  • Mounted sub-app routes were being reparsed using the parent app's regex handler when the mount prefix was added, which can change route constraint semantics and break security-sensitive regex behavior.
  • The change ensures per-App RegexHandler semantics are preserved for routes cloned from mounted sub-apps so a sub-app's constraints are not silently recompiled under a different engine.

Description

  • Changed addPrefixToRoute signature to accept an explicit regexHandler and variadic customConstraints and use them when reparsing the prefixed path.
  • Updated mount processing to pass the sub-app's config.RegexHandler and customConstraints when cloning and prefixing sub-app routes so the sub-app's regex configuration is preserved.
  • Added Test_App_Mount_PreservesSubAppRegexHandler to mount_test.go which verifies a mounted route retains the sub-app's regex behavior when the parent uses a different handler.

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 22d0a9e8-f753-4d8a-9771-8865c24fb98f

📥 Commits

Reviewing files that changed from the base of the PR and between f2ce702 and 25fd939.

📒 Files selected for processing (2)
  • domain.go
  • mount_test.go

Walkthrough

Thread mounted apps' RegexHandler and customConstraints through route prefixing so mounted routes use the mounted app's regex/constraint configuration during parsing and matching.

Changes

Sub-app regex handler preservation

Layer / File(s) Summary
Route parser configuration pass-through
router.go
addPrefixToRoute now accepts regexHandler and customConstraints and uses them when initializing route.routeParser instead of the parent app's config.
Mount integration and validation
mount.go, domain.go, mount_test.go
Mount site and wrapper app creation forward the mounted app's RegexHandler; tests (and import) added to verify mounted sub-app routes preserve their own regex handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • sixcolors
  • ReneWerner87
  • efectn

Poem

🐰 I hopped through routes both near and far,
Mounted a sub-app beneath a star,
Its regex intact, constraints stayed true,
Parent's shadow no longer drew—
Hooray! My routes now match as due.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically identifies the bug being fixed: preserving regex handler semantics for mounted sub-apps during mount prefixing.
Description check ✅ Passed The description provides clear motivation, technical details of changes, and confirms test coverage, though some template sections like benchmarks and documentation updates are not addressed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 fix-mounted-routes-regex-engine-issue

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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.

@ReneWerner87 ReneWerner87 added this to v3 May 22, 2026
@ReneWerner87 ReneWerner87 added this to the v3 milestone May 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
mount_test.go (1)

38-44: ⚡ Quick win

Add a positive-control assertion to harden this regression test.

Right now, both assertions are negative (StatusNotFound), so the test can still pass if the route is broken and never matches. Add one StatusOK check for ALLOW (direct and/or mounted) before the lowercase checks.

Suggested test hardening
 func Test_App_Mount_PreservesSubAppRegexHandler(t *testing.T) {
 	t.Parallel()
@@
 	parent.Use("/mounted", sub)
 
+	resp, err := sub.Test(httptest.NewRequest(MethodGet, "/resource/ALLOW", http.NoBody))
+	require.NoError(t, err)
+	require.Equal(t, StatusOK, resp.StatusCode)
+
+	resp, err = parent.Test(httptest.NewRequest(MethodGet, "/mounted/resource/ALLOW", http.NoBody))
+	require.NoError(t, err)
+	require.Equal(t, StatusOK, resp.StatusCode)
+
 	resp, err := sub.Test(httptest.NewRequest(MethodGet, "/resource/allow", http.NoBody))
 	require.NoError(t, err)
 	require.Equal(t, StatusNotFound, resp.StatusCode)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mount_test.go` around lines 38 - 44, Add a positive-control assertion that
verifies the ALLOW route actually matches before the lowercase negative checks:
call sub.Test and parent.Test with MethodGet for "/resource/allow" (and/or
"/mounted/resource/allow") and assert StatusOK before the existing
require.Equal(t, StatusNotFound, ...) assertions that check the lowercase
variants; update the references to resp, err, httptest.NewRequest, MethodGet,
StatusOK and StatusNotFound around the sub.Test and parent.Test calls so the
test fails if the route is broken rather than silently passing only on 404s.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@mount_test.go`:
- Around line 38-44: Add a positive-control assertion that verifies the ALLOW
route actually matches before the lowercase negative checks: call sub.Test and
parent.Test with MethodGet for "/resource/allow" (and/or
"/mounted/resource/allow") and assert StatusOK before the existing
require.Equal(t, StatusNotFound, ...) assertions that check the lowercase
variants; update the references to resp, err, httptest.NewRequest, MethodGet,
StatusOK and StatusNotFound around the sub.Test and parent.Test calls so the
test fails if the route is broken rather than silently passing only on 404s.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8afe111b-bdb9-4e6e-8406-9d0046e3bb54

📥 Commits

Reviewing files that changed from the base of the PR and between ee0c55a and f2ce702.

📒 Files selected for processing (3)
  • mount.go
  • mount_test.go
  • router.go

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the route mounting logic to ensure that a sub-app's RegexHandler and customConstraints are preserved during route flattening. Changes include modifying the addPrefixToRoute signature and adding a unit test to verify the preservation of sub-app configurations. Review feedback highlights a regression where parent constraints are replaced instead of merged, potentially breaking prefix parsing. There is also a suggestion to address nested mounting scenarios where handlers might still be lost due to how routes are cloned.

Comment thread router.go
Comment thread mount.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a mount-time route reparse issue where cloned routes from a mounted sub-app could be reparsed using the parent app’s RegexHandler, potentially changing (and weakening) regex constraint semantics. The update makes mount prefixing preserve the mounted sub-app’s regex configuration when rebuilding the route parser for the prefixed path.

Changes:

  • Updated addPrefixToRoute to accept an explicit regexHandler plus variadic customConstraints, and use those when reparsing the prefixed route.
  • Updated mount route expansion to pass the mounted sub-app’s RegexHandler and customConstraints when prefixing/cloning routes.
  • Added a regression test to ensure mounted routes don’t inherit the parent’s regex compilation semantics.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
router.go Extends addPrefixToRoute to reparse with an explicitly provided regex handler + constraints.
mount.go Passes mounted app’s regex handler and constraints into prefixing during route expansion.
mount_test.go Adds regression test for preserving sub-app regex behavior after mounting.

Comment thread mount.go
Comment thread mount_test.go
Copilot finished work on behalf of gaby May 22, 2026 01:51
@codecov

codecov Bot commented May 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.29%. Comparing base (ee0c55a) to head (25fd939).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4308      +/-   ##
==========================================
- Coverage   91.33%   91.29%   -0.05%     
==========================================
  Files         132      132              
  Lines       13087    13089       +2     
==========================================
- Hits        11953    11949       -4     
- Misses        716      721       +5     
- Partials      418      419       +1     
Flag Coverage Δ
unittests 91.29% <100.00%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ReneWerner87 ReneWerner87 merged commit a39a035 into main May 22, 2026
21 checks passed
@ReneWerner87 ReneWerner87 deleted the fix-mounted-routes-regex-engine-issue branch May 22, 2026 06:53
@github-project-automation github-project-automation Bot moved this to Done in v3 May 22, 2026
@ReneWerner87 ReneWerner87 modified the milestones: v3, v3.3.0 May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants