Problem/Motivation
drush ev "\Drupal\Core\Url::fromUri('base:2015/10/06');"
Gives:
exception 'InvalidArgumentException' with message 'The URI 'base:2015/10/06' is invalid. You must use a valid URI scheme.'
The same for \Drupal\Core\fromUri('internal:/2015/10/06') since that eventually falls back to base: if it can't find something.
The problem is apparently the parse_url() at the top of fromUri().
That parses that as host => base, port => 2015, path => 10/06. Which is a perfectly valid interpretation of that string but not at all what we expect to happen.
UrlHelper::parse() on the other hand seems to parse it correctly.
I originally found this due to the deslash (remove trailing slash) feature in redirect.module (previously a feature in globalredirect, we merged those together). It uses internal: on the incoming URL to convert that into a Url object as we're using an Url object in an internal helper method to deal with options and access checking if necessary.
So with redirect.module enabled with the deslash feature enabled (not the case by default), going to http://yoursite/2015/10/06/ currently throws that exception, which we noticed because we went live with a site that apparently used URL's like that before.
Proposed resolution
Use UrlHelper::parse() instead in fromUri() ?
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#14 | url-port-path-2580717-14.patch | 1.41 KB | tduong |
#14 | interdiff-2580717-10-14.txt | 739 bytes | tduong |
#10 | url-port-path-2580717-10-test_only.patch | 672 bytes | tduong |
#4 | url-port-path-2580717-4.patch | 751 bytes | Berdir |
Comments
Comment #2
dawehnerDoes the URL is actually able to handle that? I mean we still want theoretically to support hosts, don't we?
Comment #3
dawehnerDoes the URL is actually able to handle that? I mean we still want theoretically to support ports, don't we?
Comment #4
BerdirYeah, sorry, UrlHelper::parse() is nonsense, that doesn't work at all.
Very ugly, but this works. I have no idea what else we could do?
Comment #5
dawehnerHow did you not started writing tests, seriously
Comment #6
BerdirSorry :)
Just wanted to see if this works and get some feedback on it. Didn't have time for more, but it came up again in a project.
Comment #7
dawehnerWell, the workaround in general seems to be working, and well if we document this behaviour it might be okay.
Comment #8
tduong CreditAttribution: tduong at MD Systems GmbH commentedProvided test for Url::fromUri('internal:2015/10/06');, Url::fromUri('internal:/2015/10/06');, ...
Comment #9
BerdirWe are fixing that we get an exception, so we need to test that there is *no* exception :)
If it doesn't work, then we need to figure out why, might be a unit test environment problem.
Try specifying base: directly, not internal:
Comment #10
tduong CreditAttribution: tduong at MD Systems GmbH commentedDone. :)
Comment #11
tduong CreditAttribution: tduong at MD Systems GmbH commentedAbout the documentation @dawehner mentioned in #7, should the @Berdir's inline explanation be in the fromUri() declaration docblock?
Comment #13
claudiu.cristeas/'hostname/port'/'hostname:port'
Maybe "Prevent that by prefixing the path with a slash."?
Lets catch here only when starts with "base:". So,
'/^base:\d/'
I think is better.Comment #14
tduong CreditAttribution: tduong at MD Systems GmbH commentedAdjusted it. :)
Comment #15
dawehnerLooking at
https://tools.ietf.org/html/rfc3986#page-16
I'm wondering whether we could solve that more generically. If there is '//' in the URL, we expect a authority to be in there, otherwise there is none, and it doesn't make sense to use
parse_url()
?Comment #16
tduong CreditAttribution: tduong at MD Systems GmbH commentedWe need a scheme component that UrlHelper::parse() does not return (it returns only the URL's path, query, and fragment components), so it makes no sense to call it here.
Comment #17
dawehnerJust for curiosity I tried out the guzzle URI class:
Comment #20
BerdirStill RTBC, was just a CI error.
Comment #21
alexpottCommitted 018dd52 and pushed to 8.0.x. Thanks!
I pondered the performance implications with @dawehner but then dismissed them as rendering a URL will be far more expensive.