Problem/Motivation
AssetRoutes::routes()
contains logic to determine where to store "assets," aka CSS and JS aggregates. This used to be hard-coded to use the public stream wrapper, which implements a ::getDirectoryPath()
method. When a specific assets://
stream wrapper was introduced in #3027639: Make css/js optimized assets path configurable, the call to ::getDirectoryPath()
was maintained, however if you override the assets
stream wrapper (e.g., with Flysystem to point at object storage) this method is not available as it is not in the StreamWrapperInterface
contract.
We do not have test coverage for this as it's an expert-mode customization to Drupal, but we should not make assumptions about the stream wrapper that is used.
Related, and discovered in the course of exploring this issue, the cache-control header sent with asset binary responses is incorrect. (It's set to private, no-store but is delivered to the client as public, no-store which isn't particularly performant and also unintentional/non-deterministic.)
Steps to reproduce
Override the stream wrapper implementation for assets://
with one that is not local. Because these stream wrappers do not have a "directory path" served by the web server, no assets available to the client.
For headers, observe that the header delivered with the response is incorrect.
Proposed resolution
Adjust the asset route generation and controller logic to at least not break non-local stream wrappers for asset storage, and clear the way for them to be served either piped from external storage or cached by a CDN/something else expert-mode.