Generated with the help of an LLM.

Problem/Motivation

Opening the canonical page of a document media entity redirects the visitor to the file (e.g. a PDF). The redirect itself works (302 to the file), but every request logs two errors:

  • theme: Theme hook media not found.
  • php: LogicException: Render context is empty, because render() was called outside of a renderRoot() or renderInIsolation() call. in Drupal\Core\Render\Renderer->doRender() (core/lib/Drupal/Core/Render/Renderer.php line 318), triggered from HtmlRenderer->prepare().

The log entries carry no location, URL or IP, so they are hard to trace back to the media URL. On a busy site with short URL aliases pointing to document media, this produces many log entries per day.

Cause: pagedesigner_document_media_view() handles the redirect inside hook_media_view(), while the page is being rendered. It:

  1. creates a LocalRedirectResponse to the file URL,
  2. saves the session, prepares and calls $response->send(),
  3. calls $kernel->terminate(),

and then returns. Drupal goes on rendering the page for a request that has already been answered and terminated, which produces both log entries.

A second effect, from the same code: when the file URL is absolute and points to another host, LocalRedirectResponse refuses it and the page returns a 500 instead of the redirect:

InvalidArgumentException: It is not safe to redirect to https://example.com/sites/default/files/…

Affects 4.x branch.

Steps to reproduce

  1. Enable pagedesigner_document.
  2. Create a document media entity with a file.
  3. Visit /media/{id} (or a path alias of it) as an anonymous user.
  4. You are redirected to the file, but the watchdog log shows the two errors above.

Proposed resolution

  • Don't send the response from the view hook. Instead, return a proper redirect response when entity.media.canonical is requested for a document media with a file, e.g. from an event subscriber (kernel.request or kernel.view) in pagedesigner_document.
  • Keep the response uncacheable, as it is today (max-age 0 / page cache kill switch).
  • Drop the manual session save and $kernel->terminate().
  • Use a TrustedRedirectResponse (or check the file URL) so the redirect also works when files are served from another host.

Remaining tasks

  • Implement the event subscriber and remove the redirect from hook_media_view().
  • Add test coverage for the redirect.
  • Review.

User interface changes

None.

API changes

None.

Data model changes

None.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

guillaumepacilly created an issue. See original summary.

guillaumepacilly’s picture

Issue summary: View changes

guillaumepacilly’s picture

Status: Active » Reviewed & tested by the community

guillaumepacilly’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

guillaumepacilly’s picture

Status: Fixed » Closed (fixed)