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.3514_04'; # TRIAL
5             $Dancer::Response::VERSION = '1.351404';
6 190     190   164664 use strict;
  190         352  
  190         4874  
7 190     190   832 use warnings;
  190         331  
  190         3859  
8 190     190   869 use Carp;
  190         359  
  190         10114  
9              
10 190     190   1153 use base 'Dancer::Object';
  190         404  
  190         18960  
11              
12 190     190   1226 use Scalar::Util qw/blessed/;
  190         395  
  190         8376  
13 190     190   67931 use Dancer::HTTP;
  190         490  
  190         7642  
14 190     190   65913 use Dancer::MIME;
  190         569  
  190         5134  
15 190     190   83383 use HTTP::Headers;
  190         1014791  
  190         5990  
16 190     190   2536 use Dancer::SharedData;
  190         348  
  190         4575  
17 190     190   889 use Dancer::Exception qw(:all);
  190         367  
  190         23779  
18 190     190   74480 use Dancer::Continuation::Halted;
  190         459  
  190         149755  
19              
20             __PACKAGE__->attributes(qw/content pass streamed/);
21              
22             # constructor
23             sub init {
24 1037     1037 1 2276 my ( $self, %args ) = @_;
25 1037         3371 $self->attributes_defaults(
26             status => 200,
27             content => '',
28             pass => 0,
29             halted => 0,
30             forward => '',
31             encoded => 0,
32             );
33 1037 100       1477 $self->{headers} = HTTP::Headers->new(@{ $args{headers} || [] });
  1037         4711  
34 1037         29571 Dancer::SharedData->response($self);
35             }
36              
37             # helpers for the route handlers
38             sub exists {
39 485     485 1 741 my $self = shift;
40 485         1165 return length($self->content);
41             }
42              
43             sub status {
44 1233     1233 1 2318 my $self = shift;
45              
46 1233 100       2269 if (scalar @_ > 0) {
47 41         64 my $status = shift;
48 41         175 my $numeric_status = Dancer::HTTP->status($status);
49 41 50       112 if ($numeric_status) {
50 41         114 return $self->{status} = $numeric_status;
51             } else {
52 0         0 carp "Unrecognised HTTP status $status";
53 0         0 return;
54             }
55             } else {
56 1192         3566 return $self->{status};
57             }
58             }
59              
60             sub content_type {
61 495     495 1 3759 my $self = shift;
62              
63 495 100       1053 if (scalar @_ > 0) {
64 25         111 my $mimetype = Dancer::MIME->instance();
65 25         74 $self->header('Content-Type' => $mimetype->name_or_type(shift));
66             } else {
67 470         1144 return $self->header('Content-Type');
68             }
69             }
70              
71             sub has_passed {
72 513     513 1 751 my $self = shift;
73 513         1233 return $self->pass;
74             }
75              
76             sub forward {
77 15     15 0 26 my ($self, $uri, $params, $opts) = @_;
78 15         46 $self->{forward} = { to_url => $uri,
79             params => $params,
80             options => $opts };
81             }
82              
83             sub is_forwarded {
84 525     525 0 813 my $self = shift;
85 525         1854 $self->{forward};
86             }
87              
88             sub _already_encoded {
89 3     3   5 my $self = shift;
90 3         26 $self->{encoded};
91             }
92              
93             sub halt {
94 13     13 1 30 my ($self, $content) = @_;
95              
96 13 100 66     56 if ( blessed($content) && $content->isa('Dancer::Response') ) {
97 1         3 $content->{halted} = 1;
98 1         3 Dancer::SharedData->response($content);
99             }
100             else {
101 12 50       59 $self->content($content) if defined $content;
102 12         24 $self->{halted} = 1;
103             }
104             }
105              
106             sub halted {
107 301     301 1 421 my $self = shift;
108             return $self->{halted}
109 301         745 }
110              
111             sub header {
112 1567     1567 1 10978 my $self = shift;
113 1567         1897 my $header = shift;
114              
115 1567 100       2516 if (@_) {
116 1015         2356 $self->{headers}->header( $header => @_ );
117             }
118             else {
119 552         1561 return $self->{headers}->header($header);
120             }
121             }
122              
123             sub push_header {
124 25     25 0 50 my $self = shift;
125 25         35 my $header = shift;
126              
127 25 50       67 if (@_) {
128 25         54 foreach my $h(@_) {
129 25         95 $self->{headers}->push_header( $header => $h );
130             }
131             }
132             else {
133 0         0 return $self->{headers}->header($header);
134             }
135             }
136              
137             sub headers {
138 35     35 1 593 my $self = shift;
139 35         112 $self->{headers}->header(@_);
140             }
141              
142             sub headers_to_array {
143 504     504 1 2016 my $self = shift;
144              
145             # Time to finalise cookie headers, now
146 504         1458 $self->build_cookie_headers;
147              
148             my $headers = [
149             map {
150 344         3168 my $k = $_;
151             map {
152 361         8799 my $v = $_;
153 361         634 $v =~ s/^(.+)\r?\n(.*)$/$1\r\n $2/;
154 361         1133 ( $k => $v )
155 344         771 } $self->{headers}->header($_);
156             } $self->{headers}->header_field_names
157 504         1557 ];
158              
159 504         4559 return $headers;
160             }
161              
162             # Given a cookie name and object, add it to the cookies we're going to send.
163             # Stores them in a hashref within the response object until the response is
164             # being built, so that, if the same cookie is set multiple times, only the last
165             # value given to it will appear in a Set-Cookie header.
166             sub add_cookie {
167 44     44 0 113 my ($self, $name, $cookie) = @_;
168 44 50       151 if ($self->{_built_cookies}) {
169 0         0 die "Too late to set another cookie, headers already built";
170             }
171 44         211 $self->{_cookies}{$name} = $cookie;
172             }
173              
174              
175             # When the response is about to be rendered, that's when we build up the
176             # Set-Cookie headers
177             sub build_cookie_headers {
178 504     504 0 739 my $self = shift;
179 504         652 for my $name (keys %{ $self->{_cookies} }) {
  504         2388  
180 14         109 my $header = $self->{_cookies}{$name}->to_header;
181 14         51 $self->push_header(
182             'Set-Cookie' => $header,
183             );
184             }
185 504         1861 $self->{_built_cookies}++;
186             }
187             1;
188              
189             __END__