Dancer2

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

      unwind/unroll the stack for custom error reporting.
      (Yves Orton)
    * Added a cpanfile to allow installing local dependencies with 
      carton. (Mickey Nasriachi)
    * GH #1260: Specify optional charset to send_file and send_as
      (Russell @veryrusty Jenkins)
    * PR #1162: Change skeleton template tags so skeletons can generate
      applications that use Template Toolkit default tags (Jason Lewis)
    * GH #1149: Fix config loading inconsistencies, support local config
      files in addition to standard Dancer conf files (Jonathan Scott Duff)
    * PR #1269: Stash decoded body_parameters separately from those 
      in Plack::Request (Russell @veryrusty Jenkins)
    * GH #1253: Static middleware should send 304 Not Modified to enable
      intermediate level caching. (Russell @veryrusty Jenkins)

    [ DOCUMENTATION ]
    * GH #608: Remove extra general COPYRIGHT notice in Tutorial.
      (Sawyer X)
    * Simplify upload example. (Alberto Simões, Sawyer X)

0.203001  2016-09-03 20:59:47-05:00 America/Chicago

lib/Dancer2/Core/Request.pm  view on Meta::CPAN

# XXX: incompatible with Plack::Request
sub body { $_[0]->raw_body }

sub id { $_id }

# Private 'read-only' attributes for request params. See the params()
# method for the public interface.
#
# _body_params, _query_params and _route_params have setter methods that
# decode byte string to characters before setting; If you know you have
# decoded (character) params, such as output from a deserializer, you can
# set these directly in the request object hash to avoid the decode op.
sub _params { $_[0]->{'_params'} ||= $_[0]->_build_params }

sub _has_params { defined $_[0]->{'_params'} }

sub _body_params { $_[0]->{'_body_params'} ||= $_[0]->body_parameters->as_hashref_mixed }

sub _query_params { $_[0]->{'_query_params'} }

sub _set_query_params {

lib/Dancer2/Core/Request.pm  view on Meta::CPAN

    $self->serializer->has_request || $self->serializer->set_request($request);
    my $data = $serializer->deserialize($body);
    die $serializer_fail if $serializer_fail;

    # Set _body_params directly rather than using the setter. Deserializiation
    # returns characters and skipping the decode op in the setter ensures
    # that numerical data "stays" numerical; decoding an SV that is an IV
    # converts that to a PVIV. Some serializers are picky (JSON)..
    $self->{_body_params} = $data;

    # Set body parameters (decoded HMV)
    $self->{'body_parameters'} =
        Hash::MultiValue->from_mixed( is_hashref($data) ? %$data : () );

    return $data;
}

sub uri        { $_[0]->request_uri }

sub is_head    { $_[0]->method eq 'HEAD' }
sub is_post    { $_[0]->method eq 'POST' }

lib/Dancer2/Core/Request.pm  view on Meta::CPAN


sub parameters {
    my ( $self, $type ) = @_;

    # handle a specific case
    if ($type) {
        my $attr = "${type}_parameters";
        return $self->$attr;
    }

    # merge together the *decoded* parameters
    $self->{'merged_parameters'} ||= do {
        my $query = $self->query_parameters;
        my $body  = $self->body_parameters;
        my $route = $self->route_parameters; # not in Plack::Request
        Hash::MultiValue->new( map $_->flatten, $query, $body, $route );
    };
}

sub captures { shift->params->{captures} || {} }

lib/Dancer2/Core/Request.pm  view on Meta::CPAN

    my $new_params = $self->params;
    $new_request->{_query_params} = { %{ $self->{_query_params} || {} } };
    $new_request->{query_parameters} = $self->query_parameters->clone;
    for my $key ( keys %{ $params || {} } ) {
        my $value = $params->{$key};
        $new_params->{$key} = $value;
        $new_request->{_query_params}->{$key} = $value;
        $new_request->{query_parameters}->add( $key => $value );
    }

    # Copy params (these are already decoded)
    $new_request->{_params}       = $new_params;
    $new_request->{_body_params}  = $self->{_body_params};
    $new_request->{_route_params} = $self->{_route_params};
    $new_request->{headers}       = $self->headers;

    # Copy remaining settings
    $new_request->{is_behind_proxy} = $self->{is_behind_proxy};
    $new_request->{vars}            = $self->{vars};

    # Clone any existing decoded & cached body params. (GH#1116 GH#1269)
    $new_request->{'body_parameters'} = $self->body_parameters->clone;

    # Delete merged HMV parameters, allowing them to be reconstructed on first use.
    delete $new_request->{'merged_parameters'};

    return $new_request;
}


