diff --git a/Changes b/Changes index 082ee3121..a3eb8f34f 100644 --- a/Changes +++ b/Changes @@ -4,10 +4,14 @@ Revision history for Dancer [ API CHANGES ] [ BUG FIXES ] + - Fix temporary directory handling in serialiser tests (PR 1133, nanis) [ DOCUMENTATION ] [ ENHANCEMENTS ] + - More efficient handling of large requests - don't store the raw request + body, but fish it out of the HTTP::Body object's temp file if required + (PR 1134, David Precious (bigpresh)) [ NEW FEATURES ] diff --git a/lib/Dancer/Route.pm b/lib/Dancer/Route.pm index 98268ebcb..14ab9330b 100644 --- a/lib/Dancer/Route.pm +++ b/lib/Dancer/Route.pm @@ -79,25 +79,14 @@ sub match { my $method = lc($request->method); my $path = $request->path_info; - my %params; Dancer::Logger::core( sprintf "Trying to match '%s %s' against /%s/ (generated from '%s')", $request->method, $path, $self->{_compiled_regexp}, $self->pattern ); - my @values = $path =~ $self->{_compiled_regexp}; - # the regex comments are how we know if we captured - # a splat or a megasplat - if( my @splat_or_megasplat - = $self->{_compiled_regexp} =~ /\(\?#((?:mega)?splat)\)/g ) { - for ( @values ) { - $_ = [ split '/' => $_ ] if ( shift @splat_or_megasplat ) =~ /megasplat/; - } - } - Dancer::Logger::core(" --> got ". map { defined $_ ? $_ : 'undef' } @values) if @values; @@ -124,18 +113,37 @@ sub match { # IT WILL MOVE VERY SOON $request->{_route_pattern} = $self->pattern; - # named tokens - my @tokens = @{$self->{_params} || []}; - - Dancer::Logger::core(" --> named tokens are: @tokens") if @tokens; - if (@tokens) { - for (my $i = 0; $i < @tokens; $i++) { - $params{$tokens[$i]} = $values[$i]; + # regex comments are how we know if we captured a token, + # splat or a megasplat + my @token_or_splat + = $self->{_compiled_regexp} =~ /\(\?#([token|(?:mega)?splat]+)\)/g; + if (@token_or_splat) { + # named tokens + my @tokens = @{$self->{_params} || []}; + Dancer::Logger::core(" --> named tokens are: @tokens") if @tokens; + + my %params; + my @splat; + for ( my $i = 0; $i < @values; $i++ ) { + # Is this value from a token? + if ( $token_or_splat[$i] eq 'token' ) { + $params{ shift @tokens } = $values[$i]; + next; + } + + # megasplat values are split on '/' + if ($token_or_splat[$i] eq 'megasplat') { + $values[$i] = [ split '/' => $values[$i] ]; + } + push @splat, $values[$i]; } - return $self->save_match_data($request, \%params); + return $self->save_match_data( $request, { + %params, + ( @splat ? ( splat => \@splat ) : () ), + }); } - elsif ($self->{_should_capture}) { + if ($self->{_should_capture}) { return $self->save_match_data($request, {splat => \@values}); } @@ -326,7 +334,7 @@ sub _build_regexp_from_string { if ($pattern =~ /:/) { @params = $pattern =~ /:([^\/\.\?]+)/g; if (@params) { - $pattern =~ s/(:[^\/\.\?]+)/\(\[\^\/\]\+\)/g; + $pattern =~ s!(:[^\/\.\?]+)!(?#token)([^/]+)!g; $capture = 1; } } diff --git a/t/03_route_handler/04_wildcards_megasplat.t b/t/03_route_handler/04_wildcards_megasplat.t index 2bd3c7ef8..6b0ed6a86 100644 --- a/t/03_route_handler/04_wildcards_megasplat.t +++ b/t/03_route_handler/04_wildcards_megasplat.t @@ -3,7 +3,7 @@ use Test::More; use Dancer::Test; -plan tests => 4; +plan tests => 6; get '/foo/**' => sub { show_splat() }; response_content_is [ GET => '/foo/a/b/c' ] => '(a,b,c)'; @@ -15,6 +15,19 @@ get '/alpha/**/gamma' => sub { show_splat() }; response_content_is [ GET => '/alpha/beta/delta/gamma' ] => '(beta,delta)'; response_content_is [ GET => '/alpha/beta/gamma' ] => '(beta)'; +# mixed tokens and splat +my $route_code = sub { + my $id = param 'id'; + $id = 'undef' unless defined $id; + my $splt = show_splat(); + return "$id:$splt" +}; +get '/some/:id/**/*' => $route_code; +response_content_is [ GET => '/some/where/to/run/and/hide' ] => 'where:(to,run,and):hide'; + +get '/some/*/**/:id?' => $route_code; +response_content_is [ GET => '/some/one/to/say/boo/' ] => 'undef:one:(to,say,boo)'; + sub show_splat { return join ':', map { ref $_ ? "(" . join( ',', @$_ ) . ")": $_ } splat; }