File Coverage

blib/lib/Dancer/Response.pm
Criterion Covered Total %
statement 98 102 96.0
branch 14 18 77.7
condition 2 3 66.6
subroutine 27 27 100.0
pod 10 15 66.6
total 151 165 91.5


line stmt bran cond sub pod time code
1             package Dancer::Response;
2             our $AUTHORITY = 'cpan:SUKRIA';
3             #ABSTRACT: Response object for Dancer
4             $Dancer::Response::VERSION = '1.3520';
5 189     189   204684 use strict;
  189         453  
  189         5632  
6 189     189   2400 use warnings;
  189         393  
  189         4538  
7 189     189   960 use Carp;
  189         407  
  189         10585  
8              
9 189     189   1360 use base 'Dancer::Object';
  189         443  
  189         21178  
10              
11 189     189   1755 use Scalar::Util qw/blessed/;
  189         534  
  189         11374  
12 189     189   85323 use Dancer::HTTP;
  189         572  
  189         9269  
13 189     189   79556 use Dancer::MIME;
  189         736  
  189         6841  
14 189     189   109429 use HTTP::Headers;
  189         1247401  
  189         8118  
15 189     189   3359 use Dancer::SharedData;
  189         466  
  189         6989  
16 189     189   1286 use Dancer::Exception qw(:all);
  189         473  
  189         29938  
17 189     189   93715 use Dancer::Continuation::Halted;
  189         591  
  189         187302  
18              
19             __PACKAGE__->attributes(qw/content pass streamed/);
20              
21             # constructor
22             sub init {
23 1031     1031 1 2567 my ( $self, %args ) = @_;
24 1031         3705 $self->attributes_defaults(
25             status => 200,
26             content => '',
27             pass => 0,
28             halted => 0,
29             forward => '',
30             encoded => 0,
31             );
32 1031 100       1801 $self->{headers} = HTTP::Headers->new(@{ $args{headers} || [] });
  1031         5738  
33 1031         35537 Dancer::SharedData->response($self);
34             }
35              
36             # helpers for the route handlers
37             sub exists {
38 482     482 1 834 my $self = shift;
39 482         1295 return length($self->content);
40             }
41              
42             sub status {
43 1227     1227 1 2612 my $self = shift;
44              
45 1227 100       2624 if (scalar @_ > 0) {
46 41         97 my $status = shift;
47 41         277 my $numeric_status = Dancer::HTTP->status($status);
48 41 50       137 if ($numeric_status) {
49 41         135 return $self->{status} = $numeric_status;
50             } else {
51 0         0 carp "Unrecognised HTTP status $status";
52 0         0 return;
53             }
54             } else {
55 1186         4131 return $self->{status};
56             }
57             }
58              
59             sub content_type {
60 492     492 1 4470 my $self = shift;
61              
62 492 100       1217 if (scalar @_ > 0) {
63 25         193 my $mimetype = Dancer::MIME->instance();
64 25         101 $self->header('Content-Type' => $mimetype->name_or_type(shift));
65             } else {
66 467         1143 return $self->header('Content-Type');
67             }
68             }
69              
70             sub has_passed {
71 510     510 1 811 my $self = shift;
72 510         1311 return $self->pass;
73             }
74              
75             sub forward {
76 15     15 0 33 my ($self, $uri, $params, $opts) = @_;
77 15         58 $self->{forward} = { to_url => $uri,
78             params => $params,
79             options => $opts };
80             }
81              
82             sub is_forwarded {
83 522     522 0 902 my $self = shift;
84 522         2134 $self->{forward};
85             }
86              
87             sub _already_encoded {
88 3     3   4 my $self = shift;
89 3         25 $self->{encoded};
90             }
91              
92             sub halt {
93 13     13 1 36 my ($self, $content) = @_;
94              
95 13 100 66     70 if ( blessed($content) && $content->isa('Dancer::Response') ) {
96 1         3 $content->{halted} = 1;
97 1         3 Dancer::SharedData->response($content);
98             }
99             else {
100 12 50       73 $self->content($content) if defined $content;
101 12         40 $self->{halted} = 1;
102             }
103             }
104              
105             sub halted {
106 301     301 1 497 my $self = shift;
107             return $self->{halted}
108 301         884 }
109              
110             sub header {
111 1558     1558 1 12220 my $self = shift;
112 1558         2335 my $header = shift;
113              
114 1558 100       3089 if (@_) {
115 1009         2801 $self->{headers}->header( $header => @_ );
116             }
117             else {
118 549         1748 return $self->{headers}->header($header);
119             }
120             }
121              
122             sub push_header {
123 25     25 0 49 my $self = shift;
124 25         43 my $header = shift;
125              
126 25 50       105 if (@_) {
127 25         73 foreach my $h(@_) {
128 25         105 $self->{headers}->push_header( $header => $h );
129             }
130             }
131             else {
132 0         0 return $self->{headers}->header($header);
133             }
134             }
135              
136             sub headers {
137 35     35 1 657 my $self = shift;
138 35         153 $self->{headers}->header(@_);
139             }
140              
141             sub headers_to_array {
142 501     501 1 3170 my $self = shift;
143              
144             # Time to finalise cookie headers, now
145 501         1313 $self->build_cookie_headers;
146              
147             my $headers = [
148             map {
149 344         3912 my $k = $_;
150             map {
151 361         10939 my $v = $_;
152 361         774 $v =~ s/^(.+)\r?\n(.*)$/$1\r\n $2/;
153 361         1828 ( $k => $v )
154 344         897 } $self->{headers}->header($_);
155             } $self->{headers}->header_field_names
156 501         1725 ];
157              
158 501         4817 return $headers;
159             }
160              
161             # Given a cookie name and object, add it to the cookies we're going to send.
162             # Stores them in a hashref within the response object until the response is
163             # being built, so that, if the same cookie is set multiple times, only the last
164             # value given to it will appear in a Set-Cookie header.
165             sub add_cookie {
166 44     44 0 193 my ($self, $name, $cookie) = @_;
167 44 50       211 if ($self->{_built_cookies}) {
168 0         0 die "Too late to set another cookie, headers already built";
169             }
170 44         344 $self->{_cookies}{$name} = $cookie;
171             }
172              
173              
174             # When the response is about to be rendered, that's when we build up the
175             # Set-Cookie headers
176             sub build_cookie_headers {
177 501     501 0 797 my $self = shift;
178 501         748 for my $name (keys %{ $self->{_cookies} }) {
  501         2686  
179 14         109 my $header = $self->{_cookies}{$name}->to_header;
180 14         77 $self->push_header(
181             'Set-Cookie' => $header,
182             );
183             }
184 501         1962 $self->{_built_cookies}++;
185             }
186             1;
187              
188             __END__