| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Dancer::Request; |
|
2
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:SUKRIA'; |
|
3
|
|
|
|
|
|
|
#ABSTRACT: interface for accessing incoming requests |
|
4
|
|
|
|
|
|
|
$Dancer::Request::VERSION = '1.3521'; |
|
5
|
182
|
|
|
182
|
|
905672
|
use strict; |
|
|
182
|
|
|
|
|
501
|
|
|
|
182
|
|
|
|
|
5516
|
|
|
6
|
182
|
|
|
182
|
|
948
|
use warnings; |
|
|
182
|
|
|
|
|
389
|
|
|
|
182
|
|
|
|
|
4180
|
|
|
7
|
182
|
|
|
182
|
|
929
|
use Carp; |
|
|
182
|
|
|
|
|
1606
|
|
|
|
182
|
|
|
|
|
9693
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
182
|
|
|
182
|
|
1192
|
use base 'Dancer::Object'; |
|
|
182
|
|
|
|
|
390
|
|
|
|
182
|
|
|
|
|
26334
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
182
|
|
|
182
|
|
9460
|
use Dancer::Config 'setting'; |
|
|
182
|
|
|
|
|
427
|
|
|
|
182
|
|
|
|
|
8795
|
|
|
12
|
182
|
|
|
182
|
|
81732
|
use Dancer::Request::Upload; |
|
|
182
|
|
|
|
|
522
|
|
|
|
182
|
|
|
|
|
4612
|
|
|
13
|
182
|
|
|
182
|
|
72361
|
use Dancer::SharedData; |
|
|
182
|
|
|
|
|
691
|
|
|
|
182
|
|
|
|
|
5947
|
|
|
14
|
182
|
|
|
182
|
|
81518
|
use Dancer::Session; |
|
|
182
|
|
|
|
|
539
|
|
|
|
182
|
|
|
|
|
6667
|
|
|
15
|
182
|
|
|
182
|
|
1272
|
use Dancer::Exception qw(:all); |
|
|
182
|
|
|
|
|
478
|
|
|
|
182
|
|
|
|
|
22679
|
|
|
16
|
182
|
|
|
182
|
|
1339
|
use Encode; |
|
|
182
|
|
|
|
|
637
|
|
|
|
182
|
|
|
|
|
15016
|
|
|
17
|
182
|
|
|
182
|
|
86824
|
use HTTP::Body; |
|
|
182
|
|
|
|
|
3527353
|
|
|
|
182
|
|
|
|
|
6115
|
|
|
18
|
182
|
|
|
182
|
|
1425
|
use URI; |
|
|
182
|
|
|
|
|
640
|
|
|
|
182
|
|
|
|
|
4956
|
|
|
19
|
182
|
|
|
182
|
|
1133
|
use URI::Escape; |
|
|
182
|
|
|
|
|
492
|
|
|
|
182
|
|
|
|
|
316902
|
|
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
my @http_env_keys = ( |
|
22
|
|
|
|
|
|
|
'user_agent', 'accept_language', 'accept_charset', |
|
23
|
|
|
|
|
|
|
'accept_encoding', 'keep_alive', 'connection', 'accept', |
|
24
|
|
|
|
|
|
|
'accept_type', 'referer', #'host', managed manually |
|
25
|
|
|
|
|
|
|
); |
|
26
|
|
|
|
|
|
|
my $count = 0; |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
__PACKAGE__->attributes( |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# query |
|
31
|
|
|
|
|
|
|
'env', 'path', 'method', |
|
32
|
|
|
|
|
|
|
'content_type', 'content_length', |
|
33
|
|
|
|
|
|
|
'id', |
|
34
|
|
|
|
|
|
|
'uploads', 'headers', 'path_info', |
|
35
|
|
|
|
|
|
|
'ajax', 'is_forward', |
|
36
|
|
|
|
|
|
|
@http_env_keys, |
|
37
|
|
|
|
|
|
|
); |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub new { |
|
40
|
611
|
|
|
611
|
1
|
84201
|
my ($self, @args) = @_; |
|
41
|
611
|
50
|
|
|
|
1774
|
if (@args == 1) { |
|
42
|
0
|
|
|
|
|
0
|
@args = ('env' => $args[0]); |
|
43
|
0
|
|
|
|
|
0
|
Dancer::Deprecation->deprecated( |
|
44
|
|
|
|
|
|
|
fatal => 1, |
|
45
|
|
|
|
|
|
|
feature => 'Calling Dancer::Request->new($env)', |
|
46
|
|
|
|
|
|
|
version => 1.3059, |
|
47
|
|
|
|
|
|
|
reason => 'Please use Dancer::Request->new( env => $env ) instead', |
|
48
|
|
|
|
|
|
|
); |
|
49
|
|
|
|
|
|
|
} |
|
50
|
611
|
|
|
|
|
2869
|
$self->SUPER::new(@args); |
|
51
|
|
|
|
|
|
|
} |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# aliases |
|
54
|
1
|
|
|
1
|
1
|
4
|
sub agent { $_[0]->user_agent } |
|
55
|
19
|
|
|
19
|
1
|
56
|
sub remote_address { $_[0]->address } |
|
56
|
1
|
50
|
|
1
|
1
|
22
|
sub forwarded_for_address { $_[0]->env->{'X_FORWARDED_FOR'} || $_[0]->env->{'HTTP_X_FORWARDED_FOR'} } |
|
57
|
|
|
|
|
|
|
sub address { |
|
58
|
|
|
|
|
|
|
setting('behind_proxy') |
|
59
|
|
|
|
|
|
|
? $_[0]->forwarded_for_address() |
|
60
|
|
|
|
|
|
|
: $_[0]->env->{REMOTE_ADDR} |
|
61
|
19
|
50
|
|
19
|
1
|
51
|
} |
|
62
|
|
|
|
|
|
|
sub host { |
|
63
|
34
|
50
|
|
34
|
1
|
109
|
if (@_==2) { |
|
64
|
0
|
|
|
|
|
0
|
$_[0]->{host} = $_[1]; |
|
65
|
|
|
|
|
|
|
} else { |
|
66
|
34
|
|
|
|
|
54
|
my $host; |
|
67
|
34
|
100
|
33
|
|
|
112
|
$host = ($_[0]->env->{X_FORWARDED_HOST} || $_[0]->env->{HTTP_X_FORWARDED_HOST}) if setting('behind_proxy'); |
|
68
|
34
|
100
|
100
|
|
|
320
|
$host || $_[0]->{host} || $_[0]->env->{HTTP_HOST}; |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
} |
|
71
|
0
|
|
|
0
|
1
|
0
|
sub remote_host { $_[0]->env->{REMOTE_HOST} } |
|
72
|
1
|
|
|
1
|
1
|
7
|
sub protocol { $_[0]->env->{SERVER_PROTOCOL} } |
|
73
|
1
|
|
|
1
|
1
|
5
|
sub port { $_[0]->env->{SERVER_PORT} } |
|
74
|
617
|
|
|
617
|
1
|
2387
|
sub request_uri { $_[0]->env->{REQUEST_URI} } |
|
75
|
1
|
|
|
1
|
1
|
26
|
sub user { $_[0]->env->{REMOTE_USER} } |
|
76
|
622
|
|
|
622
|
1
|
1696
|
sub script_name { $_[0]->env->{SCRIPT_NAME} } |
|
77
|
1
|
50
|
|
1
|
1
|
5
|
sub request_base { $_[0]->env->{REQUEST_BASE} || $_[0]->env->{HTTP_REQUEST_BASE} } |
|
78
|
|
|
|
|
|
|
sub scheme { |
|
79
|
33
|
|
|
33
|
1
|
50
|
my $scheme; |
|
80
|
33
|
100
|
|
|
|
84
|
if (setting('behind_proxy')) { |
|
81
|
|
|
|
|
|
|
# PSGI specs say that X_FORWARDED_PROTO will |
|
82
|
|
|
|
|
|
|
# be converted into HTTP_X_FORWARDED_PROTO |
|
83
|
|
|
|
|
|
|
# but Dancer::Test doesn't use PSGI (for now) |
|
84
|
|
|
|
|
|
|
$scheme = $_[0]->env->{'HTTP_X_FORWARDED_PROTO'} |
|
85
|
|
|
|
|
|
|
|| $_[0]->env->{'X_FORWARDED_PROTOCOL'} |
|
86
|
|
|
|
|
|
|
|| $_[0]->env->{'HTTP_X_FORWARDED_PROTOCOL'} |
|
87
|
|
|
|
|
|
|
|| $_[0]->env->{'HTTP_FORWARDED_PROTO'} |
|
88
|
5
|
|
100
|
|
|
12
|
|| $_[0]->env->{'X_FORWARDED_PROTO'} |
|
89
|
|
|
|
|
|
|
|| "" |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
return $scheme |
|
92
|
|
|
|
|
|
|
|| $_[0]->env->{'psgi.url_scheme'} |
|
93
|
33
|
|
50
|
|
|
356
|
|| $_[0]->env->{'PSGI.URL_SCHEME'} |
|
94
|
|
|
|
|
|
|
|| ""; |
|
95
|
|
|
|
|
|
|
} |
|
96
|
1
|
|
|
1
|
1
|
5
|
sub secure { $_[0]->scheme eq 'https' } |
|
97
|
3
|
|
|
3
|
1
|
12
|
sub uri { $_[0]->request_uri } |
|
98
|
|
|
|
|
|
|
|
|
99
|
18
|
|
|
18
|
1
|
78
|
sub is_head { $_[0]->{method} eq 'HEAD' } |
|
100
|
10
|
|
|
10
|
1
|
77
|
sub is_post { $_[0]->{method} eq 'POST' } |
|
101
|
2
|
|
|
2
|
1
|
13
|
sub is_get { $_[0]->{method} eq 'GET' } |
|
102
|
15
|
|
|
15
|
1
|
89
|
sub is_put { $_[0]->{method} eq 'PUT' } |
|
103
|
2
|
|
|
2
|
1
|
28
|
sub is_delete { $_[0]->{method} eq 'DELETE' } |
|
104
|
1
|
|
|
1
|
1
|
18
|
sub is_patch { $_[0]->{method} eq 'PATCH' } |
|
105
|
7
|
|
|
7
|
1
|
28
|
sub header { $_[0]->{headers}->header($_[1]) } |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# We used to store the whole raw unparsed body; this was a big problem for large |
|
108
|
|
|
|
|
|
|
# file uploads (Issue 1129). |
|
109
|
|
|
|
|
|
|
# The original fix was to stop doing so, and replace the accessor with one that |
|
110
|
|
|
|
|
|
|
# would read it out of the temp file returned by HTTP::Body->body - but that |
|
111
|
|
|
|
|
|
|
# doesn't work for e.g. parsed form submissions, only certain types. |
|
112
|
|
|
|
|
|
|
# So, back to the older way - we may have a request body squirreled away |
|
113
|
|
|
|
|
|
|
# in memory if the config included the raw_request_body_in_ram boolean |
|
114
|
17
|
|
|
17
|
1
|
106
|
sub body { $_[0]->{body} } |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
# public interface compat with CGI.pm objects |
|
117
|
1
|
|
|
1
|
1
|
5
|
sub request_method { method(@_) } |
|
118
|
2
|
|
|
2
|
1
|
8
|
sub Vars { params(@_) } |
|
119
|
615
|
100
|
|
615
|
1
|
1918
|
sub input_handle { $_[0]->env->{'psgi.input'} || $_[0]->env->{'PSGI.INPUT'} } |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
sub init { |
|
122
|
611
|
|
|
611
|
1
|
1272
|
my ($self) = @_; |
|
123
|
|
|
|
|
|
|
|
|
124
|
611
|
|
50
|
|
|
2125
|
$self->{env} ||= {}; |
|
125
|
611
|
|
|
|
|
1679
|
$self->{path} = undef; |
|
126
|
611
|
|
|
|
|
1122
|
$self->{method} = undef; |
|
127
|
611
|
|
|
|
|
1504
|
$self->{params} = {}; |
|
128
|
611
|
|
100
|
|
|
3438
|
$self->{is_forward} ||= 0; |
|
129
|
611
|
|
100
|
|
|
1989
|
$self->{content_length} = $self->env->{CONTENT_LENGTH} || 0; |
|
130
|
611
|
|
100
|
|
|
1565
|
$self->{content_type} = $self->env->{CONTENT_TYPE} || ''; |
|
131
|
611
|
|
|
|
|
1963
|
$self->{id} = ++$count; |
|
132
|
611
|
|
|
|
|
1436
|
$self->{_chunk_size} = 4096; |
|
133
|
611
|
|
|
|
|
1084
|
$self->{_read_position} = 0; |
|
134
|
611
|
|
|
|
|
1212
|
$self->{_body_params} = undef; |
|
135
|
611
|
|
|
|
|
1423
|
$self->{_query_params} = undef; |
|
136
|
611
|
|
|
|
|
1490
|
$self->{_route_params} = {}; |
|
137
|
|
|
|
|
|
|
|
|
138
|
611
|
|
|
|
|
1908
|
$self->_build_headers(); |
|
139
|
611
|
|
|
|
|
1808
|
$self->_build_request_env(); |
|
140
|
611
|
50
|
|
|
|
1831
|
$self->_build_path() unless $self->path; |
|
141
|
611
|
50
|
|
|
|
1877
|
$self->_build_path_info() unless $self->path_info; |
|
142
|
611
|
50
|
|
|
|
1995
|
$self->_build_method() unless $self->method; |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
$self->{_http_body} |
|
145
|
611
|
|
|
|
|
2015
|
= HTTP::Body->new($self->content_type, $self->content_length); |
|
146
|
611
|
|
|
|
|
46567
|
$self->{_http_body}->cleanup(1); |
|
147
|
611
|
|
|
|
|
4189
|
$self->{body} = ''; # default, because we might not store it now. |
|
148
|
611
|
|
|
|
|
2580
|
$self->_build_params(); |
|
149
|
611
|
50
|
|
|
|
2183
|
$self->_build_uploads unless $self->uploads; |
|
150
|
611
|
|
|
|
|
1887
|
$self->{ajax} = $self->is_ajax; |
|
151
|
|
|
|
|
|
|
|
|
152
|
611
|
|
|
|
|
1529
|
return $self; |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub to_string { |
|
156
|
1
|
|
|
1
|
1
|
4
|
my ($self) = @_; |
|
157
|
1
|
|
|
|
|
4
|
return "[#" . $self->id . "] " . $self->method . " " . $self->path; |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# helper for building a request object by hand |
|
161
|
|
|
|
|
|
|
# with the given method, path, params, body and headers. |
|
162
|
|
|
|
|
|
|
sub new_for_request { |
|
163
|
571
|
|
|
571
|
1
|
3062
|
my ($class, $method, $uri, $params, $body, $headers, $extra_env) = @_; |
|
164
|
571
|
|
100
|
|
|
2541
|
$params ||= {}; |
|
165
|
571
|
|
100
|
|
|
1763
|
$extra_env ||= {}; |
|
166
|
571
|
|
|
|
|
1272
|
$method = uc($method); |
|
167
|
|
|
|
|
|
|
|
|
168
|
571
|
|
|
|
|
3613
|
my ( $path, $query_string ) = ( $uri =~ /([^?]*)(?:\?(.*))?/s ); #from HTTP::Server::Simple |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
my $env = { |
|
171
|
|
|
|
|
|
|
%ENV, |
|
172
|
571
|
|
|
|
|
14534
|
%{$extra_env}, |
|
173
|
|
|
|
|
|
|
PATH_INFO => $path, |
|
174
|
571
|
|
100
|
|
|
4734
|
QUERY_STRING => $query_string || $ENV{QUERY_STRING} || '', |
|
175
|
|
|
|
|
|
|
REQUEST_METHOD => $method |
|
176
|
|
|
|
|
|
|
}; |
|
177
|
571
|
100
|
|
|
|
3414
|
$env->{CONTENT_LENGTH} = defined($body) ? length($body) : 0 if !exists $env->{CONTENT_LENGTH}; |
|
|
|
100
|
|
|
|
|
|
|
178
|
571
|
|
|
|
|
1913
|
my $req = $class->new(env => $env); |
|
179
|
571
|
|
|
|
|
899
|
$req->{params} = {%{$req->{params}}, %{$params}}; |
|
|
571
|
|
|
|
|
1254
|
|
|
|
571
|
|
|
|
|
1256
|
|
|
180
|
571
|
|
|
|
|
1645
|
$req->_build_params(); |
|
181
|
571
|
|
|
|
|
1287
|
$req->{_query_params} = $req->{params}; |
|
182
|
571
|
|
|
|
|
1912
|
my $store_raw_body = setting('raw_request_body_in_ram'); |
|
183
|
571
|
50
|
|
|
|
1418
|
$store_raw_body = defined $store_raw_body ? $store_raw_body : 1; |
|
184
|
571
|
50
|
|
|
|
1277
|
if ($store_raw_body) { |
|
185
|
571
|
|
|
|
|
1006
|
$req->{body} = $body; |
|
186
|
|
|
|
|
|
|
} |
|
187
|
571
|
|
66
|
|
|
1729
|
$req->{headers} = $headers || HTTP::Headers->new; |
|
188
|
|
|
|
|
|
|
|
|
189
|
571
|
|
|
|
|
2685
|
return $req; |
|
190
|
|
|
|
|
|
|
} |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
#Create a new request which is a clone of the current one, apart |
|
193
|
|
|
|
|
|
|
#from the path location, which points instead to the new location |
|
194
|
|
|
|
|
|
|
sub forward { |
|
195
|
16
|
|
|
16
|
1
|
38
|
my ($class, $request, $to_data) = @_; |
|
196
|
|
|
|
|
|
|
|
|
197
|
16
|
|
|
|
|
39
|
my $env = $request->env; |
|
198
|
16
|
|
|
|
|
45
|
$env->{PATH_INFO} = $to_data->{to_url}; |
|
199
|
|
|
|
|
|
|
|
|
200
|
16
|
|
|
|
|
40
|
my $new_request = $class->new(env => $env, is_forward => 1); |
|
201
|
|
|
|
|
|
|
my $new_params = _merge_params(scalar($request->params), |
|
202
|
16
|
|
100
|
|
|
41
|
$to_data->{params} || {}); |
|
203
|
|
|
|
|
|
|
|
|
204
|
16
|
100
|
|
|
|
47
|
if (exists($to_data->{options}{method})) { |
|
205
|
2
|
50
|
|
|
|
13
|
die unless _valid_method($to_data->{options}{method}); |
|
206
|
2
|
|
|
|
|
6
|
$new_request->{method} = uc $to_data->{options}{method}; |
|
207
|
|
|
|
|
|
|
} |
|
208
|
|
|
|
|
|
|
|
|
209
|
16
|
|
|
|
|
33
|
$new_request->{params} = $new_params; |
|
210
|
16
|
|
|
|
|
31
|
$new_request->{_body_params} = $request->{_body_params}; |
|
211
|
16
|
|
|
|
|
28
|
$new_request->{_query_params} = $request->{_query_params}; |
|
212
|
16
|
|
|
|
|
26
|
$new_request->{_route_params} = $request->{_route_params}; |
|
213
|
16
|
|
|
|
|
26
|
$new_request->{_params_are_decoded} = 1; |
|
214
|
16
|
|
|
|
|
37
|
$new_request->{headers} = $request->headers; |
|
215
|
|
|
|
|
|
|
|
|
216
|
16
|
100
|
66
|
|
|
78
|
if( my $session = Dancer::Session->engine |
|
217
|
|
|
|
|
|
|
&& Dancer::Session->get_current_session ) { |
|
218
|
15
|
|
|
|
|
40
|
my $name = $session->session_name; |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# make sure that COOKIE is populated |
|
221
|
15
|
|
33
|
|
|
79
|
$new_request->{env}{COOKIE} ||= $new_request->{env}{HTTP_COOKIE}; |
|
222
|
|
|
|
|
|
|
|
|
223
|
182
|
|
|
182
|
|
1740
|
no warnings; # COOKIE can be undef |
|
|
182
|
|
|
|
|
771
|
|
|
|
182
|
|
|
|
|
519855
|
|
|
224
|
15
|
50
|
|
|
|
120
|
unless ( $new_request->{env}{COOKIE} =~ /$name\s*=/ ) { |
|
225
|
|
|
|
|
|
|
$new_request->{env}{COOKIE} = join ';', |
|
226
|
30
|
|
|
|
|
91
|
grep { $_ } |
|
227
|
|
|
|
|
|
|
$new_request->{env}{COOKIE}, |
|
228
|
15
|
|
|
|
|
45
|
join '=', $name, Dancer::Session->get_current_session->id; |
|
229
|
|
|
|
|
|
|
} |
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
|
|
232
|
16
|
|
|
|
|
67
|
$new_request->{uploads} = $request->uploads; |
|
233
|
|
|
|
|
|
|
|
|
234
|
16
|
|
|
|
|
56
|
return $new_request; |
|
235
|
|
|
|
|
|
|
} |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub _valid_method { |
|
238
|
2
|
|
|
2
|
|
5
|
my $method = shift; |
|
239
|
2
|
|
|
|
|
16
|
return $method =~ /^(?:head|post|get|put|delete)$/i; |
|
240
|
|
|
|
|
|
|
} |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
sub _merge_params { |
|
243
|
16
|
|
|
16
|
|
35
|
my ($params, $to_add) = @_; |
|
244
|
|
|
|
|
|
|
|
|
245
|
16
|
50
|
|
|
|
39
|
die unless ref $to_add eq "HASH"; |
|
246
|
16
|
|
|
|
|
52
|
for my $key (keys %$to_add) { |
|
247
|
4
|
|
|
|
|
11
|
$params->{$key} = $to_add->{$key}; |
|
248
|
|
|
|
|
|
|
} |
|
249
|
16
|
|
|
|
|
30
|
return $params; |
|
250
|
|
|
|
|
|
|
} |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
sub base { |
|
253
|
29
|
|
|
29
|
1
|
1545
|
my $self = shift; |
|
254
|
29
|
|
|
|
|
79
|
my $uri = $self->_common_uri; |
|
255
|
|
|
|
|
|
|
|
|
256
|
29
|
|
|
|
|
103
|
return $uri->canonical; |
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
sub _common_uri { |
|
260
|
32
|
|
|
32
|
|
53
|
my $self = shift; |
|
261
|
|
|
|
|
|
|
|
|
262
|
32
|
|
100
|
|
|
107
|
my $path = $self->env->{SCRIPT_NAME} || ''; |
|
263
|
32
|
|
|
|
|
104
|
my $port = $self->env->{SERVER_PORT}; |
|
264
|
32
|
|
|
|
|
105
|
my $server = $self->env->{SERVER_NAME}; |
|
265
|
32
|
|
|
|
|
96
|
my $host = $self->host; |
|
266
|
32
|
|
|
|
|
94
|
my $scheme = $self->scheme; |
|
267
|
|
|
|
|
|
|
|
|
268
|
32
|
|
|
|
|
151
|
my $uri = URI->new; |
|
269
|
32
|
|
|
|
|
41735
|
$uri->scheme($scheme); |
|
270
|
32
|
|
66
|
|
|
35309
|
$uri->authority($host || "$server:$port"); |
|
271
|
32
|
100
|
|
|
|
1612
|
if (setting('behind_proxy')) { |
|
272
|
5
|
|
100
|
|
|
16
|
my $request_base = $self->env->{REQUEST_BASE} || $self->env->{HTTP_REQUEST_BASE} || ''; |
|
273
|
5
|
|
100
|
|
|
40
|
$uri->path($request_base . $path || '/'); |
|
274
|
|
|
|
|
|
|
} |
|
275
|
|
|
|
|
|
|
else { |
|
276
|
27
|
|
100
|
|
|
331
|
$uri->path($path || '/'); |
|
277
|
|
|
|
|
|
|
} |
|
278
|
|
|
|
|
|
|
|
|
279
|
32
|
|
|
|
|
1245
|
return $uri; |
|
280
|
|
|
|
|
|
|
} |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub uri_base { |
|
283
|
3
|
|
|
3
|
1
|
35
|
my $self = shift; |
|
284
|
3
|
|
|
|
|
11
|
my $uri = $self->_common_uri; |
|
285
|
3
|
|
|
|
|
13
|
my $canon = $uri->canonical; |
|
286
|
|
|
|
|
|
|
|
|
287
|
3
|
100
|
|
|
|
448
|
if ( $uri->path eq '/' ) { |
|
288
|
2
|
|
|
|
|
40
|
$canon =~ s{/$}{}; |
|
289
|
|
|
|
|
|
|
} |
|
290
|
|
|
|
|
|
|
|
|
291
|
3
|
|
|
|
|
54
|
return $canon; |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub uri_for { |
|
295
|
26
|
|
|
26
|
1
|
6451
|
my ($self, $part, $params, $dont_escape) = @_; |
|
296
|
26
|
|
|
|
|
68
|
my $uri = $self->base; |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# Make sure there's exactly one slash between the base and the new part |
|
299
|
26
|
|
|
|
|
2773
|
my $base = $uri->path; |
|
300
|
26
|
|
|
|
|
299
|
$base =~ s|/$||; |
|
301
|
26
|
|
|
|
|
84
|
$part =~ s|^/||; |
|
302
|
26
|
|
|
|
|
106
|
$uri->path("$base/$part"); |
|
303
|
|
|
|
|
|
|
|
|
304
|
26
|
100
|
|
|
|
944
|
$uri->query_form($params) if $params; |
|
305
|
|
|
|
|
|
|
|
|
306
|
26
|
100
|
|
|
|
1137
|
return $dont_escape ? uri_unescape($uri->canonical) : $uri->canonical; |
|
307
|
|
|
|
|
|
|
} |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub params { |
|
310
|
436
|
|
|
436
|
1
|
1636
|
my ($self, $source) = @_; |
|
311
|
|
|
|
|
|
|
|
|
312
|
436
|
|
|
|
|
1406
|
my @caller = caller; |
|
313
|
|
|
|
|
|
|
|
|
314
|
436
|
100
|
|
|
|
1371
|
if (not $self->{_params_are_decoded}) { |
|
315
|
289
|
|
|
|
|
924
|
$self->{params} = _decode($self->{params}); |
|
316
|
289
|
|
|
|
|
706
|
$self->{_body_params} = _decode($self->{_body_params}); |
|
317
|
289
|
|
|
|
|
693
|
$self->{_query_params} = _decode($self->{_query_params}); |
|
318
|
289
|
|
|
|
|
833
|
$self->{_route_params} = _decode($self->{_route_params}); |
|
319
|
289
|
|
|
|
|
1414
|
$self->{_params_are_decoded} = 1; |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
|
|
322
|
436
|
100
|
100
|
|
|
1256
|
return %{$self->{params}} if wantarray && @_ == 1; |
|
|
15
|
|
|
|
|
110
|
|
|
323
|
421
|
100
|
|
|
|
2172
|
return $self->{params} if @_ == 1; |
|
324
|
|
|
|
|
|
|
|
|
325
|
19
|
100
|
|
|
|
99
|
if ($source eq 'query') { |
|
|
|
50
|
|
|
|
|
|
|
326
|
4
|
100
|
|
|
|
25
|
return %{$self->{_query_params}} if wantarray; |
|
|
2
|
|
|
|
|
16
|
|
|
327
|
2
|
|
|
|
|
11
|
return $self->{_query_params}; |
|
328
|
|
|
|
|
|
|
} |
|
329
|
|
|
|
|
|
|
elsif ($source eq 'body') { |
|
330
|
15
|
50
|
|
|
|
87
|
return %{$self->{_body_params}} if wantarray; |
|
|
0
|
|
|
|
|
0
|
|
|
331
|
15
|
|
|
|
|
69
|
return $self->{_body_params}; |
|
332
|
|
|
|
|
|
|
} |
|
333
|
0
|
0
|
|
|
|
0
|
if ($source eq 'route') { |
|
334
|
0
|
0
|
|
|
|
0
|
return %{$self->{_route_params}} if wantarray; |
|
|
0
|
|
|
|
|
0
|
|
|
335
|
0
|
|
|
|
|
0
|
return $self->{_route_params}; |
|
336
|
|
|
|
|
|
|
} |
|
337
|
|
|
|
|
|
|
else { |
|
338
|
0
|
|
|
|
|
0
|
raise core_request => "Unknown source params \"$source\"."; |
|
339
|
|
|
|
|
|
|
} |
|
340
|
|
|
|
|
|
|
} |
|
341
|
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub _decode { |
|
343
|
2538
|
|
|
2538
|
|
7907
|
my ($h) = @_; |
|
344
|
2538
|
100
|
|
|
|
4848
|
return if not defined $h; |
|
345
|
|
|
|
|
|
|
|
|
346
|
2526
|
100
|
100
|
|
|
6279
|
if (!ref($h) && !utf8::is_utf8($h)) { |
|
347
|
622
|
|
|
|
|
2597
|
return decode('UTF-8', $h); |
|
348
|
|
|
|
|
|
|
} |
|
349
|
|
|
|
|
|
|
|
|
350
|
1904
|
100
|
|
|
|
4070
|
if (ref($h) eq 'HASH') { |
|
351
|
1793
|
|
|
|
|
5398
|
while (my ($k, $v) = each(%$h)) { |
|
352
|
631
|
|
|
|
|
8027
|
$h->{$k} = _decode($v); |
|
353
|
|
|
|
|
|
|
} |
|
354
|
1793
|
|
|
|
|
22704
|
return $h; |
|
355
|
|
|
|
|
|
|
} |
|
356
|
|
|
|
|
|
|
|
|
357
|
111
|
100
|
|
|
|
249
|
if (ref($h) eq 'ARRAY') { |
|
358
|
83
|
|
|
|
|
162
|
return [ map { _decode($_) } @$h ]; |
|
|
140
|
|
|
|
|
2498
|
|
|
359
|
|
|
|
|
|
|
} |
|
360
|
|
|
|
|
|
|
|
|
361
|
28
|
|
|
|
|
94
|
return $h; |
|
362
|
|
|
|
|
|
|
} |
|
363
|
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
sub is_ajax { |
|
365
|
614
|
|
|
614
|
1
|
997
|
my $self = shift; |
|
366
|
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
# when using Plack::Builder headers are not set |
|
368
|
|
|
|
|
|
|
# so we're checking if it's actually there with PSGI plain headers |
|
369
|
614
|
50
|
|
|
|
1488
|
if ( defined $self->{x_requested_with} ) { |
|
370
|
0
|
0
|
|
|
|
0
|
if ( $self->{x_requested_with} eq "XMLHttpRequest" ) { |
|
371
|
0
|
|
|
|
|
0
|
return 1; |
|
372
|
|
|
|
|
|
|
} |
|
373
|
|
|
|
|
|
|
} |
|
374
|
|
|
|
|
|
|
|
|
375
|
614
|
100
|
|
|
|
1481
|
return 0 unless defined $self->headers; |
|
376
|
4
|
100
|
|
|
|
17
|
return 0 unless defined $self->header('X-Requested-With'); |
|
377
|
1
|
50
|
|
|
|
40
|
return 0 if $self->header('X-Requested-With') ne 'XMLHttpRequest'; |
|
378
|
1
|
|
|
|
|
46
|
return 1; |
|
379
|
|
|
|
|
|
|
} |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
# context-aware accessor for uploads |
|
382
|
|
|
|
|
|
|
sub upload { |
|
383
|
8
|
|
|
8
|
1
|
755
|
my ($self, $name) = @_; |
|
384
|
8
|
|
|
|
|
17
|
my $res = $self->{uploads}{$name}; |
|
385
|
|
|
|
|
|
|
|
|
386
|
8
|
100
|
|
|
|
34
|
return $res unless wantarray; |
|
387
|
3
|
100
|
|
|
|
9
|
return () unless defined $res; |
|
388
|
2
|
100
|
|
|
|
11
|
return (ref($res) eq 'ARRAY') ? @$res : $res; |
|
389
|
|
|
|
|
|
|
} |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
# Some Dancer's core components sometimes need to alter |
|
392
|
|
|
|
|
|
|
# the parsed request params, these protected accessors are provided |
|
393
|
|
|
|
|
|
|
# for this purpose |
|
394
|
|
|
|
|
|
|
sub _set_route_params { |
|
395
|
649
|
|
|
649
|
|
1254
|
my ($self, $params) = @_; |
|
396
|
649
|
|
|
|
|
1432
|
$self->{_route_params} = $params; |
|
397
|
649
|
|
|
|
|
1421
|
$self->_build_params(); |
|
398
|
|
|
|
|
|
|
} |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
sub _set_body_params { |
|
401
|
8
|
|
|
8
|
|
22
|
my ($self, $params) = @_; |
|
402
|
8
|
|
|
|
|
21
|
$self->{_body_params} = $params; |
|
403
|
8
|
|
|
|
|
22
|
$self->_build_params(); |
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
sub _set_query_params { |
|
407
|
0
|
|
|
0
|
|
0
|
my ($self, $params) = @_; |
|
408
|
0
|
|
|
|
|
0
|
$self->{_query_params} = $params; |
|
409
|
0
|
|
|
|
|
0
|
$self->_build_params(); |
|
410
|
|
|
|
|
|
|
} |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
sub _build_request_env { |
|
413
|
611
|
|
|
611
|
|
1168
|
my ($self) = @_; |
|
414
|
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
# Don't refactor that, it's called whenever a request object is needed, that |
|
416
|
|
|
|
|
|
|
# means at least once per request. If refactored in a loop, this will cost 4 |
|
417
|
|
|
|
|
|
|
# times more than the following static map. |
|
418
|
611
|
|
|
|
|
1544
|
my $env = $self->env; |
|
419
|
611
|
|
|
|
|
1357
|
$self->{user_agent} = $env->{HTTP_USER_AGENT}; |
|
420
|
611
|
|
|
|
|
2152
|
$self->{host} = $env->{HTTP_HOST}; |
|
421
|
611
|
|
|
|
|
1207
|
$self->{accept_language} = $env->{HTTP_ACCEPT_LANGUAGE}; |
|
422
|
611
|
|
|
|
|
1777
|
$self->{accept_charset} = $env->{HTTP_ACCEPT_CHARSET}; |
|
423
|
611
|
|
|
|
|
1133
|
$self->{accept_encoding} = $env->{HTTP_ACCEPT_ENCODING}; |
|
424
|
611
|
|
|
|
|
1250
|
$self->{keep_alive} = $env->{HTTP_KEEP_ALIVE}; |
|
425
|
611
|
|
|
|
|
1308
|
$self->{connection} = $env->{HTTP_CONNECTION}; |
|
426
|
611
|
|
|
|
|
1264
|
$self->{accept} = $env->{HTTP_ACCEPT}; |
|
427
|
611
|
|
|
|
|
1244
|
$self->{accept_type} = $env->{HTTP_ACCEPT_TYPE}; |
|
428
|
611
|
|
|
|
|
1158
|
$self->{referer} = $env->{HTTP_REFERER}; |
|
429
|
611
|
|
|
|
|
1365
|
$self->{x_requested_with} = $env->{HTTP_X_REQUESTED_WITH}; |
|
430
|
|
|
|
|
|
|
} |
|
431
|
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
sub _build_headers { |
|
433
|
611
|
|
|
611
|
|
1205
|
my ($self) = @_; |
|
434
|
611
|
|
|
|
|
2548
|
$self->{headers} = Dancer::SharedData->headers; |
|
435
|
|
|
|
|
|
|
} |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
sub _build_params { |
|
438
|
2450
|
|
|
2450
|
|
4760
|
my ($self) = @_; |
|
439
|
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
# params may have been populated by before filters |
|
441
|
|
|
|
|
|
|
# _before_ we get there, so we have to save it first |
|
442
|
2450
|
|
|
|
|
4205
|
my $previous = $self->{params}; |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
# now parse environment params... |
|
445
|
2450
|
|
|
|
|
6385
|
$self->_parse_get_params(); |
|
446
|
2450
|
100
|
|
|
|
5847
|
if ($self->is_forward) { |
|
447
|
47
|
|
100
|
|
|
120
|
$self->{_body_params} ||= {}; |
|
448
|
|
|
|
|
|
|
} else { |
|
449
|
2403
|
|
|
|
|
5313
|
$self->_parse_post_params(); |
|
450
|
|
|
|
|
|
|
} |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
# and merge everything |
|
453
|
|
|
|
|
|
|
$self->{params} = { |
|
454
|
2450
|
|
|
|
|
4433
|
%$previous, %{$self->{_query_params}}, |
|
455
|
2450
|
|
|
|
|
8391
|
%{$self->{_route_params}}, %{$self->{_body_params}}, |
|
|
2450
|
|
|
|
|
3936
|
|
|
|
2450
|
|
|
|
|
6798
|
|
|
456
|
|
|
|
|
|
|
}; |
|
457
|
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
} |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
# Written from PSGI specs: |
|
461
|
|
|
|
|
|
|
# http://search.cpan.org/dist/PSGI/PSGI.pod |
|
462
|
|
|
|
|
|
|
sub _build_path { |
|
463
|
611
|
|
|
611
|
|
1230
|
my ($self) = @_; |
|
464
|
611
|
|
|
|
|
1217
|
my $path = ""; |
|
465
|
|
|
|
|
|
|
|
|
466
|
611
|
100
|
|
|
|
1740
|
$path .= $self->script_name if defined $self->script_name; |
|
467
|
611
|
100
|
|
|
|
1591
|
$path .= $self->env->{PATH_INFO} if defined $self->env->{PATH_INFO}; |
|
468
|
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
# fallback to REQUEST_URI if nothing found |
|
470
|
|
|
|
|
|
|
# we have to decode it, according to PSGI specs. |
|
471
|
611
|
100
|
|
|
|
1744
|
if (defined $self->request_uri) { |
|
472
|
526
|
|
33
|
|
|
1819
|
$path ||= $self->_url_decode($self->request_uri); |
|
473
|
|
|
|
|
|
|
} |
|
474
|
|
|
|
|
|
|
|
|
475
|
611
|
50
|
|
|
|
1466
|
raise core_request => "Cannot resolve path" if not $path; |
|
476
|
611
|
|
|
|
|
1310
|
$self->{path} = $path; |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
sub _build_path_info { |
|
480
|
611
|
|
|
611
|
|
1516
|
my ($self) = @_; |
|
481
|
611
|
|
|
|
|
1757
|
my $info = $self->env->{PATH_INFO}; |
|
482
|
611
|
100
|
|
|
|
1873
|
if (defined $info) { |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
# Empty path info will be interpreted as "root". |
|
485
|
604
|
|
50
|
|
|
1690
|
$info ||= '/'; |
|
486
|
|
|
|
|
|
|
} |
|
487
|
|
|
|
|
|
|
else { |
|
488
|
7
|
|
|
|
|
22
|
$info = $self->path; |
|
489
|
|
|
|
|
|
|
} |
|
490
|
611
|
|
|
|
|
1504
|
$self->{path_info} = $info; |
|
491
|
|
|
|
|
|
|
} |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
sub _build_method { |
|
494
|
611
|
|
|
611
|
|
1277
|
my ($self) = @_; |
|
495
|
|
|
|
|
|
|
$self->{method} = $self->env->{REQUEST_METHOD} |
|
496
|
611
|
|
33
|
|
|
1932
|
|| $self->{request}->request_method(); |
|
497
|
|
|
|
|
|
|
} |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub _url_decode { |
|
500
|
80
|
|
|
80
|
|
132
|
my ($self, $encoded) = @_; |
|
501
|
80
|
|
|
|
|
115
|
my $clean = $encoded; |
|
502
|
80
|
|
|
|
|
116
|
$clean =~ tr/\+/ /; |
|
503
|
80
|
|
|
|
|
146
|
$clean =~ s/%([a-fA-F0-9]{2})/pack "H2", $1/eg; |
|
|
4
|
|
|
|
|
21
|
|
|
504
|
80
|
|
|
|
|
153
|
return $clean; |
|
505
|
|
|
|
|
|
|
} |
|
506
|
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
sub _parse_post_params { |
|
508
|
2403
|
|
|
2403
|
|
4505
|
my ($self) = @_; |
|
509
|
2403
|
100
|
|
|
|
5912
|
return $self->{_body_params} if defined $self->{_body_params}; |
|
510
|
|
|
|
|
|
|
|
|
511
|
595
|
|
|
|
|
1949
|
$self->_read_to_end(); |
|
512
|
595
|
|
|
|
|
2496
|
$self->{_body_params} = $self->{_http_body}->param; |
|
513
|
|
|
|
|
|
|
} |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
sub _parse_get_params { |
|
516
|
2450
|
|
|
2450
|
|
4197
|
my ($self) = @_; |
|
517
|
2450
|
100
|
|
|
|
7252
|
return $self->{_query_params} if defined $self->{_query_params}; |
|
518
|
611
|
|
|
|
|
1708
|
$self->{_query_params} = {}; |
|
519
|
|
|
|
|
|
|
|
|
520
|
611
|
|
100
|
|
|
2180
|
my $source = $self->env->{QUERY_STRING} || ''; |
|
521
|
611
|
|
|
|
|
2962
|
foreach my $token (split /[&;]/, $source) { |
|
522
|
40
|
|
|
|
|
115
|
my ($key, $val) = split(/=/, $token, 2); |
|
523
|
40
|
50
|
|
|
|
95
|
next unless defined $key; |
|
524
|
40
|
50
|
|
|
|
114
|
$val = (defined $val) ? $val : ''; |
|
525
|
40
|
|
|
|
|
91
|
$key = $self->_url_decode($key); |
|
526
|
40
|
|
|
|
|
75
|
$val = $self->_url_decode($val); |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
# looking for multi-value params |
|
529
|
40
|
100
|
|
|
|
103
|
if (exists $self->{_query_params}{$key}) { |
|
530
|
4
|
|
|
|
|
9
|
my $prev_val = $self->{_query_params}{$key}; |
|
531
|
4
|
50
|
33
|
|
|
16
|
if (ref($prev_val) && ref($prev_val) eq 'ARRAY') { |
|
532
|
0
|
|
|
|
|
0
|
push @{$self->{_query_params}{$key}}, $val; |
|
|
0
|
|
|
|
|
0
|
|
|
533
|
|
|
|
|
|
|
} |
|
534
|
|
|
|
|
|
|
else { |
|
535
|
4
|
|
|
|
|
16
|
$self->{_query_params}{$key} = [$prev_val, $val]; |
|
536
|
|
|
|
|
|
|
} |
|
537
|
|
|
|
|
|
|
} |
|
538
|
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
# simple value param (first time we see it) |
|
540
|
|
|
|
|
|
|
else { |
|
541
|
36
|
|
|
|
|
99
|
$self->{_query_params}{$key} = $val; |
|
542
|
|
|
|
|
|
|
} |
|
543
|
|
|
|
|
|
|
} |
|
544
|
611
|
|
|
|
|
1478
|
return $self->{_query_params}; |
|
545
|
|
|
|
|
|
|
} |
|
546
|
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
sub _read_to_end { |
|
548
|
595
|
|
|
595
|
|
1324
|
my $self = shift; |
|
549
|
|
|
|
|
|
|
|
|
550
|
595
|
100
|
|
|
|
1604
|
return unless $self->_has_something_to_read; |
|
551
|
|
|
|
|
|
|
|
|
552
|
32
|
100
|
|
|
|
108
|
if ( $self->content_length > 0 ) { |
|
553
|
20
|
|
|
|
|
43
|
my $body = ''; |
|
554
|
|
|
|
|
|
|
|
|
555
|
20
|
|
|
|
|
70
|
my $store_raw_body = setting('raw_request_body_in_ram'); |
|
556
|
20
|
50
|
|
|
|
93
|
$store_raw_body = defined $store_raw_body ? $store_raw_body : 1; |
|
557
|
|
|
|
|
|
|
|
|
558
|
20
|
|
|
|
|
72
|
while ( my $buffer = $self->_read ) { |
|
559
|
20
|
|
|
|
|
107
|
$self->{_http_body}->add($buffer); |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
# Only keep a copy of the raw request body in RAM if the user has |
|
562
|
|
|
|
|
|
|
# asked us to |
|
563
|
|
|
|
|
|
|
|
|
564
|
20
|
50
|
|
|
|
17075
|
if ($store_raw_body) { |
|
565
|
20
|
|
|
|
|
83
|
$self->{body} .= $buffer; |
|
566
|
|
|
|
|
|
|
} |
|
567
|
|
|
|
|
|
|
} |
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
} |
|
570
|
|
|
|
|
|
|
|
|
571
|
32
|
|
|
|
|
71
|
return $self->{_http_body}; |
|
572
|
|
|
|
|
|
|
} |
|
573
|
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
sub _has_something_to_read { |
|
575
|
595
|
|
|
595
|
|
1865
|
defined $_[0]->input_handle; |
|
576
|
|
|
|
|
|
|
} |
|
577
|
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
# taken from Miyagawa's Plack::Request::BodyParser |
|
579
|
|
|
|
|
|
|
sub _read { |
|
580
|
40
|
|
|
40
|
|
86
|
my ($self,) = @_; |
|
581
|
40
|
|
|
|
|
101
|
my $remaining = $self->content_length - $self->{_read_position}; |
|
582
|
40
|
|
|
|
|
73
|
my $maxlength = $self->{_chunk_size}; |
|
583
|
|
|
|
|
|
|
|
|
584
|
40
|
100
|
|
|
|
125
|
return if ($remaining <= 0); |
|
585
|
|
|
|
|
|
|
|
|
586
|
20
|
50
|
|
|
|
50
|
my $readlen = ($remaining > $maxlength) ? $maxlength : $remaining; |
|
587
|
20
|
|
|
|
|
35
|
my $buffer; |
|
588
|
|
|
|
|
|
|
my $rc; |
|
589
|
|
|
|
|
|
|
|
|
590
|
20
|
|
|
|
|
47
|
$rc = $self->input_handle->read($buffer, $readlen); |
|
591
|
|
|
|
|
|
|
|
|
592
|
20
|
50
|
|
|
|
204
|
if (defined $rc) { |
|
593
|
20
|
|
|
|
|
40
|
$self->{_read_position} += $rc; |
|
594
|
20
|
|
|
|
|
74
|
return $buffer; |
|
595
|
|
|
|
|
|
|
} |
|
596
|
|
|
|
|
|
|
else { |
|
597
|
0
|
|
|
|
|
0
|
raise core_request => "Unknown error reading input: $!"; |
|
598
|
|
|
|
|
|
|
} |
|
599
|
|
|
|
|
|
|
} |
|
600
|
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
# Taken gently from Plack::Request, thanks to Plack authors. |
|
602
|
|
|
|
|
|
|
sub _build_uploads { |
|
603
|
611
|
|
|
611
|
|
1372
|
my ($self) = @_; |
|
604
|
|
|
|
|
|
|
|
|
605
|
611
|
|
|
|
|
1960
|
my $uploads = _decode($self->{_http_body}->upload); |
|
606
|
611
|
|
|
|
|
1234
|
my %uploads; |
|
607
|
|
|
|
|
|
|
|
|
608
|
611
|
|
|
|
|
900
|
for my $name (keys %{$uploads}) { |
|
|
611
|
|
|
|
|
1579
|
|
|
609
|
9
|
|
|
|
|
17
|
my $files = $uploads->{$name}; |
|
610
|
9
|
100
|
|
|
|
40
|
$files = ref $files eq 'ARRAY' ? $files : [$files]; |
|
611
|
|
|
|
|
|
|
|
|
612
|
9
|
|
|
|
|
19
|
my @uploads; |
|
613
|
9
|
|
|
|
|
13
|
for my $upload (@{$files}) { |
|
|
9
|
|
|
|
|
21
|
|
|
614
|
|
|
|
|
|
|
push( |
|
615
|
|
|
|
|
|
|
@uploads, |
|
616
|
|
|
|
|
|
|
Dancer::Request::Upload->new( |
|
617
|
|
|
|
|
|
|
headers => $upload->{headers}, |
|
618
|
|
|
|
|
|
|
tempname => $upload->{tempname}, |
|
619
|
|
|
|
|
|
|
size => $upload->{size}, |
|
620
|
|
|
|
|
|
|
filename => $upload->{filename}, |
|
621
|
|
|
|
|
|
|
) |
|
622
|
11
|
|
|
|
|
64
|
); |
|
623
|
|
|
|
|
|
|
} |
|
624
|
9
|
100
|
|
|
|
28
|
$uploads{$name} = @uploads > 1 ? \@uploads : $uploads[0]; |
|
625
|
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
# support access to the filename as a normal param |
|
627
|
9
|
|
|
|
|
20
|
my @filenames = map { $_->{filename} } @uploads; |
|
|
11
|
|
|
|
|
55
|
|
|
628
|
9
|
100
|
|
|
|
37
|
$self->{_body_params}{$name} = |
|
629
|
|
|
|
|
|
|
@filenames > 1 ? \@filenames : $filenames[0]; |
|
630
|
|
|
|
|
|
|
} |
|
631
|
|
|
|
|
|
|
|
|
632
|
611
|
|
|
|
|
1701
|
$self->{uploads} = \%uploads; |
|
633
|
611
|
|
|
|
|
1266
|
$self->_build_params(); |
|
634
|
|
|
|
|
|
|
} |
|
635
|
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
1; |
|
637
|
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
__END__ |