Issue #3630926: Preserve case-sensitive managed-file URL paths

Closes #3630926

Issue: https://www.drupal.org/project/entity_usage/issues/3630926

Fix

Preserve the case-sensitive path through the shared URL-to-entity resolver. Normalize only hostname matching (including Unicode/IDN hostname case), and compare schemes case-insensitively. Keep configured/discovered site and public-wrapper base paths unchanged. Reuse the same domain conversion in the legacy update hook.

The public-file subscriber now derives the managed URI from the parsed path, without query/fragment suffixes, and uses rawurldecode() so plus signs are not mistaken for spaces. Absolute and protocol-relative CDN URLs retain their path case. File entity queries remain exact: files differing only by filename case resolve to distinct IDs.

No new dependencies, configuration workaround, content rewriting, or file renaming. This does not change Media File Delete's duplicate-counting logic.

Regression evidence

  • Existing kernel file-tracking test extended with real file entities, real URI queries, and saved plain HTML field tracking.
  • Cases: lowercase and mixed-case filenames/directories; case-distinct files; absolute, root-relative and relative paths; uppercase and Unicode hostname case; encoded spaces and encoded/literal plus signs; query/fragment suffixes; external-host and wrong-case directory rejection; mixed-case non-local public-wrapper/CDN base paths (absolute and protocol-relative).
  • SiteDomains unit coverage and legacy domain conversion kernel coverage included. Previous unit expectations for whole-path lowercasing updated to the new path-preserving contract.
  • Without the production fix, EntityUsageTrackFileTest::testCaseSensitiveFileUrls fails on MixedDirectory/MixedCase.pdf: NULL managed-file resolution. With the fix, the focused kernel/URL/domain/public-file checks pass: 56 tests, 260 assertions on Drupal 11.4.4 / PHP 8.4 / PHPUnit 11.5.
  • Local real bulk-media-delete check: saved draft's plain mixed-case PDF link recorded as node/body html_link; linked file retained (entity/disk present, HTTP 200); unreferenced lowercase control deleted (entity/disk absent, HTTP 404). No media or core file-usage records remained to mask retention. Disposable fixtures cleaned up.
  • Clean Composer reinstall on locked Entity Usage 5.0.1 verified separately.

CI results still require review. Recreate existing Entity Usage data after deploying to each environment; avoid file deletion during rebuilds. The patch only corrects reference recognition and does not establish that every deletion workflow is safe.

AI-assisted investigation/coding; results verified by executable regression and focused local integration checks. Public report and tests use synthetic examples only.

Merge request reports

Loading
Loading