neos / redirecthandler

The Neos.RedirectHandler package for Flow
MIT License
4 stars 15 forks source link

RedirectHandler escapes ? to %3F #47

Open putzwasser opened 4 years ago

putzwasser commented 4 years ago

I tried to shorten an UTM url, but the redirect handler doesn't handle ? well. In source path I entered: article/ix575ph2epxqj where ix57... is the random part of the node-name. In target path I entered: valid/path/to/my/document.html?utm_medium=foo&utm_source=bar The redirect handler redirects me from https://mysite.com/article/ix575ph2epxqj to https://mysite.com/valid/path/to/my/document.html%3Futm_medium=foo&utm_source=bar which gives me a 404 - not found.

https://mysite.com/valid/path/to/my/document.html is a valid url and manually browsing it serves me a rendered document node. Therefore, https://mysite.com/valid/path/to/my/document.html%3Futm_medium=foo&utm_source=bar serves me a correctly rendered document node, too, if I open it manually. So, it's not a problem of a missing document node or wrong URI.

putzwasser commented 4 years ago

The target path seems to be stored correctly. At least the redirecthandler-ui displays valid/path/to/my/document.html?utm_medium=foo&utm_source=bar as target path. Therefore it seems that the error might be somewhere in the redirect itself :man_shrugging:

Edit: If I export the created redirects, the target location gets exported correctly with a ? and not with %3F. So I guess it the error occurs during the redirection.

Sebobo commented 4 years ago

Thx for opening the issue.

Sadly I'm currently not able to reproduce this with an adapted example:

Bildschirmfoto 2020-08-17 um 11 22 13

The redirect is correctly built and executed. Any more hints?

putzwasser commented 4 years ago

Any more hints?

Yep. That it worked for you made me wondering. So i reproduced, what you did.

Your redirect seems to be on a document node which is a direct child of the site node. If I create a redirect on that level it works for me too.

My original redirect is on a document node which is some level deeper. Maybe/probably that's causing the error?

Bildschirmfoto_2020-08-17_13-42-31

Sebobo commented 4 years ago

Also works for me. Sure you don't have anything else in your project that might influence this or simply the node is not really accessible?

Best would be if you could reproduce it in the demo site.

putzwasser commented 4 years ago

Sure you don't have anything else in your project that might influence this

I would think so. I do not have any package installed which deals with redirects.

or simply the node is not really accessible?

Yes. A redirect withouth the query part works just fine.

Best would be if you could reproduce it in the demo site.

I just installed a vanialla Neos 5.1.9 Demo:

/var/www/html/neos-demo$ composer create-project neos/neos-base-distribution=5.1.9 .

And created redirects to test it:

image

None of the redirects with a query works.

Here's a screencast (time between frames is a bit long):

screencast

putzwasser commented 4 years ago

A little update: The redirect works if I add it with an absolute URI as targetPath:

sourcePath        targetPath
article/test_p    http://127.0.0.1:8080/en/features/navigation-elements/subpage-no3.html?utm_medium=foo

A relative path leads to an escaped ?.

sourcePath        targetPath
article/test_p    en/features/navigation-elements/subpage-no3.html?utm_medium=foo

This is re-producible for my vanilla localhost Neos Demo (5.1.9) installation and for my productive web installation (same version).

bweinzierl commented 3 years ago

Have same issue. This Line in RedirectService.php line 109 messes it up:

        // $location is fine

        if (parse_url($location, PHP_URL_SCHEME) === null) {
            $location = (string)$httpRequest->getUri()->withQuery('')->withFragment('')->withPath($location);
        }

        // $location has escaped ? character
markusguenther commented 3 years ago

Investigated the same behavior yesterday for the targetPath and great that this is already known 🙈 The withPath() encodes the path automatically.

if (parse_url($location, PHP_URL_SCHEME) === null) {
       $location = (string)$httpRequest->getUri()->withQuery('')->withFragment('')->withPath($location);
       $location = urldecode($location);
}

Something like that solves that for me. Did not find another solution yet :/ Will try it with a PR and will see which feedback comes in :D