Skip to content

Commit

Permalink
Add resolver logic to deal with the presence of trailing slashes
Browse files Browse the repository at this point in the history
Signed-off-by: Pedro Melo <melo@simplicidade.org>
  • Loading branch information
melo committed May 16, 2012
1 parent 4329d06 commit 7a17fe0
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/Mason/Interp.pm
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ method _build_match_request_path ($interp:) {
my $path = $request_path;
my @tried_paths;

$path_info = chop($path) if $path ne '/' && substr($path, -1) eq '/';

while (1) {
my @candidate_paths =
( $path_info eq '' && !@autoextensions ) ? ($path)
Expand All @@ -505,7 +507,9 @@ method _build_match_request_path ($interp:) {
}
$interp->_top_level_not_found( $request_path, \@tried_paths ) if $path eq '/';
my $name = basename($path);
$path_info = length($path_info) ? "$name/$path_info" : $name;
$path_info =
$path_info eq '/' ? "$name/" :
length($path_info) ? "$name/$path_info" : $name;
$path = dirname($path);
@index_subpaths = (); # only match index file in same directory
}
Expand Down
26 changes: 26 additions & 0 deletions lib/Mason/Manual/RequestDispatch.pod
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,32 @@ The default C<allow_path_info> returns false.
C<allow_path_info> is not checked on dhandlers, since the whole point of
dhandlers is to match partial paths.

=head2 Trailing slash

If the request URL has a trailing slash (ends with C</>), we remove it
before the match process begins and add it to the
C<< $m->path_info >>. Components that should match must have
C<allow_path_info> return true.

For example:

## request URL /news/
/news/index.{mp,mc} # $m->path_info = / if index.{mp,mc} has
# allow_path_info => true
/news/dhandler.{mp,mc} # $m->path_info = /
/news.{mp,mc} # $m->path_info = / if news.{mp,mc} has
# allow_path_info => true

## request URL /news/sports/
/news/sports/index.{mp,mc} # $m->path_info = / if index.{mp,mc} has
# allow_path_info => true
/news/sports/dhandler.{mp,mc} # $m->path_info = /
/news/sports.{mp,mc} # $m->path_info = / if sports.{mp,mc}
# has allow_path_info => true
/news/dhandler.{mp,mc} # $m->path_info = sports/
/news.{mp,mc} # $m->path_info = /sports/ if news.{mp,mc}
# has allow_path_info => true

=head2 Routes

It is possible to use route syntax to more elegantly parse C<< $m->path_info >>
Expand Down
17 changes: 17 additions & 0 deletions lib/Mason/t/ResolveURI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,23 @@ sub test_resolve : Tests {
$try->( $run_path, ['/foo/bar/baz/index'], '/foo/bar/baz/index', '' );
$try->( $run_path, ['/foo/bar/baz/index2'], '/foo/bar/baz/index2', '' );
$try->( $run_path, [ '/foo/bar/baz/index2', '/foo/bar/baz/index' ], '/foo/bar/baz/index', '' );

# trailing slashes
$try->( '/foo', ['/foo.mc=1'], '/foo.mc', '' );
$try->( '/foo/', ['/foo.mc=1'], '/foo.mc', '/' );
$try->( '/foo/bar', ['/foo.mc=1'], '/foo.mc', 'bar' );
$try->( '/foo/bar/', ['/foo.mc=1'], '/foo.mc', 'bar/' );
$try->( '/foo/', ['/foo.mc'], undef );
@interp_params = ( dhandler_names => ['dhandler'] );
$try->( '/foo/', ['/foo/dhandler'], '/foo/dhandler', '/' );
$try->( '/foo/bar', ['/foo/dhandler'], '/foo/dhandler', 'bar' );
$try->( '/foo/bar/', ['/foo/dhandler'], '/foo/dhandler', 'bar/' );
@interp_params = ( index_names => ['index'] );
$try->( '/foo/', ['/foo/index'], undef );
$try->( '/foo/', ['/foo/index=1'], '/foo/index', '/' );
@interp_params = ( dhandler_names => ['dhandler'], index_names => ['index'] );
$try->( '/foo/', ['/foo/dhandler', '/foo/index'], '/foo/dhandler', '/' );
$try->( '/foo/', ['/foo/dhandler', '/foo/index=1'], '/foo/index', '/' );
}

sub test_decline : Tests {
Expand Down

0 comments on commit 7a17fe0

Please sign in to comment.