Hi! I asked about this on May 4, but didn't have the simplest-possible example to illustrate my problem, but I do now:
use Mojo::URL;
my $url = Mojo::URL->new('/v1/accounts?account=joe%40schmoe.org');
print "URL: " . $url->to_string . "\n"; ## account=joe%40schmoe.org
my @params = $url->query->param; ## damage done
print "URL: " . $url->to_string . "\n"; ## account=j...@schmoe.org
In the first $url->to_string(), the URL stringifies to its original form.
In the second $url->to_string(), the URL stringifies with its query parameters *url-unescaped.*
The cause is that Mojo::Parameters->param calls to_hash(), which calls params(). In params(), we have this:
# Unescape
$name = url_unescape $name;
$name = decode($charset, $name) // $name if $charset;
$value = url_unescape $value;
$value = decode($charset, $value) // $value if $charset;
push @$params, $name, $value;
Decoding the parameters is a Good Thing, but pushing them back into the $params makes it impossible to retrieve the original URL (and seems out of spirit with RFC 3986 to me).
I'm not sure what to do here; my instinct says that there should be a separate member of Mojo::Parameters called, say, "unescaped" where we can preserve these nicely unescaped parameters. Alternatively (in params()), instead of deleting the 'string' parameter, we keep it and check to see if params is defined instead. Yet another alternative would be to fix Mojo::URL to keep a copy of the original query string and use that instead of Mojo::Parameter's query method in to_string(). Other ideas?
I'm happy to code this with tests, etc. but could use some advice on what would be the Mojo way.
Scott