Problem/Motivation
In #2075889: Make Drupal handle incoming paths in a case-insensitive fashion for routing I found another routing-related regression from Drupal 7 and before - repeated slashes in the request path cause a 404 instead of being normalized away.
This may affect users upgrading from earlier versions of Drupal if links exist on or to site pages that have accidental repeated slashed, and can cause cache bloat as well.
Steps to Reproduce:
- Add a node
- Go to /node/[nid]. The node will load
- Go to /node//[nid]. 404
Proposed resolution
Normalize (remove) duplicate slashes in the incoming path that's seen when matching a route and in the rest of the request
Remaining tasks
port over the fix puled out from #2075889: Make Drupal handle incoming paths in a case-insensitive fashion for routing and add more test coverage.
User interface changes
none
API changes
none
Data model changes
none
| Comment | File | Size | Author |
|---|---|---|---|
| #40 | 2852361-39.patch | 2.9 KB | smustgrave |
| #39 | 2852361-39-tests-only.patch | 1.46 KB | smustgrave |
| #39 | after_patch.png | 1.12 MB | smustgrave |
| #39 | before_patch.png | 782.83 KB | smustgrave |
| #38 | 2852361-38.patch | 2.89 KB | ranjith_kumar_k_u |
Comments
Comment #2
mpdonadioThese are the removed hunks from the other patch to turn #291 back into #289, so will be our starting point when we get that in.
And, adding Needs Tests so we can add some more cases to check and prevent regressions.
Comment #3
pwolanin commentedPatch seems to apply cleanly to 8.4.x
Comment #4
wolffereast commentedThe issue still exists in 8.4. Applying the patch fixes the issue (Tested /node//[nid], /node/[nid]/, and /node//[nid]//). The functional tests are passing. Moving to RTBC
Not a blocking issue, just a comment: The update to remove the duplicate and trailing slashes could be changed from
to
$path = preg_replace(['{//+}', '{/^}'], ['/', ''], $request->getPathInfo());I didn't roll a new patch as I have no idea which one would be faster. It may well just be a personal preference.
Comment #5
pwolanin commentedWe are using the preg_split other places, so this at least matches the other code.
Still needs tests
Comment #6
pwolanin commentedHere's with an added kernel test, maybe gtg?
Comment #7
wolffereast commentedFired off the updated tests with no failures. Makes sense on the preg_split, thanks!
One minor note on the following comment as it doesn't read smoothly. I recommend `Note that no test case is included for paths with multiple leading slashes because they are redirected and cannot be used to create Request objects.` or something similar.
Comment #9
wolffereast commentedupdated the patch. only change is the suggested comment edit. not sure what the failure from the test bot is about
Comment #10
pwolanin commentedFailure might be something sporadic - let's try again (setting to NR for that)
Comment #11
mpdonadioFailure was b/c https://www.drupal.org/node/2863416#comment-12062889 so NR is def OK here.
I think this looks good. My involvement was minimal with this change; going to read this applied later today and likely set RTBC.
More thinking out loud here, but this will result in some stale data in the cache, but I don't think this is a real problem for an edge-case and the entries will be GCed anyway. IOW, I think a post-update hook to clear is overkill.
Comment #12
mpdonadioPlayed with this applied.
Two things, not sure if we need to go back to NW.
1. If Internal Page Cache is enabled, and a path like '/node/////1' gets cached as a 404, the patch will still serve up a 404 until a cache clear. I think we may want to consider clearing that bin (if enabled) in a post-update hook.
2. Does anyone recall why we aren't doing a RedirectResponse to 301 to the proper slashified path? We will serve up the proper route, but at the path with the wonky slashes? By itself, this may not be a problem, but there are a few side effects with breadcrumbs:
?
Comment #13
pwolanin commented@mpdonadio - we are doing a redirect for leading slashes. I guess that's an option we could use for any repeated (or trailing?) slashes instead of this.
The \Drupal\system\PathBasedBreadcrumbBuilder constructor takes a request context - and fixing that to normalize slashes might be tricky. Maybe the redirect is the better option? It seems otherwise to handle this consistently we'd need to be normalizing the request path before or in the initial Request object creation in index.php.
Comment #14
john cook commentedWhile the patch works, I don't think that it's implemented as it should be.
If you got to
///node/[nid]you are redirected to/node/[nid]. I believe the same thing should happen if you visit/node///[nid]as is mentioned by pwolanin in #13. This should also fix mpdonadio's breadcrumb problem in #12.Comment #17
xanoRe-roll for 8.6.x. This includes a rather significant change in the form of
RouteProvider::normalizePath(), which I introduced to deal with the introduction ofRouteProvider::getRouteCollectionCacheId()since the last iteration of this patch.I will look into redirecting duplicated non-leading slashes as well.
Comment #18
xanoThis implements the redirect approach as discussed in #12 and #13.
Comment #19
xanoComment #20
xanoI think this is a lot cleaner, primarily because it keeps our API pure, and we move processing invalid paths to a layer dedicated to handling input.
Comment #21
runeasgar commented/node/1: works./node//1: 404.curl -l https://www.drupal.org/files/issues/2018-03-28/drupal_2852361_19.patch | git apply -vdrush crnode//1: success, I am redirected to/node/1./node/1//,/node//1//, both work, but I am redirected to/node/1/(trailing backslash). I assume this is fine.Since this issue has successful tests, and has no UI changes (no screenshot needed), I'm moving it to RTBC. Apologies if that's not the correct action.
Comment #23
xanoThat looked like an unrelated failure.
Comment #25
xanoComment #26
alexpottI don't see how this is a major bug. Also the current fix makes it a minor release only fix and one that needs a change record.
Can't do this in bug fix. Imo it'd be better to just do the changes to RedirectLeadingSlashesSubscriber and then do the service rename and class rename in another issue.
Comment #28
xanoSo keep
RedirectLeadingSlashesSubscriberbut make it handle trailing slashes as well? Would a docblock update and change record be sufficient, or do we want to document this another way too?Comment #29
xanoThis patch addresses the feedback given in #26. Thanks! I also added a change record.
Comment #37
xjmI'm not sure I agree with #26. This is extremely painful UX-wise and has caused a lot of pain since the major changes from D8 menu/routing sprint. It also creates D7 upgrade path problems with old links suddenly becoming broken. There should be some related issues about the leading slashes issues; I didn't find them but they're out there.
Setting major for now.
Comment #38
ranjith_kumar_k_u commentedRerolled #29
Comment #39
smustgrave commentedTested patch #38 and verified it worked see screenshots
This patch I'm uploading is the same as #38 but noticed there was no tests only patch.
Comment #40
smustgrave commentedNot sure why this didn't upload. Again SAME as #38
If tests-only patch fails and this passes I'll mark RTBC
Comment #43
smustgrave commentedLooks like everything passed and test-only failed.
Comment #45
catchCommitted/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x
We could use a follow-up for the class rename.
Comment #47
quietone commentedI made the followup, change the CR to make it easier to read and published it.