Problem/Motivation
example.sites.php documents how to configure path-based routing for multi-sites which share the same domain, but use different paths. It does not mention the render cache consequence — that without url.site in required_cache_contexts, render-cached blocks are shared across sub-sites and will serve wrong base-path-relative URLs to users. The default cache contexts in services.yml excludes url.site, but if this is missing in such a multi-site set up, and developers create symlinks from the multi-site paths, back to the docroot, this can potentially lead to a recursive traversal of these symlink paths, causing a large amount of variation in site URLs.
Note, the "recursive traversal of symlinks" here isn't necessarily the bug if cache contexts aren't configured properly, but does seem to happen on a site which I'm managing.
Steps to reproduce
I have replicated this in a local, sandbox site environment. This can be seen in a base Drupal installation in the standard profile, with a multi-site set up using paths. Set up such a site, let's call one the "base" site, that uses no path, and the other "site2" that uses {base domain}/site2, with a symlink in web/site2 pointing back to the "web" directory. Set up a corresponding sites/site2 directory with settings.php, and an entry in sites.php with something like:
$sites['d8-ddev.ddev.site.site2'] = 'site2';
(here I am using ddev)
Visit the homepage for one site. Then, visit the homepage for the other, and note several things. first, the CSS/JS may have been served from the original base path, which may also be broken as the generated CSS may not exist on that files directory. Also, the RSS feed link will serve from a cached version of the other site.
Proposed resolution
This may be a known issue to experienced multi-site users, but can become a serious gotcha with an unclear fix. The fix is to document the requirement for adding url.site to the required cache contexts in examples.services.yml. I'd suggest adding this in example.sites.php, with something like this after the note about symlinks:
* When using path-based aliases where sub-sites share the same domain,
* add 'url.site' to required_cache_contexts in each sub-site's services.yml
* to prevent cross-site render cache contamination:
* @code
* parameters:
* renderer.config:
* required_cache_contexts: ['languages:language_interface', 'theme',
* 'user.permissions', 'url.site']
* @endcode
* @see \Drupal\Core\Cache\Context\SiteCacheContext
Issue fork drupal-3594238
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
Comment #2
avinash.jha commentedComment #5
avinash.jha commentedI have updated example.sites.php (along with its scaffold source template at core/assets/scaffold/files/example.sites.php) to document the requirement of adding url.site to required_cache_contexts in services.yml when using a path-based multi-site configuration on a shared domain. This prevents cross-site render cache contamination and issues with generated assets/links.
Comment #6
avinash.jha commentedComment #7
amitgoyal commentedReviewed MR !16030. The patch adds documentation block to both sites/example.sites.php and core/assets/scaffold/files/example.sites.php (the scaffold source), documenting the requirement to add url.site to required_cache_contexts when using path-based multi-site configuration on a shared domain. The two files are identical (correct).
LGTM.
Comment #8
quietone commentedI can't review this to say the addition is correct but the wrapping is incorrect. Although this is a comment which are wrapped at 80, anything wrapped in an @code/@endcode block does not have that restriction.