sub _set_route {

lib/Dancer2/Core/Request.pm  view on Meta::CPAN

should not try to read C<psgi.input> by hand. C<Dancer2::Core::Request>
already did it for you and kept the raw body untouched in there.

=head2 body_data

Returns the body of the request in data form, making it possible to distinguish
between C<body_parameters>, a representation of the request parameters
(L<Hash::MultiValue>) and other forms of content.

If a serializer is set, this is the deserialized request body. Otherwise this is
the decoded body parameters (if any), or the body content itself.

=head2 content

Returns the undecoded byte string POST body.

=head2 cookies

Returns a reference to a hash containing cookies, where the keys are the names of the
cookies and values are L<Dancer2::Core::Cookie> objects.

=head2 data

If the application has a serializer and if the request has serialized
content, returns the deserialized structure as a hashref.

lib/Dancer2/Core/Request.pm  view on Meta::CPAN


Return the remote host of the client. This only works with web servers configured
to do a reverse DNS lookup on the client's IP address.

=head2 request_method

Alias to the C<method> accessor, for backward-compatibility with C<CGI> interface.

=head2 request_uri

Return the raw, undecoded request URI path.

=head2 route

Return the L<route|Dancer2::Core::Route> which this request matched.

=head2 scheme

Return the scheme of the request

=head2 script_name

lib/Dancer2/Manual/Migration.pod  view on Meta::CPAN

=item * Engines handle encoding consistently

All engines are now expected to handle encoding on their own. User code
is expected to be in internal Perl representation.

Therefore, all serializers, for example, should deserialize to the Perl
representation. Templates, in turn, encode to UTF-8 if requested by the
user, or by default.

One side-effect of this is that C<from_yaml> will call L<YAML>'s C<Load>
function with decoded input.

=back

=head3 Templating engine changes

Whereas in Dancer1, the following were equivalent for Template::Toolkit:

    template 'foo/bar'
    template '/foo/bar'

t/deserialize.t  view on Meta::CPAN

}

# default back to JSON for the rest
# we're overiding a RO attribute only for this test!
Dancer2->runner->apps->[0]->set_serializer_engine(
    Dancer2::Serializer::JSON->new
);

note "Decoding of mixed route and deserialized body params"; {
    # Check integers from request body remain integers
    # but route params get decoded.
    test_psgi $app, sub {
        my $cb = shift;

        my @req_params = (
            "/from/D\x{c3}\x{bc}sseldorf", # /from/d%C3%BCsseldorf
            'Content-Type' => 'application/json',
            Content        => JSON::MaybeXS::encode_json({ population => 592393 }),
        );

        my $r = $cb->( POST @req_params );

        # Watch out for hash order randomization..
        is_deeply(
            $r->content,
            '["population",592393,"town","'."D\x{c3}\x{bc}sseldorf".'"]',
            "Integer from JSON body remains integer and route params decoded",
        );
    };
}

