Skip to content

fix: resolve pages requested with trailing slash #25264#35151

Open
wezell wants to merge 5 commits intomainfrom
issue-25264-trailing-slash
Open

fix: resolve pages requested with trailing slash #25264#35151
wezell wants to merge 5 commits intomainfrom
issue-25264-trailing-slash

Conversation

@wezell
Copy link
Copy Markdown
Member

@wezell wezell commented Mar 27, 2026

Summary

  • Strip trailing slash from CMS_FILTER_URI_OVERRIDE in CMSFilter so page URIs like /about-us/index/ resolve correctly
  • Add early-exit in CMSUrlUtil.resolveResourceType() for internal/backend URLs to avoid unnecessary identifier lookups
  • Improve null-safety checks using UtilMethods.isSet() in resolvePageAssetSubtype()
  • Add integration test verifying trailing-slash page resolution
  • Can be disabled by setting DOT_STRIP_TRAILING_SLASH_FROM_PAGES=false

Test plan

  • Run FiltersTest#shouldResolvePageWithTrailingSlash — verifies both /path/page and /path/page/ resolve to 200 with correct URI override
  • Verify existing FiltersTest tests still pass
  • Manual test: request a page with trailing slash and confirm it renders correctly

🤖 Generated with Claude Code

This PR fixes: #25264

wezell and others added 2 commits March 27, 2026 17:11
Strip trailing slash from CMS_FILTER_URI_OVERRIDE in CMSFilter and add
early-exit for internal/backend URLs in CMSUrlUtil.resolveResourceType.
Also improves null-safety checks using UtilMethods.isSet() and adds
integration test verifying trailing-slash page resolution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These changes are local-only and should not be on this branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Mar 27, 2026

Claude finished @wezell's task in 2m 5s —— View job


PR Review

  • Gather context
  • Read changed files
  • Analyze and post review

Three issues worth fixing; the rest is fine.


1. Config property name mismatch (bug in docs / potential user confusion)

The PR description says the feature can be disabled with DOT_STRIP_TRAILING_SLASH_FROM_PAGES=false, but the code reads:

// CMSUrlUtil.java:194
Config.getBooleanProperty("STRIP_TRAILING_SLASH_FROM_PAGES", true)

dotCMS env-var overrides use the DOT_ prefix convention. Setting DOT_STRIP_TRAILING_SLASH_FROM_PAGES=false will have no effect; users need STRIP_TRAILING_SLASH_FROM_PAGES=false. Either fix the property name in code to DOT_STRIP_TRAILING_SLASH_FROM_PAGES (if that's the intended convention) or fix the docs. Fix this →


2. internalUrl() breaks on the /c/ prefix (logic bug)

BACKEND_FILTERED_COLLECTION contains "/c/" (already ends with /). The new method does:

// CMSUrlUtil.java:119
uri.startsWith(prefix + "/") || uri.equals(prefix)

For prefix = "/c/", this checks uri.startsWith("/c//") — a double slash that will never match. Any request to /c/foo will fall through instead of being short-circuited as internal. The early-exit optimization silently doesn't work for that prefix. Fix this →


3. Trailing slash stripped unconditionally in CMSFilter, but resolvePageAssetSubtype also tries both URIs

The slash is stripped in two independent places:

  • resolvePageAssetSubtype() does a second find() without the slash if the first lookup returns nothing
  • CMSFilter unconditionally strips the slash from CMS_FILTER_URI_OVERRIDE for all IAm.PAGE responses

This means if resolvePageAssetSubtype matched via the slash-stripped fallback, the CMSFilter strip is redundant but harmless. However, if a page legitimately ends with / in the identifier (unlikely, but possible if data was created that way), it would break. The real fix — stripping at the CMSFilter level — is the right place, and resolvePageAssetSubtype's double lookup may be unnecessary now. Consider whether both are needed.


Minor / unrelated changes

  • InitServlet.java: Collapsing catch (DotDataException) and catch (DotSecurityException) into catch (Exception) loses exception type specificity. Both branches did the same thing, so functionally equivalent, but it now silently swallows any unexpected runtime exception as "Unable to initialize system host." Not ideal.

  • StaticPageCacheImpl.java (infodebug) and ConcurrentPool.java (log interval 1h → 24h) are unrelated noise cleanups. Fine individually, but they dilute the PR's focus.

  • FiltersTest: The new test doesn't clean up the STRIP_TRAILING_SLASH_FROM_PAGES config property if it's ever set, but since it relies on the default (true), this is fine as-is.


The core fix (stripping in CMSFilter before setting CMS_FILTER_URI_OVERRIDE) is correct and the test covers the main scenario. Issues 1 and 2 above are the ones worth addressing before merge.

wezell and others added 3 commits March 27, 2026 17:20
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : Backend PR changes Java/Maven backend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

dotCMS should not resolve a 404 if URLs have a trailing "/"

1 participant