File Coverage

blib/lib/Plack/Middleware/ParseContent.pm
Criterion Covered Total %
statement 45 47 95.7
branch 7 14 50.0
condition 2 6 33.3
subroutine 10 10 100.0
pod 2 2 100.0
total 66 79 83.5


line stmt bran cond sub pod time code
1             package Plack::Middleware::ParseContent;
2              
3 2     2   77258 use 5.006;
  2         6  
  2         79  
4 2     2   9 use strict;
  2         2  
  2         56  
5 2     2   8 use warnings FATAL => 'all';
  2         7  
  2         82  
6              
7 2     2   407 use parent qw( Plack::Middleware );
  2         238  
  2         376  
8              
9 2     2   12783 use Plack::Request;
  2         724014  
  2         73  
10              
11 2     2   1012 use HTTP::Exception '4XX';
  2         9150  
  2         11  
12              
13 2     2   67449 use JSON::XS;
  2         9353  
  2         123  
14 2     2   958 use YAML::Syck;
  2         3424  
  2         746  
15              
16             =head1 NAME
17              
18             Plack::Middleware::ParseContent - Parse content of input data by Content-Type header.
19              
20             =head1 VERSION
21              
22             Version 0.01
23              
24             =cut
25              
26             our $VERSION = '0.01';
27              
28              
29             =head1 SYNOPSIS
30              
31             use Plack::Middleware::ParseContent;
32              
33             builder {
34             enable 'ParseContent', xyz => sub{ return {test => $_[0]} };
35             mount "/" => sub {
36             my ($env) = @_;
37              
38             ### Make some action with posted data
39             $env->{'restapi.parseddata'};
40              
41             return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'app/root' ] ];
42             };
43             };
44              
45             =head1 DESCRIPTION
46              
47             Parse input content and save it to plack env as 'restapi.parseddata'.
48              
49             For complete RestAPI in Perl use:
50              
51             =over 4
52              
53             =item * Plack::Middleware::RestAPI
54              
55             =item * Plack::Middleware::SetAccept
56              
57             =item * Plack::Middleware::FormatOutput
58              
59             =back
60              
61             =head1 CONSTANTS
62              
63             =head2 DEFAULT MIME TYPES
64              
65             =over 4
66              
67             =item * application/json
68              
69             =item * text/yaml
70              
71             =item * text/plain
72              
73             =back
74              
75             =cut
76              
77             my $Mime_types = {
78             'application/json' => sub { &decode_json($_[0]) },
79             'text/yaml' => sub { &YAML::Syck::Load($_[0]) },
80             'text/plain' => sub { $_[0] },
81             };
82              
83             sub prepare_app {
84 1     1 1 338 my $self = shift;
85              
86             # Add new mime types to env
87 1         65 foreach my $par (keys %$self){
88 2 50       7 next unless ref $self->{$par} eq 'CODE'; # just add mime types that are reference to sub
89 2         7 $Mime_types->{$par} = $self->{$par};
90             }
91             }
92              
93             sub call {
94 4     4 1 22917 my($self, $env) = @_;
95              
96             ### Get method
97 4         8 my $method = $env->{REQUEST_METHOD};
98              
99             ### Get dat from env
100 4         4 my $data;
101              
102 4 50 33     20 if ($method eq 'POST' or $method eq 'PUT') {
103 4         29 my $req = Plack::Request->new($env);
104              
105             ### Get data for fomr or from body
106 4 50       42 if ($env->{CONTENT_TYPE} eq 'application/x-www-form-urlencoded') {
107 0         0 $data = $req->body_parameters;
108             } else {
109 4         13 $data = $req->content();
110             }
111              
112             ### Parse data by content-type
113 4         3720 my $acceptedMimeType;
114 4 50       14 if ($req->content_type){
115 4         58 ($acceptedMimeType) = grep( exists $Mime_types->{$_} , split(/;/, $req->content_type, 2));
116             }else{
117 0         0 $acceptedMimeType = 'text/plain'; # set default mime type
118             }
119              
120             ### Parsed data
121 4         34 my $parsed;
122 4 50 33     28 if ($data && $acceptedMimeType){
123 4         8 $parsed = eval {$Mime_types->{$acceptedMimeType}->($data)};
  4         13  
124 4 50       89 HTTP::Exception::400->throw(status_message => "Parser error: $@") if $@;
125             }
126              
127             ### Set parsed data to env
128              
129 4 50       22 $env->{'restapi.parseddata'} = $parsed if $parsed;
130             }
131              
132 4         23 return $self->app->($env);
133             }
134              
135             =head1 STORED PARAMS TO ENV (Fulfill the PSGI specification)
136              
137             =over 4
138              
139             =item restapi.parseddata
140              
141             Store parsed data from input content.
142              
143             =back
144              
145             =head1 TUTORIAL
146              
147             L
148              
149             =head1 AUTHOR
150              
151             Vaclav Dovrtel, C<< >>
152              
153             =head1 BUGS
154              
155             Please report any bugs or feature requests to github repository.
156              
157             =head1 ACKNOWLEDGEMENTS
158              
159             Inspired by L
160              
161             =head1 REPOSITORY
162              
163             L
164              
165             =head1 LICENSE AND COPYRIGHT
166              
167             Copyright 2015 Vaclav Dovrtel.
168              
169             This program is free software; you can redistribute it and/or modify it
170             under the terms of either: the GNU General Public License as published
171             by the Free Software Foundation; or the Artistic License.
172              
173             See L for more information.
174              
175             =cut
176              
177             1; # End of Plack::Middleware::ParseContent