I want to access a resource in the Restful API, where the resource identifier contains special characters. Therefore, I have url_encoding identifier, but I get inconsistent Mojolicious auto-decoding behavior for placeholders.
Below is a test script that checks for a simple resource identifier that contains a space, one with a plus and one with a slash. I send url_encoding each of them before sending my request, but the 2nd number does not work for various reasons.
use strict;
use warnings;
use v5.10;
use Data::Dump qw(pp);
use Mojolicious::Lite;
use Mojo::UserAgent;
use Test::Exception;
use Test::More;
use URL::Encode qw(url_encode url_decode);
use WWW::Mechanize;
get '/my/app/standard_placeholder/:id' => sub {
my $c = shift;
my $id_raw = $c->stash('id');
my $id_decoded = url_decode($id_raw);
$c->render( json => { raw => $id_raw, decoded => $id_decoded } );
};
get '/my/api/shutdown' => sub {
exit 0;
};
if ( my $pid = fork ) {
note "Waiting for the server to start";
sleep 2;
run_test();
waitpid( $pid, 0 );
} else {
local @ARGV = qw(daemon);
app->log( Mojo::Log->new( path => "$0.log", level => 'debug' ) );
app->start;
}
exit 0;
sub run_test {
plan tests => 2;
my $ua = Mojo::UserAgent->new();
my $server_url = 'http://127.0.0.1:3000';
subtest 'Standard Placeholders testing url_encoding of route identifiers' => sub {
my @ids = (
"foobar",
"a space",
"a+plus",
"a/slash",
);
plan tests => 3 * @ids;
for my $id (@ids) {
my $id_encoded = url_encode($id);
my $tx = $ua->get("$server_url/my/app/standard_placeholder/$id_encoded");
SKIP: {
is( $tx->res->code, 200, "Fetch Resource at " . pp($id) )
or skip "Error in response", 2;
is( $tx->res->json->{raw}, $id_encoded, "json->{raw} eq " . pp($id_encoded) );
is( $tx->res->json->{decoded}, $id, "json->{decoded} eq " . pp($id) );
}
}
};
subtest 'Shutdown the server' => sub {
plan tests => 2;
dies_ok {
my $mech = WWW::Mechanize->new( timeout => 3 );
$mech->get("$server_url/my/api/shutdown");
}
'shutdown occurred';
like $@, qr{Error GETing .*?shutdown: Server closed connection without sending any data back},
'detected closed connection';
};
}
1;
And the conclusion:
mhall@dev19:~$ ./mojo_placeholders.pl
Server available at http://127.0.0.1:3000
1..2
1..12
ok 1 - Fetch Resource at "foobar"
ok 2 - json->{raw} eq "foobar"
ok 3 - json->{decoded} eq "foobar"
ok 4 - Fetch Resource at "a space"
ok 5 - json->{raw} eq "a+space"
ok 6 - json->{decoded} eq "a space"
ok 7 - Fetch Resource at "a+plus"
not ok 8 - json->{raw} eq "a%2Bplus"
not ok 9 - json->{decoded} eq "a+plus"
not ok 10 - Fetch Resource at "a/slash"
ok 11
ok 12
not ok 1 - Standard Placeholders testing url_encoding of route identifiers
1..2
ok 1 - shutdown occurred
ok 2 - detected closed connection
ok 2 - Shutdown the server
Any suggestions on how to approach this?
source
share