# Check body is deserialized on PATCH and DELETE.
# The RFC states the behaviour for DELETE is undefined; We take the lenient
# and deserialize it.
# http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-24#section-4.3.5
note "Deserialze any body content that is allowed or undefined"; {
    test_psgi $app, sub {

t/error.t  view on Meta::CPAN


    my $app = AppDies->to_app;
    isa_ok( $app, 'CODE', 'Got app' );

    test_psgi $app, sub {
        my $cb = shift;
        my $r  = $cb->( GET '/die' );

        is( $r->code, 500, '/die returns 500' );

        my $out = eval { JSON->new->utf8(0)->decode($r->decoded_content) };
        ok(!$@, 'JSON decoding serializer error produces no errors');
        isa_ok($out, 'HASH', 'Error deserializes to a hash');
        like($out->{exception}, qr/^oh no/, 'Get expected error message');
    };
};

subtest 'Error with exception object' => sub {
    local $@;
    eval { MyTestException->throw('a test exception object') };
    my $err = Dancer2::Core::Error->new(

t/issues/gh-797.t  view on Meta::CPAN


subtest 'Basic response' => sub {
    my $res = $test->request(
        POST '/',
        %headers,
        Content => encode_json { foo => 'bar' }
    );

    is( $res->code, 200, '[POST /] Correct response code' );

    my $response_data = decode_json( $res->decoded_content );
    is($response_data->{foo}, 'bar', "[POST /] Correct response data");
};

subtest 'Empty POST' => sub {
    my $res = $test->request( POST '/', {}, %headers );
    is(
        $res->code,
        200,
        '[POST /] Correct response code with empty post body',
    );

t/request_upload.t  view on Meta::CPAN

        is $undef, undef, '... and non-existent upload as scalar is undef';

        my @uploads = $req->upload('test_upload_file');
        like $uploads[0]->content, qr|^SHOGUN|,
          "content for first upload is ok, via 'upload'";
        like $uploads[1]->content, qr|^SHOGUN|,
          "... content for second as well";
        is $req->uploads->{'test_upload_file4'}[0]->content, 'SHOGUN4',
          "... content for other also good";

        note "headers and decoded filename";
        my $encoded_filename = encode_utf8($filename);
        is_deeply $uploads[0]->headers,
          { 'Content-Disposition' =>
              qq[form-data; name="test_upload_file"; filename="$encoded_filename"],
            'Content-Type' => 'text/plain',
          };
        is $uploads[0]->filename, $filename;

        note "type";
        is $uploads[0]->type, 'text/plain';

t/scope_problems/session_is_cleared.t  view on Meta::CPAN

ok($res1->is_success, '/normal_route does not error');

## This route should die and cause a broken state
my $res2 = $test->request(GET '/route_with_renderer_error');
ok(! $res2->is_success, '/route_with_renderer_error errors errors');

## This route will now have the same session as the previous route.
## Despite not having any cookies...
my $res3 = $test->request(GET '/normal_route');
ok($res3->is_success, '/normal_route does not error');
my $session_value = $res3->decoded_content;
isnt($session_value, "I SHOULD NOT BE IN THE NEXT SESSION", 
    '3rd route does not have session value from second route');

done_testing();

t/scope_problems/with_return_dies.t  view on Meta::CPAN

use Test::More;
use Plack::Test;
use HTTP::Request::Common qw/GET/;
use Dancer2;

my $test = Plack::Test->create(Dancer2->psgi_app);

## This route works fine
my $res1 = $test->request(GET '/normal_route');
ok($res1->is_success, '/normal_route does not error');
my $refaddr1 = $res1->decoded_content;

## This route should die
my $res2 = $test->request(GET '/route_with_renderer_error');
ok(! $res2->is_success, '/route_with_renderer_error errors errors');
my ($refaddr2) = $res2->decoded_content =~ /Hook error: (\d+)/;

## The first route now errors
## I can't seem to force with_return to fail in this test, even though I have
## it failing in production.
## So instead I'll check the refaddr of the with_return
## If refaddr of with_return is the same between route2 and route3, then this
## demonstrates that with_return has not been cleared between the two routes
## And that /normal_route is now using the wrong with_return.
## Possibly the old with_return hasn't been cleaned up? not sure.
my $res3 = $test->request(GET '/normal_route');
ok($res3->is_success, '/normal_route does not error');
my $refaddr3 = $res3->decoded_content;
isnt($refaddr1, $refaddr3, 'The 3rd request has a different with_return from the first run');
isnt($refaddr2, $refaddr3, 'The 3rd request has a different with_return from the second run');

done_testing();



( run in 1.744 second using v1.01-cache-2.11-cpan-26ccb49234f )