convert to Dist::Zilla
[catagits/Catalyst-Action-REST.git] / lib / Catalyst / Action / Deserialize / Data / Serializer.pm
1 package Catalyst::Action::Deserialize::Data::Serializer;
2
3 use Moose;
4 use namespace::autoclean;
5
6 extends 'Catalyst::Action';
7 use Data::Serializer;
8 use Safe;
9 use Scalar::Util qw(openhandle);
10 my $compartment = Safe->new;
11 $compartment->permit_only( qw(padany null lineseq const pushmark list anonhash anonlist refgen leaveeval undef) );
12
13 sub execute {
14     my $self = shift;
15     my ( $controller, $c, $serializer ) = @_;
16
17     my $sp = $serializer;
18     $sp =~ s/::/\//g;
19     $sp .= ".pm";
20     eval {
21         require $sp
22     };
23     if ($@) {
24         $c->log->debug("Could not load $serializer, refusing to serialize: $@")
25             if $c->debug;
26         return 0;
27     }
28     my $body = $c->request->body;
29     if ($body) {
30         my $rbody = '';
31
32         if(openhandle $body) {
33             seek($body, 0, 0); # in case something has already read from it
34             while ( defined( my $line = <$body> ) ) {
35                 $rbody .= $line;
36             }
37         } else {
38             $rbody = $body;
39         }
40
41         my $rdata;
42         if ( $serializer eq "Data::Dumper" ) {
43             # Taken from Data::Serialize::Data::Dumper::deserialize, but run within a Safe compartment
44             my $code = $rbody =~ /^\{/ ? "+".$rbody : $rbody;
45             $rdata = $compartment->reval( $code );
46         }
47         else {
48             my $dso = Data::Serializer->new( serializer => $serializer );
49             eval {
50                 $rdata = $dso->raw_deserialize($rbody);
51             };
52         }
53         if ($@) {
54             return $@;
55         }
56         $c->request->data($rdata);
57     } else {
58         $c->log->debug(
59             'I would have deserialized, but there was nothing in the body!')
60                 if $c->debug;
61     }
62     return 1;
63 }
64
65 __PACKAGE__->meta->make_immutable;
66
67 1;