| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
##-*- Mode: CPerl; coding: utf-8; -*- |
|
2
|
|
|
|
|
|
|
## |
|
3
|
|
|
|
|
|
|
## File: DiaColloDB/WWW/CGI.pm |
|
4
|
|
|
|
|
|
|
## Author: Bryan Jurish |
|
5
|
|
|
|
|
|
|
## Description: collocation db, www wrappers: (f)cgi handler |
|
6
|
|
|
|
|
|
|
## + adapted from DbCgi.pm ( svn+ssh://odo.dwds.de/home/svn/dev/dbcgi/trunk/DbCgi.pm ) |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
package DiaColloDB::WWW::CGI; |
|
9
|
1
|
|
|
1
|
|
60678
|
use DiaColloDB; |
|
|
1
|
|
|
|
|
291434
|
|
|
|
1
|
|
|
|
|
36
|
|
|
10
|
1
|
|
|
1
|
|
14
|
use DiaColloDB::Logger; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
19
|
|
|
11
|
1
|
|
|
1
|
|
708
|
use CGI qw(:standard :cgi-lib); |
|
|
1
|
|
|
|
|
22492
|
|
|
|
1
|
|
|
|
|
4
|
|
|
12
|
1
|
|
|
1
|
|
3341
|
use URI; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
22
|
|
|
13
|
1
|
|
|
1
|
|
5
|
use URI::Escape qw(uri_escape_utf8); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
53
|
|
|
14
|
1
|
|
|
1
|
|
5
|
use HTTP::Status; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
203
|
|
|
15
|
1
|
|
|
1
|
|
5
|
use Encode qw(); #qw(encode decode encode_utf8 decode_utf8); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
15
|
|
|
16
|
1
|
|
|
1
|
|
7
|
use File::Basename qw(basename dirname); |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
37
|
|
|
17
|
1
|
|
|
1
|
|
345
|
use File::ShareDir qw(); ##-- for shared template data |
|
|
1
|
|
|
|
|
4473
|
|
|
|
1
|
|
|
|
|
20
|
|
|
18
|
1
|
|
|
1
|
|
5
|
use Cwd qw(getcwd abs_path); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
43
|
|
|
19
|
|
|
|
|
|
|
#use LWP::UserAgent; |
|
20
|
1
|
|
|
1
|
|
341
|
use Template; |
|
|
1
|
|
|
|
|
13540
|
|
|
|
1
|
|
|
|
|
38
|
|
|
21
|
1
|
|
|
1
|
|
10
|
use JSON qw(); |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
31
|
|
|
22
|
1
|
|
|
1
|
|
7
|
use Time::HiRes qw(); |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
24
|
|
|
23
|
1
|
|
|
1
|
|
12
|
use utf8; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
8
|
|
|
24
|
1
|
|
|
1
|
|
37
|
use Carp; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
72
|
|
|
25
|
1
|
|
|
1
|
|
7
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
41
|
|
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
BEGIN { |
|
28
|
|
|
|
|
|
|
#binmode(STDIN, ':utf8'); |
|
29
|
|
|
|
|
|
|
#binmode(STDOUT,':utf8'); |
|
30
|
1
|
|
|
1
|
|
5579
|
binmode(STDERR,':utf8'); |
|
31
|
|
|
|
|
|
|
} |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
*isa = \&UNIVERSAL::isa; |
|
34
|
|
|
|
|
|
|
*can = \&UNIVERSAL::can; |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
##====================================================================== |
|
37
|
|
|
|
|
|
|
## globals |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
our $VERSION = "0.02.003"; |
|
40
|
|
|
|
|
|
|
our @ISA = qw(DiaColloDB::Logger); |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
##====================================================================== |
|
43
|
|
|
|
|
|
|
## constructors etc. |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
## $dbcgi = $that->new(%args) |
|
46
|
|
|
|
|
|
|
## + %args, object structure: |
|
47
|
|
|
|
|
|
|
## ( |
|
48
|
|
|
|
|
|
|
## ##-- basic stuff |
|
49
|
|
|
|
|
|
|
## prog => basename($0), |
|
50
|
|
|
|
|
|
|
## ## |
|
51
|
|
|
|
|
|
|
## ##-- underlying CGI module |
|
52
|
|
|
|
|
|
|
## cgipkg => 'CGI', |
|
53
|
|
|
|
|
|
|
## ## |
|
54
|
|
|
|
|
|
|
## ##-- CGI params |
|
55
|
|
|
|
|
|
|
## defaults => {}, |
|
56
|
|
|
|
|
|
|
## vars => undef, |
|
57
|
|
|
|
|
|
|
## charset => 'utf-8', |
|
58
|
|
|
|
|
|
|
## nodecode => {}, ##-- vars not to decode |
|
59
|
|
|
|
|
|
|
## ## |
|
60
|
|
|
|
|
|
|
## ##-- CGI environment stuff : see getenv() method |
|
61
|
|
|
|
|
|
|
## remote_addr => undef, |
|
62
|
|
|
|
|
|
|
## remote_user => undef, |
|
63
|
|
|
|
|
|
|
## request_method => undef, |
|
64
|
|
|
|
|
|
|
## request_uri => undef, |
|
65
|
|
|
|
|
|
|
## request_query => undef, |
|
66
|
|
|
|
|
|
|
## http_referer => undef, |
|
67
|
|
|
|
|
|
|
## http_host => undef, |
|
68
|
|
|
|
|
|
|
## server_addr => undef, |
|
69
|
|
|
|
|
|
|
## server_port => undef, |
|
70
|
|
|
|
|
|
|
## ## |
|
71
|
|
|
|
|
|
|
## ##-- template toolkit stuff |
|
72
|
|
|
|
|
|
|
## ttk_package => (ref($that)||$that), |
|
73
|
|
|
|
|
|
|
## ttk_vars => {}, ##-- template vars |
|
74
|
|
|
|
|
|
|
## ttk_config => {ENCODING=>'utf8'}, ##-- options for Template->new() |
|
75
|
|
|
|
|
|
|
## ttk_process => {binmode=>':utf8'}, ##-- options for Template->process() |
|
76
|
|
|
|
|
|
|
## ttk_dir => abs_path(dirname($0)), |
|
77
|
|
|
|
|
|
|
## ttk_key => undef, ##-- current template basename |
|
78
|
|
|
|
|
|
|
## ttk_rawkeys => { ##-- pseudo-set of raw keys |
|
79
|
|
|
|
|
|
|
## profile=>1, |
|
80
|
|
|
|
|
|
|
## }, |
|
81
|
|
|
|
|
|
|
## ## |
|
82
|
|
|
|
|
|
|
## ##-- File::ShareDir stuff (fallbacks for ttk_dir) |
|
83
|
|
|
|
|
|
|
## ttk_sharedir => File::ShareDir::dist_dir("DiaColloDB-WWW")."/htdocs", |
|
84
|
|
|
|
|
|
|
## ) |
|
85
|
|
|
|
|
|
|
sub new { |
|
86
|
0
|
|
|
0
|
1
|
|
my $that = shift; |
|
87
|
0
|
|
0
|
|
|
|
my $dbcgi = bless({ |
|
|
|
|
0
|
|
|
|
|
|
88
|
|
|
|
|
|
|
##-- basic stuff |
|
89
|
|
|
|
|
|
|
prog => basename($0), |
|
90
|
|
|
|
|
|
|
## |
|
91
|
|
|
|
|
|
|
##-- underlying CGI module |
|
92
|
|
|
|
|
|
|
cgipkg => 'CGI', |
|
93
|
|
|
|
|
|
|
## |
|
94
|
|
|
|
|
|
|
##-- CGI params |
|
95
|
|
|
|
|
|
|
defaults => {}, |
|
96
|
|
|
|
|
|
|
vars => undef, |
|
97
|
|
|
|
|
|
|
charset => 'utf-8', |
|
98
|
|
|
|
|
|
|
nodecode => {}, ##-- vars not to decode |
|
99
|
|
|
|
|
|
|
## |
|
100
|
|
|
|
|
|
|
##-- CGI environment stuff : see getenv() method |
|
101
|
|
|
|
|
|
|
remote_addr => undef, |
|
102
|
|
|
|
|
|
|
remote_user => undef, |
|
103
|
|
|
|
|
|
|
request_method => undef, |
|
104
|
|
|
|
|
|
|
request_uri => undef, |
|
105
|
|
|
|
|
|
|
request_query => undef, |
|
106
|
|
|
|
|
|
|
http_referer => undef, |
|
107
|
|
|
|
|
|
|
http_host => undef, |
|
108
|
|
|
|
|
|
|
server_addr => undef, |
|
109
|
|
|
|
|
|
|
server_port => undef, |
|
110
|
|
|
|
|
|
|
## |
|
111
|
|
|
|
|
|
|
##-- template toolkit stuff |
|
112
|
|
|
|
|
|
|
ttk_package => (ref($that)||$that), |
|
113
|
|
|
|
|
|
|
ttk_vars => {}, ##-- template vars |
|
114
|
|
|
|
|
|
|
ttk_config => {ENCODING=>'utf8'}, ##-- options for Template->new() |
|
115
|
|
|
|
|
|
|
ttk_process => {binmode=>':utf8'}, ##-- options for Template->process() |
|
116
|
|
|
|
|
|
|
ttk_dir => abs_path(dirname($0)), |
|
117
|
|
|
|
|
|
|
ttk_key => undef, ##-- current template basename |
|
118
|
|
|
|
|
|
|
ttk_rawkeys => { ##-- pseudo-set of raw keys |
|
119
|
|
|
|
|
|
|
profile=>1, |
|
120
|
|
|
|
|
|
|
}, |
|
121
|
|
|
|
|
|
|
## |
|
122
|
|
|
|
|
|
|
##-- File::ShareDir stuff (fallbacks for ttk_dir) |
|
123
|
|
|
|
|
|
|
ttk_sharedir => File::ShareDir::dist_dir("DiaColloDB-WWW")."/htdocs", |
|
124
|
|
|
|
|
|
|
## |
|
125
|
|
|
|
|
|
|
##-- user args |
|
126
|
|
|
|
|
|
|
@_, |
|
127
|
|
|
|
|
|
|
}, ref($that)||$that); |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
##-- CGI package |
|
130
|
0
|
0
|
|
|
|
|
if ($dbcgi->{cgipkg}) { |
|
131
|
0
|
|
|
|
|
|
eval "use $dbcgi->{cgipkg} qw(:standard :cgi-lib);"; |
|
132
|
0
|
0
|
|
|
|
|
$dbcgi->logconfess("new(): could not use {cgipkg} $dbcgi->{cgipkg}: $@") if ($@); |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
##-- environment defaults |
|
136
|
0
|
|
|
|
|
|
$dbcgi->_getenv(); |
|
137
|
|
|
|
|
|
|
|
|
138
|
0
|
|
|
|
|
|
return $dbcgi; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
## @keys = $dbcgi->_param() |
|
142
|
|
|
|
|
|
|
## $val = $dbcgi->_param($name) |
|
143
|
|
|
|
|
|
|
sub _param { |
|
144
|
0
|
|
|
0
|
|
|
my $dbcgi = shift; |
|
145
|
0
|
|
|
|
|
|
return $dbcgi->cgi('param',@_); |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
## $dbcgi = $dbcgi->_reset() |
|
149
|
|
|
|
|
|
|
## + resets CGI environment |
|
150
|
|
|
|
|
|
|
sub _reset { |
|
151
|
0
|
|
|
0
|
|
|
my $dbcgi = shift; |
|
152
|
0
|
|
|
|
|
|
delete @$dbcgi{(qw(vars), |
|
153
|
|
|
|
|
|
|
qw(remote_addr remote_user), |
|
154
|
|
|
|
|
|
|
qw(request_method request_uri request_query), |
|
155
|
|
|
|
|
|
|
qw(http_referer http_host server_addr server_port), |
|
156
|
|
|
|
|
|
|
)}; |
|
157
|
0
|
|
|
|
|
|
return $dbcgi; |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
## $dbcgi = $dbcgi->_getenv() |
|
161
|
|
|
|
|
|
|
sub _getenv { |
|
162
|
0
|
|
|
0
|
|
|
my $dbcgi = shift; |
|
163
|
0
|
|
0
|
|
|
|
$dbcgi->{remote_addr} = ($ENV{REMOTE_ADDR}||'0.0.0.0'); |
|
164
|
0
|
|
0
|
|
|
|
$dbcgi->{remote_user} = ($ENV{REMOTE_USER} || getpwuid($>)); |
|
165
|
0
|
|
0
|
|
|
|
$dbcgi->{request_method} = ($ENV{REQUEST_METHOD}||'GET'); |
|
166
|
0
|
|
0
|
|
|
|
$dbcgi->{request_uri} = ($ENV{REQUEST_URI} || $0); |
|
167
|
0
|
|
|
|
|
|
$dbcgi->{request_query} = $ENV{QUERY_STRING}; |
|
168
|
0
|
|
|
|
|
|
$dbcgi->{http_referer} = $ENV{HTTP_REFERER}; |
|
169
|
0
|
|
|
|
|
|
$dbcgi->{http_host} = $ENV{HTTP_HOST}; |
|
170
|
0
|
|
|
|
|
|
$dbcgi->{server_addr} = $ENV{SERVER_ADDR}; |
|
171
|
0
|
|
|
|
|
|
$dbcgi->{server_port} = $ENV{SERVER_PORT}; |
|
172
|
0
|
|
|
|
|
|
return $dbcgi; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
## $dbcgi = $dbcgi->fromRequest($httpRequest,$csock) |
|
176
|
|
|
|
|
|
|
## + sets up $dbcgi from an HTTP::Request object |
|
177
|
|
|
|
|
|
|
sub fromRequest { |
|
178
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$hreq,$csock) = @_; |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
##-- setup pseudo-environment |
|
181
|
0
|
|
|
|
|
|
my $uri = $hreq->uri; |
|
182
|
0
|
|
|
|
|
|
my @path = grep {$_ ne ''} $uri->path_segments; |
|
|
0
|
|
|
|
|
|
|
|
183
|
0
|
|
0
|
|
|
|
$dbcgi->{prog} = $path[$#path] || 'index'; |
|
184
|
0
|
0
|
|
|
|
|
$dbcgi->{remote_addr} = $ENV{REMOTE_ADDR} = $csock ? $csock->peerhost : '0.0.0.0'; |
|
185
|
0
|
0
|
|
|
|
|
$dbcgi->{remote_port} = $ENV{REMOTE_PORT} = $csock ? $csock->peerport : '0'; |
|
186
|
0
|
|
|
|
|
|
$dbcgi->{remote_user} = $ENV{REMOTE_USER} = ''; |
|
187
|
0
|
|
|
|
|
|
$dbcgi->{request_method} = $ENV{REQUEST_METHOD} = $hreq->method; |
|
188
|
0
|
|
|
|
|
|
$dbcgi->{request_uri} = $ENV{REQUEST_URI} = $uri->as_string; |
|
189
|
0
|
|
|
|
|
|
$dbcgi->{request_query} = $ENV{REQUEST_QUERY} = $uri->query; |
|
190
|
0
|
|
|
|
|
|
$dbcgi->{http_referer} = $ENV{HTTP_REFERER} = $hreq->referer; |
|
191
|
0
|
|
0
|
|
|
|
$dbcgi->{http_host} = $ENV{HTTP_HOST} = $uri->host || $csock->sockhost; |
|
192
|
0
|
0
|
|
|
|
|
$dbcgi->{server_addr} = $ENV{SERVER_ADDR} = $csock ? $csock->sockaddr : '0.0.0.0'; |
|
193
|
0
|
0
|
|
|
|
|
$dbcgi->{server_port} = $ENV{SERVER_PORT} = $csock ? $csock->sockport : '0'; |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
##-- setup variables |
|
196
|
0
|
|
|
|
|
|
my %vars = $uri->query_form; |
|
197
|
|
|
|
|
|
|
my $addVars = sub { |
|
198
|
0
|
|
|
0
|
|
|
my $add = shift; |
|
199
|
0
|
|
|
|
|
|
foreach (grep {defined $add->{$_}} keys %$add) { |
|
|
0
|
|
|
|
|
|
|
|
200
|
0
|
0
|
|
|
|
|
if (!exists($vars{$_})) { |
|
201
|
0
|
|
|
|
|
|
$vars{$_} = $add->{$_}; |
|
202
|
|
|
|
|
|
|
} else { |
|
203
|
0
|
0
|
|
|
|
|
$vars{$_} = [ $vars{$_} ] if (!ref($vars{$_})); |
|
204
|
0
|
0
|
|
|
|
|
push(@{$vars{$_}}, ref($add->{$_}) ? @{$add->{$_}} : $add->{$_}); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
} |
|
207
|
0
|
|
|
|
|
|
}; |
|
208
|
0
|
0
|
|
|
|
|
if ($hreq->method eq 'POST') { |
|
209
|
0
|
0
|
|
|
|
|
if ($hreq->content_type eq 'application/x-www-form-urlencoded') { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
##-- POST: x-www-form-urlencoded |
|
211
|
0
|
|
|
|
|
|
$addVars->( {URI->new('?'.$hreq->content)->query_form} ); |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
elsif ($hreq->content_type eq 'multipart/form-data') { |
|
214
|
|
|
|
|
|
|
##-- POST: multipart/form-data: parse by hand |
|
215
|
0
|
|
|
|
|
|
foreach my $part ($hreq->parts) { |
|
216
|
0
|
|
|
|
|
|
my $pdis = $part->header('Content-Disposition'); |
|
217
|
0
|
0
|
|
|
|
|
if ($pdis =~ /^form-data\b/) { |
|
218
|
|
|
|
|
|
|
##-- POST: multipart/form-data: part: form-data; name="PARAMNAME" |
|
219
|
0
|
0
|
|
|
|
|
if ($pdis =~ /\bname=[\"\']?([\w\-\.\,\+]*)[\'\"]?/) { |
|
220
|
0
|
|
|
|
|
|
$addVars->({ $1 => $part->content }); |
|
221
|
0
|
|
|
|
|
|
next; |
|
222
|
|
|
|
|
|
|
} |
|
223
|
|
|
|
|
|
|
} |
|
224
|
|
|
|
|
|
|
##-- POST: multipart/form-data: part: anything other than 'form-data; name="PARAMNAME"' |
|
225
|
0
|
|
|
|
|
|
$addVars->({ POSTDATA => $part->content }); |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
elsif ($hreq->content_length > 0) { |
|
229
|
|
|
|
|
|
|
##-- POST: anything else: use POSTDATA |
|
230
|
0
|
|
|
|
|
|
$addVars->({ POSTDATA => $hreq->content }); |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
} |
|
233
|
0
|
|
|
|
|
|
$dbcgi->vars(\%vars); |
|
234
|
|
|
|
|
|
|
|
|
235
|
0
|
|
|
|
|
|
return $dbcgi; |
|
236
|
|
|
|
|
|
|
} |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
## \%vars = $dbcgi->vars() |
|
240
|
|
|
|
|
|
|
## \%vars = $dbcgi->vars(\%vars) |
|
241
|
|
|
|
|
|
|
## + get/set CGI variables, instantiating $dbcgi->{defaults} if present |
|
242
|
|
|
|
|
|
|
sub vars { |
|
243
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$vars) = @_; |
|
244
|
0
|
0
|
0
|
|
|
|
return $dbcgi->{vars} if (defined($dbcgi->{vars}) && !defined($vars)); |
|
245
|
0
|
0
|
0
|
|
|
|
$vars ||= $dbcgi->cgi('param') ? { %{$dbcgi->cgi('Vars')} } : {}; |
|
|
0
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
|
|
247
|
0
|
0
|
0
|
|
|
|
if (($dbcgi->{cgipkg}//'CGI') ne 'CGI' || defined($vars->{POSTDATA})) { |
|
|
|
|
0
|
|
|
|
|
|
248
|
|
|
|
|
|
|
##-- parse params from query string; required e.g. for CGI::Fast or non-form POST requests (which set POSTDATA) |
|
249
|
0
|
|
|
|
|
|
my $uri = URI->new($dbcgi->{request_uri}); |
|
250
|
0
|
|
|
|
|
|
my %urif = $uri->query_form(); |
|
251
|
0
|
|
|
|
|
|
@$vars{keys %urif} = values %urif; |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
|
|
254
|
0
|
0
|
|
|
|
|
foreach (grep {!exists($vars->{$_}) && defined($dbcgi->{defaults}{$_})} keys %{$dbcgi->{defaults}||{}}) { |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
##-- defaults |
|
256
|
0
|
|
|
|
|
|
$vars->{$_} = $dbcgi->{defaults}{$_} |
|
257
|
|
|
|
|
|
|
} |
|
258
|
0
|
|
|
|
|
|
my ($tmp); |
|
259
|
0
|
|
|
|
|
|
foreach (keys %$vars) { |
|
260
|
|
|
|
|
|
|
##-- decode (annoying temporary variable hack hopefully ensures that utf8 flag is set!) |
|
261
|
0
|
|
|
|
|
|
$tmp = $vars->{$_}; |
|
262
|
0
|
|
|
|
|
|
$tmp =~ s/\x{0}/ /g; |
|
263
|
0
|
0
|
0
|
|
|
|
if ($dbcgi->{charset} && !utf8::is_utf8($tmp) && !exists($dbcgi->{nodecode}{$_})) { |
|
|
|
|
0
|
|
|
|
|
|
264
|
0
|
|
|
|
|
|
$tmp = Encode::decode($dbcgi->{charset},$tmp); |
|
265
|
|
|
|
|
|
|
#$dbcgi->trace("decode var '$_':\n+ OLD=$vars->{$_}\n+ NEW=$tmp\n"); |
|
266
|
0
|
|
|
|
|
|
$vars->{$_} = $tmp; |
|
267
|
|
|
|
|
|
|
} |
|
268
|
|
|
|
|
|
|
} |
|
269
|
0
|
|
|
|
|
|
return $dbcgi->{vars} = $vars; |
|
270
|
|
|
|
|
|
|
} |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
##====================================================================== |
|
273
|
|
|
|
|
|
|
## config loading (optional) |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
## $dbcgi = $dbcgi->load_config($filename) |
|
276
|
|
|
|
|
|
|
## + clobers %$dbcgi keys from JSON filename |
|
277
|
|
|
|
|
|
|
sub load_config { |
|
278
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$file) = @_; |
|
279
|
0
|
0
|
|
|
|
|
open(RC,"<:raw",$file) |
|
280
|
|
|
|
|
|
|
or $dbcgi->logconfess("load_config(): failed for '$file': $!"); |
|
281
|
0
|
|
|
|
|
|
local $/ = undef; |
|
282
|
0
|
|
|
|
|
|
my $buf = ; |
|
283
|
0
|
0
|
|
|
|
|
close RC |
|
284
|
|
|
|
|
|
|
or $dbcgi->logconfess("load_config(): close failed for '$file': $!"); |
|
285
|
0
|
0
|
|
|
|
|
my $data = JSON::from_json($buf,{utf8=>1,relaxed=>1}) |
|
286
|
|
|
|
|
|
|
or $dbcgi->logconfess("load_config(): from_json() failed for config data from '$file': $!"); |
|
287
|
0
|
|
|
|
|
|
@$dbcgi{keys %$data} = values %$data; |
|
288
|
0
|
|
|
|
|
|
return $dbcgi; |
|
289
|
|
|
|
|
|
|
} |
|
290
|
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
##====================================================================== |
|
292
|
|
|
|
|
|
|
## Template Toolkit stuff |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
## $key = $dbcgi->ttk_key($key) |
|
295
|
|
|
|
|
|
|
## $key = $dbcgi->ttk_key() |
|
296
|
|
|
|
|
|
|
## + returns current template key |
|
297
|
|
|
|
|
|
|
## + default is basename($dbcgi->{prog}) without final extension |
|
298
|
|
|
|
|
|
|
sub ttk_key { |
|
299
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$key) = @_; |
|
300
|
0
|
0
|
|
|
|
|
($key=basename($dbcgi->{prog})) =~ s/\.[^\.]*\z// if (!$key); |
|
301
|
0
|
|
|
|
|
|
return $key; |
|
302
|
|
|
|
|
|
|
} |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
## @paths = $dbcgi->ttk_include() |
|
305
|
|
|
|
|
|
|
## $paths = $dbcgi->ttk_include() |
|
306
|
|
|
|
|
|
|
## + returns ttk search path @$dbcgi->{qw(ttk_dir ttk_sharedir)} |
|
307
|
|
|
|
|
|
|
## + in scalar context returns ":"-separated list |
|
308
|
|
|
|
|
|
|
sub ttk_include { |
|
309
|
0
|
|
|
0
|
1
|
|
my $dbcgi = shift; |
|
310
|
0
|
0
|
|
|
|
|
my @dirs = map {s/\/+\z//; abs_path($_)} grep {defined($_) && $_ ne ''} @$dbcgi{qw(ttk_dir ttk_sharedir)}; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
311
|
0
|
0
|
|
|
|
|
return wantarray ? @dirs : join(":",@dirs); |
|
312
|
|
|
|
|
|
|
} |
|
313
|
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
## $file = $dbcgi->ttk_file() |
|
315
|
|
|
|
|
|
|
## $file = $dbcgi->ttk_file($key) |
|
316
|
|
|
|
|
|
|
## + returns template filename for template key (basename) $key |
|
317
|
|
|
|
|
|
|
## + $key defaults to $dbcgi->{prog} without final extension |
|
318
|
|
|
|
|
|
|
## + searches in $dbcgi->{ttk_dir} or $dbcgi->{ttk_sharedir} |
|
319
|
|
|
|
|
|
|
sub ttk_file { |
|
320
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$key) = @_; |
|
321
|
0
|
|
0
|
|
|
|
(my $dir = $dbcgi->{ttk_dir} || '.') =~ s/\/+\z//; |
|
322
|
0
|
|
|
|
|
|
$key = $dbcgi->ttk_key($key); |
|
323
|
0
|
|
|
|
|
|
my $file = "$key.ttk"; |
|
324
|
0
|
|
|
|
|
|
my @dirs = $dbcgi->ttk_include(); |
|
325
|
0
|
|
|
|
|
|
foreach (@dirs) { |
|
326
|
0
|
0
|
|
|
|
|
return "$_/$file" if (-f "$_/$file"); |
|
327
|
|
|
|
|
|
|
} |
|
328
|
0
|
|
|
|
|
|
$dbcgi->logconfess("ttk_file(): could not find template file '$file' in ttk search path ".$dbcgi->ttk_include); |
|
329
|
|
|
|
|
|
|
} |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
## $t = $dbcgi->ttk_template(\%templateConfigArgs) |
|
332
|
|
|
|
|
|
|
## + returns a new Template object with default args set |
|
333
|
|
|
|
|
|
|
sub ttk_template { |
|
334
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$targs) = @_; |
|
335
|
|
|
|
|
|
|
my $t = Template->new( |
|
336
|
|
|
|
|
|
|
INTERPOLATE=>1, |
|
337
|
|
|
|
|
|
|
PRE_CHOMP=>0, |
|
338
|
|
|
|
|
|
|
POST_CHOMP=>1, |
|
339
|
|
|
|
|
|
|
EVAL_PERL=>1, |
|
340
|
|
|
|
|
|
|
ABSOLUTE=>1, |
|
341
|
|
|
|
|
|
|
RELATIVE=>1, |
|
342
|
|
|
|
|
|
|
INCLUDE_PATH =>scalar($dbcgi->ttk_include), |
|
343
|
0
|
0
|
|
|
|
|
%{$dbcgi->{ttk_config}||{}}, |
|
344
|
0
|
0
|
|
|
|
|
%{$targs||{}}, |
|
|
0
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
); |
|
346
|
0
|
|
|
|
|
|
return $t; |
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
## $data = $dbcgi->ttk_process($srcFile, \%templateVars, \%templateConfigArgs, \%templateProcessArgs) |
|
350
|
|
|
|
|
|
|
## $dbcgi = $dbcgi->ttk_process($srcFile, \%templateVars, \%templateConfigArgs, \%templateProcessArgs, $outfh) |
|
351
|
|
|
|
|
|
|
## $dbcgi = $dbcgi->ttk_process($srcFile, \%templateVars, \%templateConfigArgs, \%templateProcessArgs, \$outbuf) |
|
352
|
|
|
|
|
|
|
## + process a template $srcFile, returns generated $data |
|
353
|
|
|
|
|
|
|
sub ttk_process { |
|
354
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$src,$tvars,$targs,$pargs,$output) = @_; |
|
355
|
0
|
|
|
|
|
|
my $outbuf = ''; |
|
356
|
0
|
|
|
|
|
|
my $t = $dbcgi->ttk_template($targs); |
|
357
|
|
|
|
|
|
|
$t->process($src, |
|
358
|
0
|
0
|
|
|
|
|
{package=>$dbcgi->{ttk_package}, version=>$VERSION, ENV=>{%ENV}, %{$dbcgi->{ttk_vars}||{}}, cdb=>$dbcgi, %{$tvars||{}}}, |
|
|
0
|
0
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
(defined($output) ? $output : \$outbuf), |
|
360
|
0
|
0
|
|
|
|
|
%{$dbcgi->{ttk_process}||{}}, |
|
361
|
0
|
0
|
|
|
|
|
%{$pargs||{}}, |
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
) |
|
363
|
|
|
|
|
|
|
or $dbcgi->logconfess("ttk_process(): template error: ".$t->error); |
|
364
|
0
|
0
|
|
|
|
|
return defined($output) ? $dbcgi : $outbuf; |
|
365
|
|
|
|
|
|
|
} |
|
366
|
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
##====================================================================== |
|
368
|
|
|
|
|
|
|
## CGI stuff: generic |
|
369
|
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
## @error = $dbcgi->htmlerror($status,@message) |
|
371
|
|
|
|
|
|
|
## + returns a print()-able HTML error |
|
372
|
|
|
|
|
|
|
sub htmlerror { |
|
373
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$status,@msg) = @_; |
|
374
|
0
|
0
|
|
|
|
|
$status = 500 if (!defined($status)); ##-- RC_INTERNAL_SERVER_ERROR |
|
375
|
0
|
|
|
|
|
|
my $title = 'Error: '.$status.' '.status_message($status); |
|
376
|
0
|
|
|
|
|
|
charset($dbcgi->{charset}); |
|
377
|
0
|
|
0
|
|
|
|
my $msg = join(($,//''), @msg); |
|
378
|
0
|
|
|
|
|
|
$msg =~ s/\beval\s*\'(?:\\.|[^\'])*\'/eval '...'/sg; ##-- suppress long eval '...' messsages |
|
379
|
|
|
|
|
|
|
return |
|
380
|
0
|
|
|
|
|
|
(header(-status=>$status), |
|
381
|
|
|
|
|
|
|
start_html($title), |
|
382
|
|
|
|
|
|
|
h1($title), |
|
383
|
|
|
|
|
|
|
pre("\n",escapeHTML($msg),"\n"), |
|
384
|
|
|
|
|
|
|
end_html, |
|
385
|
|
|
|
|
|
|
); |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
## @whatever = $dbcgi->cgi($method, @args) |
|
389
|
|
|
|
|
|
|
## + call a method from the CGI package $dbcgi->{cgipkg}->can($method) |
|
390
|
|
|
|
|
|
|
sub cgi { |
|
391
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$method)=splice(@_,0,2); |
|
392
|
0
|
0
|
|
|
|
|
CGI::charset($dbcgi->{charset}) if ($dbcgi->{charset}); |
|
393
|
0
|
|
|
|
|
|
my ($sub); |
|
394
|
0
|
0
|
|
|
|
|
if (ref($method)) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
395
|
0
|
|
|
|
|
|
return $method->(@_); |
|
396
|
|
|
|
|
|
|
} |
|
397
|
|
|
|
|
|
|
elsif ($sub=$dbcgi->{cgipkg}->can($method)) { |
|
398
|
0
|
|
|
|
|
|
return $sub->(@_); |
|
399
|
|
|
|
|
|
|
} |
|
400
|
|
|
|
|
|
|
elsif ($sub=CGI->can($method)) { |
|
401
|
0
|
|
|
|
|
|
return $sub->(@_); |
|
402
|
|
|
|
|
|
|
} |
|
403
|
0
|
|
|
|
|
|
$dbcgi->logconfess("cgi(): unknown method '$method' for cgipkg='$dbcgi->{cgipkg}'"); |
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
## undef = $dbcgi->cgi_main() |
|
407
|
|
|
|
|
|
|
## undef = $dbcgi->cgi_main($ttk_key) |
|
408
|
|
|
|
|
|
|
## + wraps a template-instantiation for $ttk_key, by default basename($0) |
|
409
|
|
|
|
|
|
|
sub cgi_main { |
|
410
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$key) = @_; |
|
411
|
0
|
|
|
|
|
|
my @content; |
|
412
|
0
|
|
|
|
|
|
my $israw = $dbcgi->{ttk_rawkeys}{$dbcgi->ttk_key($key)}; |
|
413
|
0
|
|
|
|
|
|
eval { |
|
414
|
0
|
0
|
|
|
|
|
@content = $dbcgi->ttk_process($dbcgi->ttk_file($key), $dbcgi->vars, ($israw ? {ENCODING=>undef} : undef), ($israw ? {binmode=>':raw'} : undef)); |
|
|
|
0
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
}; |
|
416
|
0
|
0
|
0
|
|
|
|
if ($@) { |
|
|
|
0
|
|
|
|
|
|
|
417
|
0
|
|
|
|
|
|
$israw = 0; |
|
418
|
0
|
|
|
|
|
|
@content = $dbcgi->htmlerror(undef, $@); |
|
419
|
|
|
|
|
|
|
} |
|
420
|
|
|
|
|
|
|
elsif (!@content || !defined($content[0])) { |
|
421
|
0
|
|
|
|
|
|
$israw = 0; |
|
422
|
0
|
|
|
|
|
|
@content = $dbcgi->htmlerror(undef, "template '$key' returned no content"); |
|
423
|
|
|
|
|
|
|
} |
|
424
|
|
|
|
|
|
|
|
|
425
|
0
|
0
|
|
|
|
|
if ($dbcgi->{charset}) { |
|
426
|
0
|
|
|
|
|
|
charset($dbcgi->{charset}); |
|
427
|
0
|
0
|
|
|
|
|
binmode(\*STDOUT, ($israw ? ":raw" : ":encoding($dbcgi->{charset})")); |
|
428
|
|
|
|
|
|
|
} |
|
429
|
0
|
|
|
|
|
|
print @content; |
|
430
|
|
|
|
|
|
|
} |
|
431
|
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
## undef = $dbcgi->fcgi_main() |
|
433
|
|
|
|
|
|
|
## undef = $dbcgi->fcgi_main($ttk_key) |
|
434
|
|
|
|
|
|
|
## + wraps a template-instantiation for $ttk_key, by default basename($0) |
|
435
|
|
|
|
|
|
|
sub fcgi_main { |
|
436
|
0
|
|
|
0
|
1
|
|
my ($dbcgi,$key) = @_; |
|
437
|
0
|
|
|
|
|
|
require CGI::Fast; |
|
438
|
0
|
|
|
|
|
|
CGI::Fast->import(':standard'); |
|
439
|
0
|
|
|
|
|
|
$dbcgi->{cgipkg} = 'CGI::Fast'; |
|
440
|
0
|
|
|
|
|
|
while (CGI::Fast->new()) { |
|
441
|
0
|
|
|
|
|
|
$dbcgi->_getenv(); |
|
442
|
0
|
|
|
|
|
|
$dbcgi->cgi_main($key); |
|
443
|
0
|
|
|
|
|
|
$dbcgi->_reset(); |
|
444
|
|
|
|
|
|
|
} |
|
445
|
|
|
|
|
|
|
} |
|
446
|
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
##====================================================================== |
|
448
|
|
|
|
|
|
|
## Template stuff: useful aliases |
|
449
|
|
|
|
|
|
|
|
|
450
|
0
|
|
|
0
|
1
|
|
sub remoteAddr { return $_[0]{remote_addr}; } |
|
451
|
0
|
|
|
0
|
1
|
|
sub remoteUser { return $_[0]{remote_user}; } |
|
452
|
0
|
|
|
0
|
1
|
|
sub requestMethod { return $_[0]{request_method}; } |
|
453
|
0
|
|
|
0
|
1
|
|
sub requestUri { return $_[0]{request_uri}; } |
|
454
|
0
|
|
|
0
|
1
|
|
sub requestQuery { return $_[0]{request_query}; } |
|
455
|
0
|
|
|
0
|
1
|
|
sub httpReferer { return $_[0]{http_referer}; } |
|
456
|
0
|
|
|
0
|
1
|
|
sub httpHost { return $_[0]{http_host}; } |
|
457
|
0
|
|
|
0
|
1
|
|
sub serverAddr { return $_[0]{server_addr}; } |
|
458
|
|
|
|
|
|
|
sub serverPort { |
|
459
|
0
|
0
|
|
0
|
1
|
|
return $_[0]{server_port} if ($_[0]{server_port}); |
|
460
|
0
|
|
|
|
|
|
my $host = $_[0]->httpHost; |
|
461
|
0
|
0
|
0
|
|
|
|
return $1 if ($host && $host =~ /:([0-9]+)$/); |
|
462
|
0
|
0
|
|
|
|
|
return $ENV{HTTPS} ? 443 : 80; ##-- guess port from scheme |
|
463
|
|
|
|
|
|
|
} |
|
464
|
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
## $uri = $dbcgi->uri() |
|
467
|
|
|
|
|
|
|
## $uri = $dbcgi->uri($uri) |
|
468
|
|
|
|
|
|
|
sub uri { |
|
469
|
0
|
0
|
|
0
|
1
|
|
return URI->new($_[1]) if (defined $_[1]); |
|
470
|
0
|
|
|
|
|
|
my $dbcgi = shift; |
|
471
|
0
|
|
0
|
|
|
|
my $host = $dbcgi->httpHost // ''; |
|
472
|
0
|
|
|
|
|
|
my $port = $dbcgi->serverPort; |
|
473
|
0
|
0
|
|
|
|
|
my $scheme = ($ENV{HTTPS} ? 'https' : 'http'); |
|
474
|
0
|
0
|
0
|
|
|
|
return URI->new( |
|
|
|
0
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
#($host ? "http://$host" : "file://") |
|
476
|
|
|
|
|
|
|
($host ? "${scheme}://$host" : "file://") ##-- guess scheme from HTTPS environment variable |
|
477
|
|
|
|
|
|
|
.( ($host && $host =~ /:[0-9]+$/) || $port==($scheme eq 'https' ? 443 : 80) ? '' : ":$port" ) |
|
478
|
|
|
|
|
|
|
.$dbcgi->requestUri |
|
479
|
|
|
|
|
|
|
); |
|
480
|
|
|
|
|
|
|
} |
|
481
|
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
## $scheme = $dbcgi->uriScheme($uri?) |
|
483
|
|
|
|
|
|
|
## $opaque = $dbcgi->uriOpaque($uri?) |
|
484
|
|
|
|
|
|
|
## $path = $dbcgi->uriPath($uri?) |
|
485
|
|
|
|
|
|
|
## $frag = $dbcgi->uriFragment($uri?) |
|
486
|
|
|
|
|
|
|
## $canon = $dbcgi->uriCanonical($uri?) |
|
487
|
|
|
|
|
|
|
## $abs = $dbcgi->uriAbs($uri?); |
|
488
|
0
|
|
|
0
|
1
|
|
sub uriScheme { $_[0]->uri($_[1])->scheme; } |
|
489
|
0
|
|
|
0
|
1
|
|
sub uriPath { $_[0]->uri($_[1])->path; } |
|
490
|
0
|
|
|
0
|
1
|
|
sub uriFragment { $_[0]->uri($_[1])->fragment; } |
|
491
|
0
|
|
|
0
|
1
|
|
sub uriCanonical { $_[0]->uri($_[1])->canonical->as_string; } |
|
492
|
0
|
|
|
0
|
1
|
|
sub uriAbs { $_[0]->uri($_[1])->abs->as_string; } |
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
## $dir = $dbcgi->uriDir($uri?) |
|
495
|
|
|
|
|
|
|
## + returns URI up to but not including query or fragment, truncating any trailing slashes |
|
496
|
|
|
|
|
|
|
sub uriDir { |
|
497
|
0
|
|
|
0
|
1
|
|
my $uri = $_[0]->uri($_[1])->as_string; |
|
498
|
0
|
|
|
|
|
|
$uri =~ s{[?#].*$}{}; |
|
499
|
0
|
|
|
|
|
|
$uri =~ s{/+[^/]*$}{}; |
|
500
|
0
|
|
|
|
|
|
return $uri; |
|
501
|
|
|
|
|
|
|
} |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
## $auth = $dbcgi->uriAuthority($uri?) |
|
504
|
|
|
|
|
|
|
## $pquery = $dbcgi->uriPathQuery($uri?) |
|
505
|
|
|
|
|
|
|
## \@segs = $dbcgi->uriPathSegments($uri?) |
|
506
|
|
|
|
|
|
|
## $query = $dbcgi->uriQuery($uri?) |
|
507
|
|
|
|
|
|
|
## \%form = $dbcgi->uriQueryForm($uri?) |
|
508
|
|
|
|
|
|
|
## \@kws = $dbcgi->uriQueryKeywords($uri?) |
|
509
|
0
|
|
|
0
|
1
|
|
sub uriAuthority { $_[0]->uri($_[1])->authority; } |
|
510
|
0
|
|
|
0
|
1
|
|
sub uriPathQuery { $_[0]->uri($_[1])->path_query; } |
|
511
|
0
|
|
|
0
|
1
|
|
sub uriPathSegments { [$_[0]->uri($_[1])->path_segments]; } |
|
512
|
0
|
|
|
0
|
1
|
|
sub uriQuery { $_[0]->uri($_[1])->query; } |
|
513
|
0
|
|
|
0
|
1
|
|
sub uriQueryForm { {$_[0]->uri($_[1])->query_form}; } |
|
|
0
|
|
|
|
|
|
|
|
514
|
0
|
|
|
0
|
1
|
|
sub uriQueryKeywords { [$_[0]->uri($_[1])->query_keywords]; } |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
## $userinfo = $dbcgi->uriUserInfo($uri?) |
|
517
|
|
|
|
|
|
|
## $host = $dbcgi->uriHost($uri?) |
|
518
|
|
|
|
|
|
|
## $port = $dbcgi->uriPort($uri?) |
|
519
|
0
|
|
|
0
|
1
|
|
sub userinfo { $_[0]->uri($_[1])->userinfo; } |
|
520
|
0
|
|
|
0
|
1
|
|
sub uriHost { $_[0]->uri($_[1])->host; } |
|
521
|
0
|
|
|
0
|
1
|
|
sub uriPort { $_[0]->uri($_[1])->port; } |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
## $uristr = quri($base, \%form) |
|
524
|
|
|
|
|
|
|
sub quri { |
|
525
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
526
|
0
|
|
|
|
|
|
my ($base,$form)=@_; |
|
527
|
0
|
|
|
|
|
|
my $uri=URI->new($base); |
|
528
|
0
|
0
|
|
|
|
|
$uri->query_form($uri->query_form, map {utf8::is_utf8($_) ? Encode::encode_utf8($_) : $_} %{$form||{}}); |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
529
|
0
|
|
|
|
|
|
return $uri->as_string; |
|
530
|
|
|
|
|
|
|
} |
|
531
|
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
## $urisub = uuri($base, \%form) |
|
533
|
|
|
|
|
|
|
## $uristr = $urisub->(\%form) |
|
534
|
|
|
|
|
|
|
sub uuri { |
|
535
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
536
|
0
|
|
|
|
|
|
my $qbase = quri(@_); |
|
537
|
0
|
|
|
0
|
|
|
return sub { quri($qbase,@_); }; |
|
|
0
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
} |
|
539
|
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
## $sqstring = sqstring($str) |
|
541
|
|
|
|
|
|
|
sub sqstring { |
|
542
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
543
|
0
|
|
|
|
|
|
(my $s=shift) =~ s/([\\\'])/\\$1/g; "'$s'" |
|
|
0
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
} |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
## $str = sprintf_(...) |
|
547
|
|
|
|
|
|
|
sub sprintf_ { |
|
548
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
549
|
0
|
|
|
|
|
|
return CORE::sprintf($_[0],@_[1..$#_]); |
|
550
|
|
|
|
|
|
|
} |
|
551
|
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
## $mtime = $dbcgi->mtime($filename) |
|
553
|
|
|
|
|
|
|
sub mtime { |
|
554
|
0
|
|
|
0
|
1
|
|
my $dbcgi = shift; |
|
555
|
0
|
|
|
|
|
|
my $file = shift; |
|
556
|
0
|
0
|
|
|
|
|
$file =~ s/^.*?=(\w+).*$/$1/ if ($file =~ /^dbi:/); ##-- trim dsns |
|
557
|
0
|
|
|
|
|
|
my @stat = stat($file); |
|
558
|
0
|
|
|
|
|
|
return $stat[9]; |
|
559
|
|
|
|
|
|
|
} |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
## $str = $dbcgi->timestamp() |
|
562
|
|
|
|
|
|
|
## + gets localtime timestamp |
|
563
|
|
|
|
|
|
|
sub timestamp { |
|
564
|
|
|
|
|
|
|
#my $dbcgi = shift; |
|
565
|
0
|
|
|
0
|
1
|
|
return POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime()); |
|
566
|
|
|
|
|
|
|
} |
|
567
|
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
## $json_str = PACKAGE->to_json($data) |
|
569
|
|
|
|
|
|
|
## $json_str = PACKAGE::to_json($data) |
|
570
|
|
|
|
|
|
|
## $json_str = PACKAGE->to_json($data,\%opts) |
|
571
|
|
|
|
|
|
|
## $json_str = PACKAGE::to_json($data,\%opts) |
|
572
|
|
|
|
|
|
|
sub to_json { |
|
573
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
574
|
0
|
0
|
|
|
|
|
return JSON::to_json($_[0]) if (@_==1); |
|
575
|
0
|
|
|
|
|
|
return JSON::to_json($_[0],$_[1]); |
|
576
|
|
|
|
|
|
|
} |
|
577
|
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
## $json_str = PACKAGE->from_json($data) |
|
579
|
|
|
|
|
|
|
## $json_str = PACKAGE::from_json($data) |
|
580
|
|
|
|
|
|
|
sub from_json { |
|
581
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
582
|
0
|
|
|
|
|
|
return JSON::from_json(@_); |
|
583
|
|
|
|
|
|
|
} |
|
584
|
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
## \@timeofday = PACKAGE->gettimeofday() |
|
586
|
|
|
|
|
|
|
## \@timeofday = PACKAGE::gettimeofday() |
|
587
|
|
|
|
|
|
|
sub gettimeofday { |
|
588
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
589
|
0
|
|
|
|
|
|
return [Time::HiRes::gettimeofday()]; |
|
590
|
|
|
|
|
|
|
} |
|
591
|
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
## $secs = PACKAGE->tv_interval($t0,$t1) |
|
593
|
|
|
|
|
|
|
## $secs = PACKAGE::tv_interval($t0,$t1) |
|
594
|
|
|
|
|
|
|
sub tv_interval { |
|
595
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
596
|
0
|
|
|
|
|
|
return Time::HiRes::tv_interval(@_); |
|
597
|
|
|
|
|
|
|
} |
|
598
|
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
## \@timeofday = PACKAGE->t_start() |
|
600
|
|
|
|
|
|
|
## \@timeofday = PACKAGE->t_start() |
|
601
|
|
|
|
|
|
|
## + sets package variable $t_started |
|
602
|
|
|
|
|
|
|
our $t_started = [Time::HiRes::gettimeofday]; |
|
603
|
|
|
|
|
|
|
sub t_start { |
|
604
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
605
|
0
|
|
|
|
|
|
$t_started = [Time::HiRes::gettimeofday]; |
|
606
|
|
|
|
|
|
|
} |
|
607
|
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
## $secs = PACKAGE->t_elapsed() |
|
609
|
|
|
|
|
|
|
## $secs = PACKAGE->t_elapsed($t1) |
|
610
|
|
|
|
|
|
|
## $secs = PACKAGE->t_elapsed($t0,$t1) |
|
611
|
|
|
|
|
|
|
## $secs = PACKAGE::t_elapsed() |
|
612
|
|
|
|
|
|
|
## $secs = PACKAGE::t_elapsed($t1) |
|
613
|
|
|
|
|
|
|
## $secs = PACKAGE::t_elapsed($t0,$t1) |
|
614
|
|
|
|
|
|
|
sub t_elapsed { |
|
615
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
616
|
0
|
|
|
|
|
|
my ($t0,$t1) = @_; |
|
617
|
0
|
0
|
|
|
|
|
return tv_interval($t_started,[Time::HiRes::gettimeofday]) if (!@_); |
|
618
|
0
|
0
|
|
|
|
|
return tv_interval($t_started,$_[0]) if (@_==1); |
|
619
|
0
|
|
|
|
|
|
return tv_interval($_[0],$_[1]); |
|
620
|
|
|
|
|
|
|
} |
|
621
|
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
## $enc = PACKAGE->encode_utf8($str, $force=0) |
|
623
|
|
|
|
|
|
|
## $enc = PACKAGE::encode_utf8($str, $force=0) |
|
624
|
|
|
|
|
|
|
## + encodes only if $force is true or if not already flagged as a byte-string |
|
625
|
|
|
|
|
|
|
sub encode_utf8 { |
|
626
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
627
|
0
|
0
|
0
|
|
|
|
return $_[0] if (!$_[1] && !utf8::is_utf8($_[0])); |
|
628
|
0
|
|
|
|
|
|
return Encode::encode_utf8($_[0]); |
|
629
|
|
|
|
|
|
|
} |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
## $enc = PACKAGE->decode_utf8($str, $force=0) |
|
632
|
|
|
|
|
|
|
## $enc = PACKAGE::decode_utf8($str, $force=0) |
|
633
|
|
|
|
|
|
|
## + decodes only if $force is true or if not flagged as a byte-string |
|
634
|
|
|
|
|
|
|
sub decode_utf8 { |
|
635
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
|
636
|
0
|
0
|
0
|
|
|
|
return $_[0] if (!$_[1] && utf8::is_utf8($_[0])); |
|
637
|
0
|
|
|
|
|
|
return Encode::decode_utf8($_[0]); |
|
638
|
|
|
|
|
|
|
} |
|
639
|
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
1; ##-- be happy |
|
641
|
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
__END__ |