X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst.pm;h=20595e057521bd7e886da637773bdb839d239074;hp=0d8a817cc91d6053899a046da5c9e9e4a3a93f10;hb=d2b583c3793b7ccf5ac228206c2fdad9bf7593aa;hpb=772bd9deac85d462d77bfe2cbbe73f3de1688ebf diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index 0d8a817..20595e0 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -1447,6 +1447,10 @@ In general the scheme of the generated URI object will follow the incoming reque however if your targeted action or action chain has the Scheme attribute it will use that instead. +Also, if the targeted Action or Action chain declares Args/CaptureArgs that have +type constraints, we will require that your proposed URL verify on those declared +constraints. + =cut sub uri_for { @@ -1469,15 +1473,17 @@ sub uri_for { foreach my $arg (@args) { if(ref($arg)||'' eq 'ARRAY') { push @encoded_args, [map { - my $encoded = encode_utf8 $_; - $encoded =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; - $encoded; + # my $encoded = encode_utf8 $_; + # $encoded =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; + # $encoded; + $_ } @$arg]; } else { push @encoded_args, do { - my $encoded = encode_utf8 $arg; - $encoded =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; - $encoded; + # my $encoded = encode_utf8 $arg; + # $encoded =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; + # $encoded; + $arg; } } } @@ -1491,20 +1497,36 @@ sub uri_for { : ()) ]; my $action = $path; + my $expanded_action = $c->dispatcher->expand_action( $action ); + my $num_captures = $expanded_action->number_of_captures; + # ->uri_for( $action, \@captures_and_args, \%query_values? ) if( !@encoded_args && $action->number_of_args ) { - my $expanded_action = $c->dispatcher->expand_action( $action ); - my $num_captures = $expanded_action->number_of_captures; - unshift @encoded_args, splice @$captures, $num_captures; + unshift @encoded_args, splice @$captures, $num_captures; + } + + if($num_captures) { + unless($expanded_action->match_captures($c, $captures)) { + carp "captures [@{$captures}] do not match the type constraints in actionchain ending with '$action'"; + return; + } } - $path = $c->dispatcher->uri_for_action($action, $captures); + $path = $c->dispatcher->uri_for_action($action, $captures); if (not defined $path) { $c->log->debug(qq/Can't find uri_for action '$action' @$captures/) if $c->debug; return undef; } $path = '/' if $path eq ''; + + # At this point @encoded_args is the remaining Args (all captures removed). + if($expanded_action->has_args_constraints) { + unless($expanded_action->match_args($c,\@encoded_args)) { + carp "args [@encoded_args] do not match the type constraints in action '$expanded_action'"; + return; + } + } } unshift(@encoded_args, $path); @@ -1567,6 +1589,11 @@ sub uri_for { } @keys); } + $base = encode_utf8 $base; + $base =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; + $args = encode_utf8 $args; + $args =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; + my $res = bless(\"${base}${args}${query}", $class); $res; } @@ -3904,6 +3931,51 @@ parameter to true. =item * +C + +If true, then do not try to character decode any wide characters in your +request URL query or keywords. Most readings of the relevent specifications +suggest these should be UTF-* encoded, which is the default that L +will use, hwoever if you are creating a lot of URLs manually or have external +evil clients, this might cause you trouble. If you find the changes introduced +in Catalyst version 5.90080+ break some of your query code, you may disable +the UTF-8 decoding globally using this configuration. + +This setting takes precedence over C and +C + +=item * + +C + +By default we decode query and keywords in your request URL using UTF-8, which +is our reading of the relevent specifications. This setting allows one to +specify a fixed value for how to decode your query. You might need this if +you are doing a lot of custom encoding of your URLs and not using UTF-8. + +This setting take precedence over C. + +=item * + +C + +Setting this to true will default your query decoding to whatever your +general global encoding is (the default is UTF-8). + +=item * + +C + +In older versions of Catalyst, when more than one action matched the same path +AND all those matching actions declared Args(0), we'd break the tie by choosing +the first action defined. We now normalized how Args(0) works so that it +follows the same rule as Args(N), which is to say when we need to break a tie +we choose the LAST action defined. If this breaks your code and you don't +have time to update to follow the new normalized approach, you may set this +value to true and it will globally revert to the original chaining behavior. + +=item * + C - See L. =item *