While working on a Rest-resource we have an issue with rendering Url's to private files.
We used $file->url()
and that resulted in this error:
The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early.
Diving into it looks like PrivateStream::getExternalUrl()
and UrlGeneratorTrait::url()
are here to blame, because these functions do not pass the collect_bubbleable_metadata
attribute when rendering the url.
We used:
$file->url()
This will call file_create_url()
located in /core/includes/file.inc
At some point in file_create_url()
the appropriate wrapper is loaded and the method getExternalUrl()
will be called.
// Attempt to return an external URL using the appropriate wrapper.
if ($wrapper = \Drupal::service('stream_wrapper_manager')->getViaUri($uri)) {
return $wrapper->getExternalUrl();
}
else {
return FALSE;
}
The function getExternalUrl
on the PrivateStreamWrapper calls
url()
in Drupal/Core/Routing/UrlGeneratorTrait.php
This doc-comment says that \Drupal\Core\Routing\UrlGeneratorTrait::url()
follows \Drupal\Core\Routing\UrlGeneratorInterface::generateFromRoute()
, but it does not.
The collect_bubbleable_metadata
attribute is missing.