line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Cake::Engine;
|
2
|
8
|
|
|
8
|
|
58
|
use strict;
|
|
8
|
|
|
|
|
21
|
|
|
8
|
|
|
|
|
335
|
|
3
|
8
|
|
|
8
|
|
196
|
use warnings;
|
|
8
|
|
|
|
|
17
|
|
|
8
|
|
|
|
|
244
|
|
4
|
8
|
|
|
8
|
|
43
|
use Carp;
|
|
8
|
|
|
|
|
28
|
|
|
8
|
|
|
|
|
600
|
|
5
|
8
|
|
|
8
|
|
7597
|
use IO::File;
|
|
8
|
|
|
|
|
102083
|
|
|
8
|
|
|
|
|
1247
|
|
6
|
8
|
|
|
8
|
|
10115
|
use File::Temp qw/ tempfile tempdir /;
|
|
8
|
|
|
|
|
123100
|
|
|
8
|
|
|
|
|
4767
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
sub init {
|
9
|
2
|
|
|
2
|
0
|
18
|
my $self = shift;
|
10
|
2
|
|
50
|
|
|
20
|
my $uri = $self->env->{'REQUEST_URI'} || '';
|
11
|
2
|
|
|
|
|
17
|
my($path, $query) = ( $uri =~ /^([^?]*)(?:\?(.*))?$/s );
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
##remove script name from path info
|
14
|
2
|
|
50
|
|
|
10
|
my $script = $self->env->{SCRIPT_NAME} || '';
|
15
|
2
|
|
|
|
|
32
|
$path =~ s/^$script//;
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#for ($path, $query) { s/\#.*$// if length } # dumb clients sending URI fragments
|
18
|
2
|
|
|
|
|
19
|
$self->env->{PATH_INFO} = Cake::URI::uri_decode($path);
|
19
|
2
|
|
50
|
|
|
18
|
$self->env->{QUERY_STRING} = $query || '';
|
20
|
2
|
|
|
|
|
14
|
$self->engine(bless {}, __PACKAGE__);
|
21
|
|
|
|
|
|
|
}
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#BEGIN { open (STDERR, ">>/xampp/htdocs/CakeBlog/error.txt"); }
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
#=============================================================================
|
26
|
|
|
|
|
|
|
# finalize output
|
27
|
|
|
|
|
|
|
#=============================================================================
|
28
|
|
|
|
|
|
|
sub finalize {
|
29
|
3
|
|
|
3
|
0
|
14
|
my $self = shift;
|
30
|
3
|
|
|
|
|
45
|
$self->printConsole();
|
31
|
3
|
|
|
|
|
7
|
return $self;
|
32
|
|
|
|
|
|
|
}
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
#=============================================================================
|
35
|
|
|
|
|
|
|
# console debugging
|
36
|
|
|
|
|
|
|
#=============================================================================
|
37
|
|
|
|
|
|
|
sub printConsole {
|
38
|
3
|
|
|
3
|
0
|
5
|
my $self = shift;
|
39
|
3
|
50
|
|
|
|
15
|
return if !$self->debug;
|
40
|
0
|
0
|
|
|
|
0
|
if (my $logs = $self->app->{log}){
|
41
|
|
|
|
|
|
|
|
42
|
0
|
|
|
|
|
0
|
my $debug = "\n=======================\n";
|
43
|
0
|
|
|
|
|
0
|
$debug .= " DEBUGGING CONSOLE ||\n";
|
44
|
0
|
|
|
|
|
0
|
$debug .= _charFormatter('=');
|
45
|
0
|
|
|
|
|
0
|
$debug .= "REQUEST PATH : ".$self->path . "\n";
|
46
|
0
|
|
|
|
|
0
|
$debug .= "REQUEST METHOD : ".$self->method . "\n";
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
##log request params
|
49
|
|
|
|
|
|
|
|
50
|
0
|
|
|
|
|
0
|
$debug .= _charFormatter('#');
|
51
|
0
|
|
|
|
|
0
|
$debug .= _charFormatter(' ');
|
52
|
|
|
|
|
|
|
|
53
|
0
|
|
|
|
|
0
|
my $i = 0;
|
54
|
0
|
|
|
|
|
0
|
foreach my $log (@{$logs}){
|
|
0
|
|
|
|
|
0
|
|
55
|
|
|
|
|
|
|
|
56
|
0
|
0
|
|
|
|
0
|
if (ref $log eq "ARRAY"){
|
|
|
0
|
|
|
|
|
|
57
|
0
|
|
|
|
|
0
|
$log = join "\n",@{$log};
|
|
0
|
|
|
|
|
0
|
|
58
|
|
|
|
|
|
|
} elsif (ref $log eq 'CODE') {
|
59
|
0
|
|
|
|
|
0
|
$log = $log->();
|
60
|
|
|
|
|
|
|
}
|
61
|
|
|
|
|
|
|
|
62
|
0
|
0
|
|
|
|
0
|
if (length($log) > 65){
|
63
|
0
|
|
|
|
|
0
|
my @logs = unpack("(A62)*", $log);
|
64
|
0
|
|
|
|
|
0
|
my $last = pop @logs;
|
65
|
0
|
|
|
|
|
0
|
foreach my $lo (@logs){
|
66
|
0
|
|
|
|
|
0
|
$lo .= "->";
|
67
|
0
|
|
|
|
|
0
|
$debug .= _printFormatter($lo);
|
68
|
|
|
|
|
|
|
}
|
69
|
0
|
|
|
|
|
0
|
$log = $last;
|
70
|
|
|
|
|
|
|
}
|
71
|
|
|
|
|
|
|
|
72
|
0
|
|
|
|
|
0
|
$debug .= _printFormatter($log);
|
73
|
0
|
|
|
|
|
0
|
$debug .= _charFormatter(' ');
|
74
|
|
|
|
|
|
|
}
|
75
|
0
|
|
|
|
|
0
|
$debug .= _charFormatter('#');
|
76
|
0
|
|
|
|
|
0
|
warn $debug."\n";
|
77
|
|
|
|
|
|
|
}
|
78
|
|
|
|
|
|
|
|
79
|
0
|
0
|
|
|
|
0
|
if (my $warnings = delete $self->app->{warnings}){
|
80
|
8
|
|
|
8
|
|
80
|
use Data::Dumper;
|
|
8
|
|
|
|
|
16
|
|
|
8
|
|
|
|
|
3658
|
|
81
|
0
|
|
|
|
|
0
|
my $warn = "\n=======================\n";
|
82
|
0
|
|
|
|
|
0
|
$warn .= " WARNING CONSOLE ||\n";
|
83
|
0
|
|
|
|
|
0
|
$warn .= _charFormatter('=');
|
84
|
0
|
|
|
|
|
0
|
my $count = 0;
|
85
|
0
|
|
|
|
|
0
|
foreach my $key (keys %{$warnings}){
|
|
0
|
|
|
|
|
0
|
|
86
|
0
|
|
|
|
|
0
|
$warn .= _charFormatter('-');
|
87
|
0
|
|
|
|
|
0
|
$warn .= "CALLER => ". $key . "\n";
|
88
|
0
|
|
|
|
|
0
|
$warn .= "WARNS => ". scalar @{ $warnings->{$key} } . "\n";
|
|
0
|
|
|
|
|
0
|
|
89
|
0
|
|
|
|
|
0
|
$warn .= _charFormatter('-');
|
90
|
0
|
|
|
|
|
0
|
for (@{ $warnings->{$key} }){
|
|
0
|
|
|
|
|
0
|
|
91
|
0
|
|
|
|
|
0
|
$count++;
|
92
|
0
|
|
|
|
|
0
|
$warn .= "Message: ". $_->{message} ."\n";
|
93
|
0
|
|
|
|
|
0
|
$warn .= "Line: ". $_->{line} ."\n\n";
|
94
|
|
|
|
|
|
|
}
|
95
|
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
0
|
$warn .= "\n";
|
97
|
|
|
|
|
|
|
}
|
98
|
|
|
|
|
|
|
|
99
|
0
|
|
|
|
|
0
|
$warn .= _charFormatter('#');
|
100
|
0
|
|
|
|
|
0
|
my $str = "# TOTAL WARNINGS : $count ";
|
101
|
0
|
|
|
|
|
0
|
$warn .= _printFormatter($str);
|
102
|
0
|
|
|
|
|
0
|
$warn .= _charFormatter('#');
|
103
|
|
|
|
|
|
|
|
104
|
0
|
|
|
|
|
0
|
warn $warn;
|
105
|
|
|
|
|
|
|
}
|
106
|
0
|
|
|
|
|
0
|
$self->app->{log} = [];
|
107
|
|
|
|
|
|
|
}
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub _printFormatter {
|
110
|
0
|
|
|
0
|
|
0
|
my $text = shift;
|
111
|
0
|
|
0
|
|
|
0
|
my $padd = shift || ' ';
|
112
|
0
|
|
|
|
|
0
|
my $form .= "$text";
|
113
|
0
|
|
|
|
|
0
|
$form .= $padd x (64 - length($text)) . "#\n";
|
114
|
0
|
|
|
|
|
0
|
return $form;
|
115
|
|
|
|
|
|
|
}
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub _charFormatter {
|
118
|
0
|
|
|
0
|
|
0
|
my $char = shift;
|
119
|
0
|
|
0
|
|
|
0
|
my $multi = shift || 64;
|
120
|
0
|
|
|
|
|
0
|
return ($char x $multi) . "#\n";
|
121
|
|
|
|
|
|
|
}
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
#=============================================================================
|
124
|
|
|
|
|
|
|
# serve output
|
125
|
|
|
|
|
|
|
#=============================================================================
|
126
|
|
|
|
|
|
|
sub serve {
|
127
|
|
|
|
|
|
|
|
128
|
3
|
|
|
3
|
0
|
6
|
my $self = shift;
|
129
|
3
|
|
|
|
|
6
|
my $type = shift;
|
130
|
|
|
|
|
|
|
|
131
|
3
|
50
|
|
|
|
10
|
if ($type){
|
132
|
3
|
50
|
|
|
|
49
|
return $self->serve_as_psgi if uc $type eq 'PSGI';
|
133
|
3
|
50
|
|
|
|
23
|
if (ref $type eq 'CODE'){
|
134
|
3
|
|
|
|
|
12
|
return $type->($self,$self->env->{client});
|
135
|
|
|
|
|
|
|
}
|
136
|
0
|
|
|
|
|
0
|
$self->Require($type,'');
|
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
{
|
139
|
8
|
|
|
8
|
|
56
|
no strict 'refs';
|
|
8
|
|
|
|
|
19
|
|
|
8
|
|
|
|
|
20921
|
|
|
0
|
|
|
|
|
0
|
|
140
|
0
|
|
|
|
|
0
|
*{"${type}::serve"}->($self);
|
|
0
|
|
|
|
|
0
|
|
141
|
|
|
|
|
|
|
}
|
142
|
|
|
|
|
|
|
}
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
else {
|
145
|
0
|
|
|
|
|
0
|
$self->print_headers();
|
146
|
0
|
|
|
|
|
0
|
$self->print_body();
|
147
|
|
|
|
|
|
|
}
|
148
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
0
|
close $self->{response}->{body};
|
150
|
|
|
|
|
|
|
}
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
#=============================================================================
|
155
|
|
|
|
|
|
|
# get parameters
|
156
|
|
|
|
|
|
|
#=============================================================================
|
157
|
|
|
|
|
|
|
sub get_parameters {
|
158
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
159
|
0
|
|
|
|
|
0
|
return $self->_parse_parameters($self->env->{'QUERY_STRING'});
|
160
|
|
|
|
|
|
|
}
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
#=============================================================================
|
163
|
|
|
|
|
|
|
# body parameters
|
164
|
|
|
|
|
|
|
#=============================================================================
|
165
|
|
|
|
|
|
|
sub post_parameters {
|
166
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
167
|
0
|
|
|
|
|
0
|
my $buffer;
|
168
|
|
|
|
|
|
|
|
169
|
0
|
0
|
|
|
|
0
|
return {} if $self->method ne 'post';
|
170
|
|
|
|
|
|
|
|
171
|
0
|
0
|
0
|
|
|
0
|
if (my $tt = ($self->env->{'client.input'} || $self->env->{'psgi.input'})){
|
172
|
|
|
|
|
|
|
{
|
173
|
0
|
|
|
|
|
0
|
local $/;
|
|
0
|
|
|
|
|
0
|
|
174
|
0
|
|
|
|
|
0
|
$buffer = <$tt>;
|
175
|
|
|
|
|
|
|
}
|
176
|
|
|
|
|
|
|
}
|
177
|
|
|
|
|
|
|
##CGI
|
178
|
|
|
|
|
|
|
else {
|
179
|
0
|
|
|
|
|
0
|
read( STDIN, $buffer, $self->env->{ "CONTENT_LENGTH" } );
|
180
|
|
|
|
|
|
|
}
|
181
|
|
|
|
|
|
|
|
182
|
0
|
0
|
|
|
|
0
|
if ($self->env->{CONTENT_TYPE} =~ /^multipart\/form-data/i){
|
183
|
0
|
|
|
|
|
0
|
$self->env->{CONTENT_TYPE} =~ m/boundary=(.*)/;
|
184
|
0
|
|
|
|
|
0
|
my $boundary = $1;
|
185
|
0
|
|
|
|
|
0
|
return $self->_multipart_parameters($buffer,$boundary);
|
186
|
|
|
|
|
|
|
}
|
187
|
|
|
|
|
|
|
|
188
|
0
|
|
|
|
|
0
|
return $self->_parse_parameters($buffer);
|
189
|
|
|
|
|
|
|
}
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
#=============================================================================
|
192
|
|
|
|
|
|
|
# process multipart body parameters
|
193
|
|
|
|
|
|
|
#=============================================================================
|
194
|
|
|
|
|
|
|
sub _multipart_parameters {
|
195
|
|
|
|
|
|
|
|
196
|
0
|
|
|
0
|
|
0
|
my $self = shift;
|
197
|
0
|
|
|
|
|
0
|
my $params = shift;
|
198
|
0
|
|
|
|
|
0
|
my $boundary = shift;
|
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
0
|
my $CRLF = $self->crlf;
|
201
|
0
|
|
|
|
|
0
|
$boundary = '--'.$boundary;
|
202
|
0
|
|
|
|
|
0
|
$params =~ s/$CRLF$boundary--//g;
|
203
|
|
|
|
|
|
|
|
204
|
0
|
|
|
|
|
0
|
my @params = split($boundary.$CRLF,$params);
|
205
|
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
0
|
my @query;
|
207
|
|
|
|
|
|
|
my $handle;
|
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
0
|
for my $field (@params){
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
##remove first line
|
212
|
0
|
|
|
|
|
0
|
$field =~ s/^$CRLF//;
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
##remove last blank
|
215
|
0
|
|
|
|
|
0
|
$field =~ s/$CRLF$//;
|
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
##split on first 2 line breaks
|
218
|
0
|
|
|
|
|
0
|
my ($header,$content) = split(/$CRLF$CRLF/,$field,2);
|
219
|
0
|
0
|
|
|
|
0
|
next if !$header;
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
##split header on line break
|
222
|
0
|
|
|
|
|
0
|
my ($name,$filename,$contenttype) =
|
223
|
|
|
|
|
|
|
$header =~ m/
|
224
|
|
|
|
|
|
|
name="?([^\";]*)"?
|
225
|
|
|
|
|
|
|
(?:;\s+filename="?([^\"]*)"?$CRLF)?
|
226
|
|
|
|
|
|
|
(?:Content-Type:(.*))?
|
227
|
|
|
|
|
|
|
/x;
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
230
|
0
|
0
|
|
|
|
0
|
if($filename){
|
231
|
|
|
|
|
|
|
#make sure the file name is safe
|
232
|
0
|
|
|
|
|
0
|
my $dir = tempdir( CLEANUP => 1 );
|
233
|
0
|
|
|
|
|
0
|
my ($fh, $tmp) = tempfile(
|
234
|
|
|
|
|
|
|
DIR => $dir,
|
235
|
|
|
|
|
|
|
SUFFIX => '.dat'
|
236
|
|
|
|
|
|
|
);
|
237
|
|
|
|
|
|
|
|
238
|
0
|
|
|
|
|
0
|
$fh->unlink_on_destroy( 1 );
|
239
|
|
|
|
|
|
|
|
240
|
0
|
0
|
|
|
|
0
|
if (defined $fh) {
|
241
|
0
|
|
|
|
|
0
|
binmode $fh, ":utf8";
|
242
|
0
|
|
|
|
|
0
|
print $fh $content;
|
243
|
0
|
|
|
|
|
0
|
$fh->close;
|
244
|
|
|
|
|
|
|
}
|
245
|
|
|
|
|
|
|
|
246
|
0
|
|
|
|
|
0
|
$self->{uploads}->{$name} = {
|
247
|
|
|
|
|
|
|
'filehandle' => $fh,
|
248
|
|
|
|
|
|
|
'filename' => $filename,
|
249
|
|
|
|
|
|
|
temp => $tmp,
|
250
|
|
|
|
|
|
|
'path' => $dir,
|
251
|
|
|
|
|
|
|
'content-type' => $contenttype
|
252
|
|
|
|
|
|
|
};
|
253
|
|
|
|
|
|
|
|
254
|
0
|
|
|
|
|
0
|
$content = $filename;
|
255
|
|
|
|
|
|
|
}
|
256
|
|
|
|
|
|
|
|
257
|
0
|
|
|
|
|
0
|
push(@query,$name.'='.Cake::URI::uri_encode($content));
|
258
|
|
|
|
|
|
|
}
|
259
|
|
|
|
|
|
|
|
260
|
0
|
|
|
|
|
0
|
my $query = join('&',@query);
|
261
|
0
|
|
|
|
|
0
|
return $self->_parse_parameters($query);
|
262
|
|
|
|
|
|
|
}
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
#=============================================================================
|
265
|
|
|
|
|
|
|
# XXX - TODO return uploads info & file handle
|
266
|
|
|
|
|
|
|
#=============================================================================
|
267
|
|
|
|
|
|
|
sub uploads {
|
268
|
|
|
|
|
|
|
|
269
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
#didn't parse params yet
|
272
|
0
|
0
|
|
|
|
0
|
unless (defined $self->{'params'}){
|
273
|
0
|
|
|
|
|
0
|
$self->parameters();
|
274
|
|
|
|
|
|
|
}
|
275
|
|
|
|
|
|
|
|
276
|
0
|
0
|
|
|
|
0
|
return {} if !$self->{uploads};
|
277
|
0
|
|
|
|
|
0
|
return $self->{uploads};
|
278
|
|
|
|
|
|
|
}
|
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub upload {
|
281
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
282
|
0
|
|
|
|
|
0
|
my $name = shift;
|
283
|
0
|
|
|
|
|
0
|
return $self->uploads->{$name};
|
284
|
|
|
|
|
|
|
}
|
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
#=============================================================================
|
288
|
|
|
|
|
|
|
# return processed parameters
|
289
|
|
|
|
|
|
|
#=============================================================================
|
290
|
|
|
|
|
|
|
sub parameters {
|
291
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
292
|
0
|
0
|
|
|
|
0
|
return $self->{'params'} if $self->{'params'};
|
293
|
0
|
|
|
|
|
0
|
my $params = Cake::Utils::combineHashes($self->get_parameters,$self->post_parameters);
|
294
|
0
|
|
|
|
|
0
|
$self->{'params'} = $params;
|
295
|
0
|
|
|
|
|
0
|
return $params;
|
296
|
|
|
|
|
|
|
}
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
#=============================================================================
|
299
|
|
|
|
|
|
|
# parse parameters
|
300
|
|
|
|
|
|
|
#=============================================================================
|
301
|
|
|
|
|
|
|
sub _parse_parameters {
|
302
|
|
|
|
|
|
|
|
303
|
0
|
|
|
0
|
|
0
|
my $self = shift;
|
304
|
0
|
|
|
|
|
0
|
my $content = shift;
|
305
|
0
|
|
|
|
|
0
|
my $params = {};
|
306
|
|
|
|
|
|
|
|
307
|
0
|
|
|
|
|
0
|
my @pairs = split(/[&;]/, $content);
|
308
|
0
|
|
|
|
|
0
|
foreach my $pair (@pairs) {
|
309
|
0
|
|
|
|
|
0
|
my ($name, $value) = map Cake::URI::uri_decode($_), split( "=", $pair, 2 );
|
310
|
|
|
|
|
|
|
|
311
|
0
|
0
|
|
|
|
0
|
if ($name =~ s/\[(\d+)\]\[(.*?)\]//){
|
312
|
0
|
|
|
|
|
0
|
my $index = $1;
|
313
|
0
|
|
|
|
|
0
|
my $n = $2;
|
314
|
0
|
0
|
|
|
|
0
|
if (!ref $params->{$name}){
|
315
|
0
|
|
|
|
|
0
|
$params->{$name} = [];
|
316
|
|
|
|
|
|
|
}
|
317
|
0
|
|
|
|
|
0
|
$params->{$name}->[$index]->{$n} = $value;
|
318
|
|
|
|
|
|
|
} else {
|
319
|
|
|
|
|
|
|
|
320
|
0
|
0
|
0
|
|
|
0
|
if ($name =~ s/\[\]$// && !ref $params->{$name}){
|
321
|
0
|
|
|
|
|
0
|
$params->{$name} = [];
|
322
|
|
|
|
|
|
|
}
|
323
|
|
|
|
|
|
|
|
324
|
0
|
0
|
|
|
|
0
|
if ($params->{$name}){
|
325
|
0
|
0
|
|
|
|
0
|
if (!ref $params->{$name}){
|
326
|
0
|
|
|
|
|
0
|
my $holds = [$params->{$name},$value];
|
327
|
0
|
|
|
|
|
0
|
$params->{$name} = $holds;
|
328
|
|
|
|
|
|
|
} else {
|
329
|
0
|
|
|
|
|
0
|
push (@{$params->{$name}},$value);
|
|
0
|
|
|
|
|
0
|
|
330
|
|
|
|
|
|
|
}
|
331
|
|
|
|
|
|
|
} else {
|
332
|
0
|
|
|
|
|
0
|
$params->{$name} = $value;
|
333
|
|
|
|
|
|
|
}
|
334
|
|
|
|
|
|
|
}
|
335
|
|
|
|
|
|
|
}
|
336
|
|
|
|
|
|
|
|
337
|
0
|
|
|
|
|
0
|
return $params;
|
338
|
|
|
|
|
|
|
}
|
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
#serve content as psgi
|
341
|
|
|
|
|
|
|
sub serve_as_psgi {
|
342
|
|
|
|
|
|
|
|
343
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
344
|
|
|
|
|
|
|
|
345
|
0
|
|
|
|
|
0
|
my @headers = $self->_get_psgi_headers;
|
346
|
|
|
|
|
|
|
|
347
|
0
|
|
|
|
|
0
|
my $body = $self->body();
|
348
|
|
|
|
|
|
|
|
349
|
0
|
0
|
|
|
|
0
|
seek($body,0,0) if ref $body eq 'GLOB';
|
350
|
|
|
|
|
|
|
|
351
|
0
|
0
|
|
|
|
0
|
if (!ref $body){
|
|
|
0
|
|
|
|
|
|
352
|
0
|
|
|
|
|
0
|
$body = [ $body ];
|
353
|
|
|
|
|
|
|
}
|
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
elsif (ref $body eq 'CODE'){
|
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
return sub {
|
358
|
0
|
|
|
0
|
|
0
|
my $response = shift;
|
359
|
0
|
|
|
|
|
0
|
my $w = $response->([ $self->status_code(), \@headers ]);
|
360
|
0
|
|
|
|
|
0
|
$body->($w);
|
361
|
0
|
|
|
|
|
0
|
};
|
362
|
|
|
|
|
|
|
|
363
|
0
|
|
|
|
|
0
|
return $body;
|
364
|
|
|
|
|
|
|
}
|
365
|
|
|
|
|
|
|
|
366
|
0
|
|
|
|
|
0
|
return [ $self->status_code, \@headers, $body ];
|
367
|
|
|
|
|
|
|
}
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub _get_psgi_headers {
|
370
|
0
|
|
|
0
|
|
0
|
my $self = shift;
|
371
|
0
|
|
|
|
|
0
|
my @headers = ('Content-Type',$self->content_type);
|
372
|
0
|
|
|
|
|
0
|
foreach my $header (@{$self->headers}){
|
|
0
|
|
|
|
|
0
|
|
373
|
0
|
|
|
|
|
0
|
my @nh = split(/:/,$header,2);
|
374
|
0
|
|
|
|
|
0
|
push (@headers,@nh);
|
375
|
|
|
|
|
|
|
}
|
376
|
0
|
|
|
|
|
0
|
return @headers;
|
377
|
|
|
|
|
|
|
}
|
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
sub print_headers {
|
380
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
381
|
0
|
|
|
|
|
0
|
my $headers;
|
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
##normal print/ for CGI
|
384
|
0
|
|
|
|
|
0
|
my $content_type_header = 'Content-Type: '.$self->content_type;
|
385
|
0
|
|
|
|
|
0
|
my $status_code = 'Status-code: '.$self->status_code;
|
386
|
0
|
|
|
|
|
0
|
$headers = Cake::Utils::get_status_code($self->env,$self->status_code);
|
387
|
0
|
|
|
|
|
0
|
$headers .= "$content_type_header\015\012";
|
388
|
0
|
|
|
|
|
0
|
my $found_content_length;
|
389
|
0
|
|
|
|
|
0
|
foreach my $header (@{$self->headers}){
|
|
0
|
|
|
|
|
0
|
|
390
|
0
|
|
|
|
|
0
|
$headers .= $header."\015\012";
|
391
|
0
|
0
|
0
|
|
|
0
|
$found_content_length = 1
|
392
|
|
|
|
|
|
|
if $header =~ /^Content-Length/i && !$found_content_length;
|
393
|
|
|
|
|
|
|
}
|
394
|
|
|
|
|
|
|
|
395
|
0
|
0
|
|
|
|
0
|
unless ($found_content_length){
|
396
|
0
|
|
|
|
|
0
|
my $body = $self->body();
|
397
|
0
|
0
|
|
|
|
0
|
$headers .= "Content-Length: ".Cake::Utils::content_length($body)."\015\012" if $body;
|
398
|
|
|
|
|
|
|
}
|
399
|
|
|
|
|
|
|
|
400
|
0
|
|
|
|
|
0
|
$headers .= "\015\012";
|
401
|
0
|
|
|
|
|
0
|
my $stdout = $self->stdout;
|
402
|
0
|
|
|
|
|
0
|
print $stdout $headers;
|
403
|
|
|
|
|
|
|
}
|
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub print_body {
|
406
|
0
|
|
|
0
|
0
|
0
|
my $self = shift;
|
407
|
0
|
|
|
|
|
0
|
my $body = $self->body();
|
408
|
0
|
|
|
|
|
0
|
my $stdout = $self->stdout;
|
409
|
0
|
|
|
|
|
0
|
binmode $stdout;
|
410
|
0
|
0
|
|
|
|
0
|
if (ref $body eq 'GLOB'){
|
|
|
0
|
|
|
|
|
|
411
|
|
|
|
|
|
|
##seek to the start
|
412
|
0
|
|
|
|
|
0
|
seek($body,0,0);
|
413
|
0
|
|
|
|
|
0
|
local $/ = undef;
|
414
|
0
|
|
|
|
|
0
|
$body = <$body>;
|
415
|
0
|
|
|
|
|
0
|
print $stdout $body;
|
416
|
|
|
|
|
|
|
}
|
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
elsif (ref $body eq 'CODE'){
|
419
|
0
|
|
|
|
|
0
|
$body->(__PACKAGE__);
|
420
|
|
|
|
|
|
|
}
|
421
|
|
|
|
|
|
|
}
|
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
#=============================================================================
|
424
|
|
|
|
|
|
|
# ENV
|
425
|
|
|
|
|
|
|
#=============================================================================
|
426
|
|
|
|
|
|
|
sub path {
|
427
|
4
|
50
|
|
4
|
0
|
29
|
if (@_ > 1){
|
428
|
0
|
|
|
|
|
0
|
$_[0]->env->{PATH_INFO} = $_[1];
|
429
|
0
|
|
|
|
|
0
|
return $_[0];
|
430
|
|
|
|
|
|
|
}
|
431
|
4
|
|
50
|
|
|
18
|
return $_[0]->env->{PATH_INFO} || '/';
|
432
|
|
|
|
|
|
|
}
|
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
sub method {
|
435
|
3
|
50
|
|
3
|
0
|
14
|
if (@_ > 1){
|
436
|
0
|
|
|
|
|
0
|
$_[0]->env->{REQUEST_METHOD} = $_[1];
|
437
|
|
|
|
|
|
|
}
|
438
|
3
|
|
50
|
|
|
14
|
return lc ($_[0]->env->{REQUEST_METHOD} || '');
|
439
|
|
|
|
|
|
|
}
|
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
sub is_secure {
|
442
|
0
|
0
|
|
0
|
0
|
|
return $_[0]->env->{'SSL_PROTOCOL'} ? 1 : 0;
|
443
|
|
|
|
|
|
|
}
|
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
sub base {
|
446
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
447
|
0
|
|
|
|
|
|
my $base = 'http';
|
448
|
0
|
0
|
|
|
|
|
$base .='s' if $self->is_secure();
|
449
|
0
|
|
|
|
|
|
$base .= '://'.$self->env->{HTTP_HOST};
|
450
|
0
|
|
|
|
|
|
return $base;
|
451
|
|
|
|
|
|
|
}
|
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
sub host {
|
454
|
0
|
|
|
0
|
0
|
|
return $_[0]->env->{HTTP_HOST};
|
455
|
|
|
|
|
|
|
}
|
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
sub server_protocol {
|
458
|
0
|
|
0
|
0
|
0
|
|
return shift->env->{SERVER_PROTOCOL} || 'HTTP/1.1';
|
459
|
|
|
|
|
|
|
}
|
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
sub request_header {
|
462
|
|
|
|
|
|
|
|
463
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
464
|
0
|
|
|
|
|
|
my $header = uc shift;
|
465
|
0
|
|
|
|
|
|
my $response_headers = {
|
466
|
|
|
|
|
|
|
'ETAG' => 'IF-NONE-MATCH'
|
467
|
|
|
|
|
|
|
};
|
468
|
0
|
|
|
|
|
|
$header =~ s/^(HTTP[-_])//;
|
469
|
0
|
|
|
|
|
|
$header =~ s/[-\s]/_/g;
|
470
|
0
|
|
0
|
|
|
|
$header = $response_headers->{$header} || $header;
|
471
|
0
|
|
|
|
|
|
$header = 'HTTP_'.$header;
|
472
|
0
|
|
|
|
|
|
return $self->env->{$header};
|
473
|
|
|
|
|
|
|
}
|
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
sub stdout {
|
476
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
477
|
0
|
0
|
|
|
|
|
if (@_){
|
478
|
0
|
|
|
|
|
|
$self->env->{client} = shift;
|
479
|
|
|
|
|
|
|
}
|
480
|
0
|
|
0
|
|
|
|
return $self->env->{client} || \*STDOUT;
|
481
|
|
|
|
|
|
|
}
|
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
#=============================================================================
|
484
|
|
|
|
|
|
|
# cookies : return cookies list as hash - copied from plack
|
485
|
|
|
|
|
|
|
#=============================================================================
|
486
|
|
|
|
|
|
|
sub cookies {
|
487
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
488
|
0
|
0
|
|
|
|
|
return {} unless $self->env->{HTTP_COOKIE};
|
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# HTTP_COOKIE hasn't changed: reuse the parsed cookie
|
491
|
0
|
0
|
0
|
|
|
|
if ( $self->env->{'cake.cookie.parsed'}
|
492
|
|
|
|
|
|
|
&& $self->env->{'cake.cookie.string'} eq $self->env->{HTTP_COOKIE}) {
|
493
|
0
|
|
|
|
|
|
return $self->env->{'cake.cookie.parsed'};
|
494
|
|
|
|
|
|
|
}
|
495
|
|
|
|
|
|
|
|
496
|
0
|
|
|
|
|
|
$self->env->{'cake.cookie.string'} = $self->env->{HTTP_COOKIE};
|
497
|
|
|
|
|
|
|
|
498
|
0
|
|
|
|
|
|
my %results;
|
499
|
0
|
|
|
|
|
|
my @pairs = grep /=/, split "[;,] ?", $self->env->{'cake.cookie.string'};
|
500
|
|
|
|
|
|
|
|
501
|
0
|
|
|
|
|
|
for my $pair ( @pairs ) {
|
502
|
|
|
|
|
|
|
# trim leading trailing whitespace
|
503
|
0
|
|
|
|
|
|
$pair =~ s/^\s+//; $pair =~ s/\s+$//;
|
|
0
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
#my ($key, $value) = split( "=", $pair, 2 );
|
505
|
0
|
|
|
|
|
|
my ($key, $value) = map Cake::URI::uri_decode($_), split( "=", $pair, 2 );
|
506
|
|
|
|
|
|
|
# Take the first one like CGI.pm or rack do
|
507
|
0
|
0
|
|
|
|
|
$results{$key} = $value unless exists $results{$key};
|
508
|
|
|
|
|
|
|
}
|
509
|
|
|
|
|
|
|
|
510
|
0
|
|
|
|
|
|
$self->env->{'cake.cookie.parsed'} = \%results;
|
511
|
0
|
|
|
|
|
|
return \%results;
|
512
|
|
|
|
|
|
|
}
|
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
#=============================================================================
|
515
|
|
|
|
|
|
|
# set/get a cookie
|
516
|
|
|
|
|
|
|
#=============================================================================
|
517
|
|
|
|
|
|
|
sub cookie {
|
518
|
0
|
|
|
0
|
0
|
|
my $self = shift;
|
519
|
|
|
|
|
|
|
|
520
|
0
|
0
|
|
|
|
|
if (ref $_[0] eq 'HASH'){
|
521
|
0
|
|
|
|
|
|
my $args = shift;
|
522
|
0
|
|
0
|
|
|
|
my $name = Cake::URI::uri_encode($args->{name} || ref $self->app);
|
523
|
0
|
|
0
|
|
|
|
my $value = Cake::URI::uri_encode($args->{value} || '');
|
524
|
0
|
|
0
|
|
|
|
my $secure = $args->{secure} || '0';
|
525
|
0
|
|
0
|
|
|
|
my $path = $args->{path} || '/';
|
526
|
0
|
|
|
|
|
|
my $time = '';
|
527
|
|
|
|
|
|
|
|
528
|
0
|
0
|
|
|
|
|
if ($args->{length}){
|
529
|
0
|
|
|
|
|
|
my $length = Cake::Utils::to_epoch($args->{length});
|
530
|
0
|
|
|
|
|
|
$time = gmtime($length)." GMT";
|
531
|
|
|
|
|
|
|
}
|
532
|
|
|
|
|
|
|
|
533
|
0
|
|
|
|
|
|
my $cookie = "$name=$value; path=$path; expires=$time; $secure";
|
534
|
0
|
|
|
|
|
|
$self->push_header('Set-Cookie: '.$cookie);
|
535
|
|
|
|
|
|
|
}
|
536
|
|
|
|
|
|
|
|
537
|
0
|
0
|
0
|
|
|
|
croak 'cookie method only accepts Hash ref for setting and string for getting'
|
538
|
|
|
|
|
|
|
if ref $_[0] || @_ > 1;
|
539
|
|
|
|
|
|
|
|
540
|
0
|
|
0
|
|
|
|
my $name = shift || '';
|
541
|
0
|
|
|
|
|
|
return $self->cookies->{$name};
|
542
|
|
|
|
|
|
|
}
|
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
1;
|