Filename | /usr/local/share/perl/5.18.2/Plack/Request.pm |
Statements | Executed 8909665 statements in 37.5s |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
200002 | 2 | 1 | 17.6s | 37.1s | headers | Plack::Request::
100001 | 1 | 1 | 5.31s | 12.3s | _parse_query | Plack::Request::
599517 | 4 | 1 | 3.54s | 4.53s | method | Plack::Request::
3002136 | 2 | 1 | 1.71s | 1.71s | CORE:match (opcode) | Plack::Request::
1299524 | 7 | 1 | 1.58s | 1.58s | env | Plack::Request::
200002 | 2 | 1 | 1.31s | 1.52s | content_length | Plack::Request::
100001 | 1 | 1 | 1.21s | 13.5s | query_parameters | Plack::Request::
904221 | 3 | 1 | 1.18s | 1.18s | CORE:subst (opcode) | Plack::Request::
100001 | 1 | 1 | 788ms | 788ms | new | Plack::Request::
100001 | 1 | 1 | 671ms | 735ms | request_uri | Plack::Request::
100001 | 1 | 1 | 652ms | 719ms | path_info | Plack::Request::
1 | 1 | 1 | 5.69ms | 5.86ms | BEGIN@7 | Plack::Request::
1 | 1 | 1 | 3.90ms | 21.3ms | BEGIN@10 | Plack::Request::
1 | 1 | 1 | 2.44ms | 2.72ms | BEGIN@9 | Plack::Request::
1 | 1 | 1 | 304µs | 341µs | BEGIN@12 | Plack::Request::
1 | 1 | 1 | 278µs | 2.30ms | BEGIN@13 | Plack::Request::
1 | 1 | 1 | 18µs | 46µs | BEGIN@2 | Plack::Request::
1 | 1 | 1 | 17µs | 17µs | BEGIN@4 | Plack::Request::
1 | 1 | 1 | 17µs | 27µs | BEGIN@3 | Plack::Request::
1 | 1 | 1 | 8µs | 8µs | BEGIN@8 | Plack::Request::
1 | 1 | 1 | 7µs | 7µs | BEGIN@14 | Plack::Request::
1 | 1 | 1 | 2µs | 2µs | BEGIN@15 | Plack::Request::
0 | 0 | 0 | 0s | 0s | _make_upload | Plack::Request::
0 | 0 | 0 | 0s | 0s | _parse_request_body | Plack::Request::
0 | 0 | 0 | 0s | 0s | _uri_base | Plack::Request::
0 | 0 | 0 | 0s | 0s | address | Plack::Request::
0 | 0 | 0 | 0s | 0s | base | Plack::Request::
0 | 0 | 0 | 0s | 0s | body | Plack::Request::
0 | 0 | 0 | 0s | 0s | body_parameters | Plack::Request::
0 | 0 | 0 | 0s | 0s | content | Plack::Request::
0 | 0 | 0 | 0s | 0s | content_encoding | Plack::Request::
0 | 0 | 0 | 0s | 0s | content_type | Plack::Request::
0 | 0 | 0 | 0s | 0s | cookies | Plack::Request::
0 | 0 | 0 | 0s | 0s | header | Plack::Request::
0 | 0 | 0 | 0s | 0s | input | Plack::Request::
0 | 0 | 0 | 0s | 0s | logger | Plack::Request::
0 | 0 | 0 | 0s | 0s | new_response | Plack::Request::
0 | 0 | 0 | 0s | 0s | param | Plack::Request::
0 | 0 | 0 | 0s | 0s | parameters | Plack::Request::
0 | 0 | 0 | 0s | 0s | path | Plack::Request::
0 | 0 | 0 | 0s | 0s | port | Plack::Request::
0 | 0 | 0 | 0s | 0s | protocol | Plack::Request::
0 | 0 | 0 | 0s | 0s | query_string | Plack::Request::
0 | 0 | 0 | 0s | 0s | raw_body | Plack::Request::
0 | 0 | 0 | 0s | 0s | referer | Plack::Request::
0 | 0 | 0 | 0s | 0s | remote_host | Plack::Request::
0 | 0 | 0 | 0s | 0s | scheme | Plack::Request::
0 | 0 | 0 | 0s | 0s | script_name | Plack::Request::
0 | 0 | 0 | 0s | 0s | secure | Plack::Request::
0 | 0 | 0 | 0s | 0s | session | Plack::Request::
0 | 0 | 0 | 0s | 0s | session_options | Plack::Request::
0 | 0 | 0 | 0s | 0s | upload | Plack::Request::
0 | 0 | 0 | 0s | 0s | uploads | Plack::Request::
0 | 0 | 0 | 0s | 0s | uri | Plack::Request::
0 | 0 | 0 | 0s | 0s | user | Plack::Request::
0 | 0 | 0 | 0s | 0s | user_agent | Plack::Request::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Plack::Request; | ||||
2 | 2 | 42µs | 2 | 75µs | # spent 46µs (18+28) within Plack::Request::BEGIN@2 which was called:
# once (18µs+28µs) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 2 # spent 46µs making 1 call to Plack::Request::BEGIN@2
# spent 28µs making 1 call to strict::import |
3 | 2 | 38µs | 2 | 37µs | # spent 27µs (17+10) within Plack::Request::BEGIN@3 which was called:
# once (17µs+10µs) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 3 # spent 27µs making 1 call to Plack::Request::BEGIN@3
# spent 10µs making 1 call to warnings::import |
4 | 2 | 86µs | 1 | 17µs | # spent 17µs within Plack::Request::BEGIN@4 which was called:
# once (17µs+0s) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 4 # spent 17µs making 1 call to Plack::Request::BEGIN@4 |
5 | 1 | 500ns | our $VERSION = '1.0037'; | ||
6 | |||||
7 | 2 | 175µs | 1 | 5.86ms | # spent 5.86ms (5.69+170µs) within Plack::Request::BEGIN@7 which was called:
# once (5.69ms+170µs) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 7 # spent 5.86ms making 1 call to Plack::Request::BEGIN@7 |
8 | 2 | 33µs | 1 | 8µs | # spent 8µs within Plack::Request::BEGIN@8 which was called:
# once (8µs+0s) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 8 # spent 8µs making 1 call to Plack::Request::BEGIN@8 |
9 | 2 | 159µs | 1 | 2.72ms | # spent 2.72ms (2.44+282µs) within Plack::Request::BEGIN@9 which was called:
# once (2.44ms+282µs) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 9 # spent 2.72ms making 1 call to Plack::Request::BEGIN@9 |
10 | 2 | 137µs | 1 | 21.3ms | # spent 21.3ms (3.90+17.4) within Plack::Request::BEGIN@10 which was called:
# once (3.90ms+17.4ms) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 10 # spent 21.3ms making 1 call to Plack::Request::BEGIN@10 |
11 | |||||
12 | 2 | 76µs | 1 | 341µs | # spent 341µs (304+36) within Plack::Request::BEGIN@12 which was called:
# once (304µs+36µs) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 12 # spent 341µs making 1 call to Plack::Request::BEGIN@12 |
13 | 2 | 70µs | 1 | 2.30ms | # spent 2.30ms (278µs+2.02) within Plack::Request::BEGIN@13 which was called:
# once (278µs+2.02ms) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 13 # spent 2.30ms making 1 call to Plack::Request::BEGIN@13 |
14 | 2 | 20µs | 1 | 7µs | # spent 7µs within Plack::Request::BEGIN@14 which was called:
# once (7µs+0s) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 14 # spent 7µs making 1 call to Plack::Request::BEGIN@14 |
15 | 2 | 1.48ms | 1 | 2µs | # spent 2µs within Plack::Request::BEGIN@15 which was called:
# once (2µs+0s) by PONAPI::CLI::RunServer::BEGIN@4.20 at line 15 # spent 2µs making 1 call to Plack::Request::BEGIN@15 |
16 | |||||
17 | # spent 788ms within Plack::Request::new which was called 100001 times, avg 8µs/call:
# 100001 times (788ms+0s) by PONAPI::Server::call at line 64 of lib/PONAPI/Server.pm, avg 8µs/call | ||||
18 | 100001 | 84.2ms | my($class, $env) = @_; | ||
19 | 100001 | 152ms | Carp::croak(q{$env is required}) | ||
20 | unless defined $env && ref($env) eq 'HASH'; | ||||
21 | |||||
22 | 100001 | 846ms | bless { env => $env }, $class; | ||
23 | } | ||||
24 | |||||
25 | 1299524 | 5.11s | # spent 1.58s within Plack::Request::env which was called 1299524 times, avg 1µs/call:
# 599517 times (986ms+0s) by Plack::Request::method at line 30, avg 2µs/call
# 200002 times (213ms+0s) by Plack::Request::content_length at line 43, avg 1µs/call
# 100001 times (98.5ms+0s) by Plack::Request::headers at line 123, avg 985ns/call
# 100001 times (86.5ms+0s) by Plack::Request::query_parameters at line 80, avg 865ns/call
# 100001 times (67.5ms+0s) by Plack::Request::path_info at line 34, avg 675ns/call
# 100001 times (67.2ms+0s) by Plack::Request::_parse_query at line 87, avg 672ns/call
# 100001 times (64.9ms+0s) by Plack::Request::request_uri at line 33, avg 649ns/call | ||
26 | |||||
27 | sub address { $_[0]->env->{REMOTE_ADDR} } | ||||
28 | sub remote_host { $_[0]->env->{REMOTE_HOST} } | ||||
29 | sub protocol { $_[0]->env->{SERVER_PROTOCOL} } | ||||
30 | 599517 | 3.44s | 599517 | 986ms | # spent 4.53s (3.54+986ms) within Plack::Request::method which was called 599517 times, avg 8µs/call:
# 299514 times (1.30s+209ms) by PONAPI::Server::_is_get_like at line 99 of lib/PONAPI/Server.pm, avg 5µs/call
# 100001 times (869ms+332ms) by PONAPI::Server::_ponapi_check_headers at line 201 of lib/PONAPI/Server.pm, avg 12µs/call
# 100001 times (701ms+220ms) by PONAPI::Server::_ponapi_route_match at line 139 of lib/PONAPI/Server.pm, avg 9µs/call
# 100001 times (673ms+224ms) by PONAPI::Server::call at line 78 of lib/PONAPI/Server.pm, avg 9µs/call # spent 986ms making 599517 calls to Plack::Request::env, avg 2µs/call |
31 | sub port { $_[0]->env->{SERVER_PORT} } | ||||
32 | sub user { $_[0]->env->{REMOTE_USER} } | ||||
33 | 100001 | 531ms | 100001 | 64.9ms | # spent 735ms (671+64.9) within Plack::Request::request_uri which was called 100001 times, avg 7µs/call:
# 100001 times (671ms+64.9ms) by PONAPI::Server::_ponapi_params at line 120 of lib/PONAPI/Server.pm, avg 7µs/call # spent 64.9ms making 100001 calls to Plack::Request::env, avg 649ns/call |
34 | 100001 | 550ms | 100001 | 67.5ms | # spent 719ms (652+67.5) within Plack::Request::path_info which was called 100001 times, avg 7µs/call:
# 100001 times (652ms+67.5ms) by PONAPI::Server::_ponapi_route_match at line 143 of lib/PONAPI/Server.pm, avg 7µs/call # spent 67.5ms making 100001 calls to Plack::Request::env, avg 675ns/call |
35 | sub path { $_[0]->env->{PATH_INFO} || '/' } | ||||
36 | sub query_string{ $_[0]->env->{QUERY_STRING} } | ||||
37 | sub script_name { $_[0]->env->{SCRIPT_NAME} } | ||||
38 | sub scheme { $_[0]->env->{'psgi.url_scheme'} } | ||||
39 | sub secure { $_[0]->scheme eq 'https' } | ||||
40 | sub body { $_[0]->env->{'psgi.input'} } | ||||
41 | sub input { $_[0]->env->{'psgi.input'} } | ||||
42 | |||||
43 | 200002 | 1.27s | 200002 | 213ms | # spent 1.52s (1.31+213ms) within Plack::Request::content_length which was called 200002 times, avg 8µs/call:
# 100001 times (719ms+98.5ms) by PONAPI::Server::_ponapi_check_headers at line 208 of lib/PONAPI/Server.pm, avg 8µs/call
# 100001 times (586ms+115ms) by PONAPI::Server::_ponapi_data at line 291 of lib/PONAPI/Server.pm, avg 7µs/call # spent 213ms making 200002 calls to Plack::Request::env, avg 1µs/call |
44 | sub content_type { $_[0]->env->{CONTENT_TYPE} } | ||||
45 | |||||
46 | sub session { $_[0]->env->{'psgix.session'} } | ||||
47 | sub session_options { $_[0]->env->{'psgix.session.options'} } | ||||
48 | sub logger { $_[0]->env->{'psgix.logger'} } | ||||
49 | |||||
50 | sub cookies { | ||||
51 | my $self = shift; | ||||
52 | |||||
53 | return {} unless $self->env->{HTTP_COOKIE}; | ||||
54 | |||||
55 | # HTTP_COOKIE hasn't changed: reuse the parsed cookie | ||||
56 | if ( $self->env->{'plack.cookie.parsed'} | ||||
57 | && $self->env->{'plack.cookie.string'} eq $self->env->{HTTP_COOKIE}) { | ||||
58 | return $self->env->{'plack.cookie.parsed'}; | ||||
59 | } | ||||
60 | |||||
61 | $self->env->{'plack.cookie.string'} = $self->env->{HTTP_COOKIE}; | ||||
62 | |||||
63 | my %results; | ||||
64 | my @pairs = grep m/=/, split "[;,] ?", $self->env->{'plack.cookie.string'}; | ||||
65 | for my $pair ( @pairs ) { | ||||
66 | # trim leading trailing whitespace | ||||
67 | $pair =~ s/^\s+//; $pair =~ s/\s+$//; | ||||
68 | |||||
69 | my ($key, $value) = map URI::Escape::uri_unescape($_), split( "=", $pair, 2 ); | ||||
70 | |||||
71 | # Take the first one like CGI.pm or rack do | ||||
72 | $results{$key} = $value unless exists $results{$key}; | ||||
73 | } | ||||
74 | |||||
75 | $self->env->{'plack.cookie.parsed'} = \%results; | ||||
76 | } | ||||
77 | |||||
78 | # spent 13.5s (1.21+12.3) within Plack::Request::query_parameters which was called 100001 times, avg 135µs/call:
# 100001 times (1.21s+12.3s) by PONAPI::Server::_ponapi_query_params at line 240 of lib/PONAPI/Server.pm, avg 135µs/call | ||||
79 | 100001 | 50.0ms | my $self = shift; | ||
80 | 100001 | 876ms | 200002 | 12.3s | $self->env->{'plack.request.query'} ||= $self->_parse_query; # spent 12.3s making 100001 calls to Plack::Request::_parse_query, avg 123µs/call
# spent 86.5ms making 100001 calls to Plack::Request::env, avg 865ns/call |
81 | } | ||||
82 | |||||
83 | # spent 12.3s (5.31+6.94) within Plack::Request::_parse_query which was called 100001 times, avg 123µs/call:
# 100001 times (5.31s+6.94s) by Plack::Request::query_parameters at line 80, avg 123µs/call | ||||
84 | 100001 | 43.6ms | my $self = shift; | ||
85 | |||||
86 | 100001 | 32.6ms | my @query; | ||
87 | 100001 | 189ms | 100001 | 67.2ms | my $query_string = $self->env->{QUERY_STRING}; # spent 67.2ms making 100001 calls to Plack::Request::env, avg 672ns/call |
88 | 100001 | 112ms | if (defined $query_string) { | ||
89 | 100001 | 625ms | 100001 | 133ms | $query_string =~ s/\A[&;]+//; # spent 133ms making 100001 calls to Plack::Request::CORE:subst, avg 1µs/call |
90 | 204214 | 725ms | 204214 | 71.7ms | @query = # spent 71.7ms making 204214 calls to Plack::Request::CORE:subst, avg 351ns/call |
91 | 306321 | 982ms | 306321 | 1.40s | map { s/\+/ /g; URI::Escape::uri_unescape($_) } # spent 1.27s making 204214 calls to URI::Escape::uri_unescape, avg 6µs/call
# spent 123ms making 102107 calls to Plack::Request::CORE:match, avg 1µs/call |
92 | 100001 | 519ms | map { /=/ ? split(/=/, $_, 2) : ($_ => '')} | ||
93 | split(/[&;]+/, $query_string); | ||||
94 | } | ||||
95 | |||||
96 | 100001 | 1.09s | 100001 | 3.76s | Hash::MultiValue->new(@query); # spent 3.76s making 100001 calls to Hash::MultiValue::new, avg 38µs/call |
97 | } | ||||
98 | |||||
99 | sub content { | ||||
100 | my $self = shift; | ||||
101 | |||||
102 | unless ($self->env->{'psgix.input.buffered'}) { | ||||
103 | $self->_parse_request_body; | ||||
104 | } | ||||
105 | |||||
106 | my $fh = $self->input or return ''; | ||||
107 | my $cl = $self->env->{CONTENT_LENGTH} or return ''; | ||||
108 | |||||
109 | $fh->seek(0, 0); # just in case middleware/apps read it without seeking back | ||||
110 | $fh->read(my($content), $cl, 0); | ||||
111 | $fh->seek(0, 0); | ||||
112 | |||||
113 | return $content; | ||||
114 | } | ||||
115 | |||||
116 | sub raw_body { $_[0]->content } | ||||
117 | |||||
118 | # XXX you can mutate headers with ->headers but it's not written through to the env | ||||
119 | |||||
120 | # spent 37.1s (17.6+19.5) within Plack::Request::headers which was called 200002 times, avg 186µs/call:
# 100001 times (17.3s+19.5s) by PONAPI::Server::_ponapi_check_headers at line 218 of lib/PONAPI/Server.pm, avg 368µs/call
# 100001 times (280ms+0s) by PONAPI::Server::_ponapi_query_params at line 242 of lib/PONAPI/Server.pm, avg 3µs/call | ||||
121 | 200002 | 105ms | my $self = shift; | ||
122 | 200002 | 521ms | if (!defined $self->{headers}) { | ||
123 | 100001 | 189ms | 100001 | 98.5ms | my $env = $self->env; # spent 98.5ms making 100001 calls to Plack::Request::env, avg 985ns/call |
124 | 600006 | 3.52s | 600006 | 973ms | $self->{headers} = HTTP::Headers::Fast->new( # spent 973ms making 600006 calls to Plack::Request::CORE:subst, avg 2µs/call |
125 | map { | ||||
126 | 2900029 | 11.2s | 2900029 | 1.58s | (my $field = $_) =~ s/^HTTPS?_//; # spent 1.58s making 2900029 calls to Plack::Request::CORE:match, avg 546ns/call |
127 | 600006 | 975ms | ( $field => $env->{$_} ); | ||
128 | } | ||||
129 | 100001 | 2.86s | 100001 | 16.9s | grep { /^(?:HTTP|CONTENT)/i } keys %$env # spent 16.9s making 100001 calls to HTTP::Headers::Fast::new, avg 169µs/call |
130 | ); | ||||
131 | } | ||||
132 | 200002 | 930ms | $self->{headers}; | ||
133 | } | ||||
134 | |||||
135 | sub content_encoding { shift->headers->content_encoding(@_) } | ||||
136 | sub header { shift->headers->header(@_) } | ||||
137 | sub referer { shift->headers->referer(@_) } | ||||
138 | sub user_agent { shift->headers->user_agent(@_) } | ||||
139 | |||||
140 | sub body_parameters { | ||||
141 | my $self = shift; | ||||
142 | |||||
143 | unless ($self->env->{'plack.request.body'}) { | ||||
144 | $self->_parse_request_body; | ||||
145 | } | ||||
146 | |||||
147 | return $self->env->{'plack.request.body'}; | ||||
148 | } | ||||
149 | |||||
150 | # contains body + query | ||||
151 | sub parameters { | ||||
152 | my $self = shift; | ||||
153 | |||||
154 | $self->env->{'plack.request.merged'} ||= do { | ||||
155 | my $query = $self->query_parameters; | ||||
156 | my $body = $self->body_parameters; | ||||
157 | Hash::MultiValue->new($query->flatten, $body->flatten); | ||||
158 | }; | ||||
159 | } | ||||
160 | |||||
161 | sub uploads { | ||||
162 | my $self = shift; | ||||
163 | |||||
164 | if ($self->env->{'plack.request.upload'}) { | ||||
165 | return $self->env->{'plack.request.upload'}; | ||||
166 | } | ||||
167 | |||||
168 | $self->_parse_request_body; | ||||
169 | return $self->env->{'plack.request.upload'}; | ||||
170 | } | ||||
171 | |||||
172 | sub param { | ||||
173 | my $self = shift; | ||||
174 | |||||
175 | return keys %{ $self->parameters } if @_ == 0; | ||||
176 | |||||
177 | my $key = shift; | ||||
178 | return $self->parameters->{$key} unless wantarray; | ||||
179 | return $self->parameters->get_all($key); | ||||
180 | } | ||||
181 | |||||
182 | sub upload { | ||||
183 | my $self = shift; | ||||
184 | |||||
185 | return keys %{ $self->uploads } if @_ == 0; | ||||
186 | |||||
187 | my $key = shift; | ||||
188 | return $self->uploads->{$key} unless wantarray; | ||||
189 | return $self->uploads->get_all($key); | ||||
190 | } | ||||
191 | |||||
192 | sub uri { | ||||
193 | my $self = shift; | ||||
194 | |||||
195 | my $base = $self->_uri_base; | ||||
196 | |||||
197 | # We have to escape back PATH_INFO in case they include stuff like | ||||
198 | # ? or # so that the URI parser won't be tricked. However we should | ||||
199 | # preserve '/' since encoding them into %2f doesn't make sense. | ||||
200 | # This means when a request like /foo%2fbar comes in, we recognize | ||||
201 | # it as /foo/bar which is not ideal, but that's how the PSGI PATH_INFO | ||||
202 | # spec goes and we can't do anything about it. See PSGI::FAQ for details. | ||||
203 | |||||
204 | # See RFC 3986 before modifying. | ||||
205 | my $path_escape_class = q{^/;:@&=A-Za-z0-9\$_.+!*'(),-}; | ||||
206 | |||||
207 | my $path = URI::Escape::uri_escape($self->env->{PATH_INFO} || '', $path_escape_class); | ||||
208 | $path .= '?' . $self->env->{QUERY_STRING} | ||||
209 | if defined $self->env->{QUERY_STRING} && $self->env->{QUERY_STRING} ne ''; | ||||
210 | |||||
211 | $base =~ s!/$!! if $path =~ m!^/!; | ||||
212 | |||||
213 | return URI->new($base . $path)->canonical; | ||||
214 | } | ||||
215 | |||||
216 | sub base { | ||||
217 | my $self = shift; | ||||
218 | URI->new($self->_uri_base)->canonical; | ||||
219 | } | ||||
220 | |||||
221 | sub _uri_base { | ||||
222 | my $self = shift; | ||||
223 | |||||
224 | my $env = $self->env; | ||||
225 | |||||
226 | my $uri = ($env->{'psgi.url_scheme'} || "http") . | ||||
227 | "://" . | ||||
228 | ($env->{HTTP_HOST} || (($env->{SERVER_NAME} || "") . ":" . ($env->{SERVER_PORT} || 80))) . | ||||
229 | ($env->{SCRIPT_NAME} || '/'); | ||||
230 | |||||
231 | return $uri; | ||||
232 | } | ||||
233 | |||||
234 | sub new_response { | ||||
235 | my $self = shift; | ||||
236 | require Plack::Response; | ||||
237 | Plack::Response->new(@_); | ||||
238 | } | ||||
239 | |||||
240 | sub _parse_request_body { | ||||
241 | my $self = shift; | ||||
242 | |||||
243 | my $ct = $self->env->{CONTENT_TYPE}; | ||||
244 | my $cl = $self->env->{CONTENT_LENGTH}; | ||||
245 | if (!$ct && !$cl) { | ||||
246 | # No Content-Type nor Content-Length -> GET/HEAD | ||||
247 | $self->env->{'plack.request.body'} = Hash::MultiValue->new; | ||||
248 | $self->env->{'plack.request.upload'} = Hash::MultiValue->new; | ||||
249 | return; | ||||
250 | } | ||||
251 | |||||
252 | my $body = HTTP::Body->new($ct, $cl); | ||||
253 | |||||
254 | # HTTP::Body will create temporary files in case there was an | ||||
255 | # upload. Those temporary files can be cleaned up by telling | ||||
256 | # HTTP::Body to do so. It will run the cleanup when the request | ||||
257 | # env is destroyed. That the object will not go out of scope by | ||||
258 | # the end of this sub we will store a reference here. | ||||
259 | $self->env->{'plack.request.http.body'} = $body; | ||||
260 | $body->cleanup(1); | ||||
261 | |||||
262 | my $input = $self->input; | ||||
263 | |||||
264 | my $buffer; | ||||
265 | if ($self->env->{'psgix.input.buffered'}) { | ||||
266 | # Just in case if input is read by middleware/apps beforehand | ||||
267 | $input->seek(0, 0); | ||||
268 | } else { | ||||
269 | $buffer = Stream::Buffered->new($cl); | ||||
270 | } | ||||
271 | |||||
272 | my $spin = 0; | ||||
273 | while ($cl) { | ||||
274 | $input->read(my $chunk, $cl < 8192 ? $cl : 8192); | ||||
275 | my $read = length $chunk; | ||||
276 | $cl -= $read; | ||||
277 | $body->add($chunk); | ||||
278 | $buffer->print($chunk) if $buffer; | ||||
279 | |||||
280 | if ($read == 0 && $spin++ > 2000) { | ||||
281 | Carp::croak "Bad Content-Length: maybe client disconnect? ($cl bytes remaining)"; | ||||
282 | } | ||||
283 | } | ||||
284 | |||||
285 | if ($buffer) { | ||||
286 | $self->env->{'psgix.input.buffered'} = 1; | ||||
287 | $self->env->{'psgi.input'} = $buffer->rewind; | ||||
288 | } else { | ||||
289 | $input->seek(0, 0); | ||||
290 | } | ||||
291 | |||||
292 | $self->env->{'plack.request.body'} = Hash::MultiValue->from_mixed($body->param); | ||||
293 | |||||
294 | my @uploads = Hash::MultiValue->from_mixed($body->upload)->flatten; | ||||
295 | my @obj; | ||||
296 | while (my($k, $v) = splice @uploads, 0, 2) { | ||||
297 | push @obj, $k, $self->_make_upload($v); | ||||
298 | } | ||||
299 | |||||
300 | $self->env->{'plack.request.upload'} = Hash::MultiValue->new(@obj); | ||||
301 | |||||
302 | 1; | ||||
303 | } | ||||
304 | |||||
305 | sub _make_upload { | ||||
306 | my($self, $upload) = @_; | ||||
307 | my %copy = %$upload; | ||||
308 | $copy{headers} = HTTP::Headers::Fast->new(%{$upload->{headers}}); | ||||
309 | Plack::Request::Upload->new(%copy); | ||||
310 | } | ||||
311 | |||||
312 | 1 | 2µs | 1; | ||
313 | __END__ | ||||
sub Plack::Request::CORE:match; # opcode | |||||
# spent 1.18s within Plack::Request::CORE:subst which was called 904221 times, avg 1µs/call:
# 600006 times (973ms+0s) by Plack::Request::headers at line 124, avg 2µs/call
# 204214 times (71.7ms+0s) by Plack::Request::_parse_query at line 90, avg 351ns/call
# 100001 times (133ms+0s) by Plack::Request::_parse_query at line 89, avg 1µs/call |