Strip 'www.' prefix from Origin/Referer header in CA logic
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Problem Statement
When persisting Content Analytics events to CAEM, dotCMS resolves the target Site by extracting the host from the Origin HTTP header (falling back to Referer) and matching it against a Site's name or alias. This happens in ContentAnalyticsUtil.getSiteNameOrAlias() / getSiteFromRequest() (com.dotcms.rest.api.v1.analytics.content.util.ContentAnalyticsUtil, lines ~229-252 and ~349-376), which is also called from SiteAuthValidator.validate() (com.dotcms.jitsu.validators.SiteAuthValidator) to validate each incoming event's site auth.
Many public sites serve their canonical pages under a www. subdomain (e.g. https://www.example.com), but the dotCMS Site's configured hostname and aliases typically do not include the www. prefix (e.g. example.com). The host extracted from the Origin/Referer header via URLUtils.parseURL() is passed as-is — with no normalization — into HostAPI.findByName() and then HostAPI.findByAlias(). Both lookups fail for a www.-prefixed host, so getSiteFromRequest() throws AnalyticsValidationException ("Site with name/alias '...' was not found").
Observed impact: SiteAuthValidator catches this exception per-event, so the individual event is silently dropped from the batch payload (ContentAnalyticsUtil.removeInvalidEventsFromPayload()) while other valid events in the same batch still persist — this makes the failure easy to miss since analytics keeps flowing for the site overall. Separately, getSiteFromRequestSilently() (used by includeInternalFields()) wraps the same exception as an unchecked RuntimeException, which can abort processing for that call site entirely.
This host-resolution logic is custom to ContentAnalyticsUtil and is not shared with dotCMS's general request-host resolution (HostWebAPIImpl.getCurrentHost(), which uses request.getServerName() and is unaffected by this bug), so the fix is fully contained to Content Analytics event ingestion. No backwards compatibility needs to be preserved for this change.
Out of scope: ContentAnalyticsUtil.sendEvents() resolves the host for logging via HostWebAPI.getCurrentHost() (server name) rather than getSiteFromRequest() (Origin/Referer), so the host used to persist/log an event can already differ from the one used to validate site auth. That inconsistency is a separate issue and is not addressed here.
Steps to Reproduce
- Configure a dotCMS Site with hostname
example.com(nowww.example.comalias configured). - Enable Content Analytics tracking for that Site (Content Analytics app with
siteAuthandcontentImpression/contentClickconfigured). - Load a page served under
https://www.example.com/...so that the browser sendsOrigin: https://www.example.com(orReferer: https://www.example.com/...) with the analytics event request. - Trigger a Content Analytics event (e.g. page view / click) so it is submitted for persistence.
Expected: The event resolves to the example.com Site and is persisted.
Actual: getSiteNameOrAlias() extracts host www.example.com, which matches neither the Site's name nor its aliases. getSiteFromRequest() throws AnalyticsValidationException, SiteAuthValidator drops the event from the batch, and it is never persisted — with no visible error to the caller since other events in the batch may still succeed.
Acceptance Criteria
- When the Origin or Referer header host starts with
www.(case-insensitive) and the remainder matches a configured Site name or alias, the event resolves to that Site and is persisted (e.g.Origin: https://www.example.commatches Siteexample.com). - When the Origin or Referer header host does not start with
www., existing Site matching behavior is unchanged. - Only a single leading
www.label is stripped; hosts such asshop.example.comorwww2.example.comare not modified by this normalization. - The
www.prefix match is case-insensitive (e.g.WWW.example.comandWww.Example.comare also normalized before lookup). - If, after stripping
www., the host still does not match any Site name or alias, the existingAnalyticsValidationException("Site with name/alias '...' was not found") is thrown, unchanged from current behavior. - Unit test coverage added covering
www.-prefixed Origin and Referer headers resolving correctly to the underlying Site, plus a case confirming non-www hosts are unaffected.
dotCMS Version
Latest from main branch
Severity
Medium - Some functionality impacted
Links
- NA
Contributor 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.
Research direction
Start with ContentAnalyticsUtil.getSiteNameOrAlias() and getSiteFromRequest(), then trace their use from SiteAuthValidator.validate(). Add unit coverage for www.-prefixed Origin and Referer hosts, unchanged non-www behavior, and the existing failure path. Run the relevant Content Analytics tests and confirm matching events resolve to the configured Site.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- analytics, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100