Skip to content
This repository

'redirect' decodes the encoded url #846

berekuk opened this Issue October 10, 2012 · 4 comments

4 participants

Vyacheslav Matyukhin Stefan Hornburg (Racke) Yanick Champoux hh10k
Vyacheslav Matyukhin

I think it's a bug.

package redirtest;
use Dancer ':syntax';

get '/' => sub {
    # returns foo: bar=
    # (older versions of (Plack? Dancer?) lose the '=' sign too, because of their different interpretation of a=b=value cgi params)
    return "foo: ".params->{foo};

get '/redir' => sub {
    # will redirect to /?foo=bar=&
    redirect '/?foo=bar%3D%26';

Stefan Hornburg (Racke)
racke commented May 21, 2013

The correct syntax should be:

redirect uri_for('/', {foo => 'bar=&'});


Vyacheslav Matyukhin
berekuk commented May 22, 2013

But this is still a bug, right? uri_for works because it adds the full http://$hostport to the url, it's just a coincidence.

Or are you saying that I should never pass relative urls to redirect (in which case docs should be fixed), or that there's some hidden meaning to the current behavior?

Yanick Champoux yanick referenced this issue from a commit June 10, 2013
Yanick Champoux add additional test for #846 c7905f7
Yanick Champoux
yanick commented June 10, 2013

The problem lies in the interaction of URI and uri_for(). uri_for() passes the path to $uri->path(), which does escape everything (so 'foo&bar%26' becomes 'foo%26bar%26). If uri_for() has the $dont_escape, everything is re-unescaped (and becomes 'foo&bar&'.. oops)

I have to think about the repercussions, but the solution might lie in pre-emptively escaping the '%' before we go through the URI transformation...


I found the temporary solution to this bug is to always pass an absolute URL to redirect. _redirect() in doesn't modify the URL if it appears to start with a scheme.

get '/redir' => sub {
    # Will correctly redirect to /?foo=bar%3D%26
    redirect request->uri_base.'/?foo=bar%3D%26';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.