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
|
|
53942
|
use DiaColloDB; |
|
1
|
|
|
|
|
317990
|
|
|
1
|
|
|
|
|
41
|
|
10
|
1
|
|
|
1
|
|
14
|
use DiaColloDB::Logger; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
18
|
|
11
|
1
|
|
|
1
|
|
869
|
use CGI qw(:standard :cgi-lib); |
|
1
|
|
|
|
|
22828
|
|
|
1
|
|
|
|
|
6
|
|
12
|
1
|
|
|
1
|
|
3700
|
use URI; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
24
|
|
13
|
1
|
|
|
1
|
|
4
|
use URI::Escape qw(uri_escape_utf8); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
69
|
|
14
|
1
|
|
|
1
|
|
5
|
use HTTP::Status; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
213
|
|
15
|
1
|
|
|
1
|
|
6
|
use Encode qw(); #qw(encode decode encode_utf8 decode_utf8); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
18
|
|
16
|
1
|
|
|
1
|
|
5
|
use File::Basename qw(basename dirname); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
38
|
|
17
|
1
|
|
|
1
|
|
557
|
use File::ShareDir qw(); ##-- for shared template data |
|
1
|
|
|
|
|
4657
|
|
|
1
|
|
|
|
|
23
|
|
18
|
1
|
|
|
1
|
|
7
|
use Cwd qw(getcwd abs_path); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
49
|
|
19
|
|
|
|
|
|
|
#use LWP::UserAgent; |
20
|
1
|
|
|
1
|
|
435
|
use Template; |
|
1
|
|
|
|
|
13942
|
|
|
1
|
|
|
|
|
31
|
|
21
|
1
|
|
|
1
|
|
7
|
use JSON qw(); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
23
|
|
22
|
1
|
|
|
1
|
|
4
|
use Time::HiRes qw(); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
16
|
|
23
|
1
|
|
|
1
|
|
8
|
use utf8; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
24
|
1
|
|
|
1
|
|
22
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
49
|
|
25
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
BEGIN { |
28
|
|
|
|
|
|
|
#binmode(STDIN, ':utf8'); |
29
|
|
|
|
|
|
|
#binmode(STDOUT,':utf8'); |
30
|
1
|
|
|
1
|
|
3227
|
binmode(STDERR,':utf8'); |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
*isa = \&UNIVERSAL::isa; |
34
|
|
|
|
|
|
|
*can = \&UNIVERSAL::can; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
##====================================================================== |
37
|
|
|
|
|
|
|
## globals |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
our $VERSION = "0.02.002"; |
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
|
0
|
|
0
|
0
|
1
|
|
sub serverPort { return $_[0]{server_port} || ($ENV{HTTPS} ? 443 : 80); } |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
## $uri = $dbcgi->uri() |
461
|
|
|
|
|
|
|
## $uri = $dbcgi->uri($uri) |
462
|
|
|
|
|
|
|
sub uri { |
463
|
0
|
0
|
|
0
|
1
|
|
return URI->new($_[1]) if (defined $_[1]); |
464
|
0
|
|
|
|
|
|
my $dbcgi = shift; |
465
|
0
|
|
0
|
|
|
|
my $host = $dbcgi->httpHost // ''; |
466
|
0
|
|
|
|
|
|
my $port = $dbcgi->serverPort; |
467
|
0
|
0
|
|
|
|
|
my $scheme = ($ENV{HTTPS} ? 'https' : 'http'); |
468
|
0
|
0
|
|
|
|
|
return URI->new( |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
469
|
|
|
|
|
|
|
#($host ? "http://$host" : "file://") |
470
|
|
|
|
|
|
|
($host ? "${scheme}://$host" : "file://") ##-- guess scheme from HTTPS environment variable |
471
|
|
|
|
|
|
|
.($port==($scheme eq 'https' ? 443 : 80) ? '' : ":$port") |
472
|
|
|
|
|
|
|
.$dbcgi->requestUri |
473
|
|
|
|
|
|
|
); |
474
|
|
|
|
|
|
|
} |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
## $scheme = $dbcgi->uriScheme($uri?) |
477
|
|
|
|
|
|
|
## $opaque = $dbcgi->uriOpaque($uri?) |
478
|
|
|
|
|
|
|
## $path = $dbcgi->uriPath($uri?) |
479
|
|
|
|
|
|
|
## $frag = $dbcgi->uriFragment($uri?) |
480
|
|
|
|
|
|
|
## $canon = $dbcgi->uriCanonical($uri?) |
481
|
|
|
|
|
|
|
## $abs = $dbcgi->uriAbs($uri?); |
482
|
0
|
|
|
0
|
1
|
|
sub uriScheme { $_[0]->uri($_[1])->scheme; } |
483
|
0
|
|
|
0
|
1
|
|
sub uriPath { $_[0]->uri($_[1])->path; } |
484
|
0
|
|
|
0
|
1
|
|
sub uriFragment { $_[0]->uri($_[1])->fragment; } |
485
|
0
|
|
|
0
|
1
|
|
sub uriCanonical { $_[0]->uri($_[1])->canonical->as_string; } |
486
|
0
|
|
|
0
|
1
|
|
sub uriAbs { $_[0]->uri($_[1])->abs->as_string; } |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
## $dir = $dbcgi->uriDir($uri?) |
489
|
|
|
|
|
|
|
sub uriDir { |
490
|
0
|
|
|
0
|
1
|
|
my $uri = $_[0]->uri($_[1])->as_string; |
491
|
0
|
|
|
|
|
|
$uri =~ s{[?#].*$}{}; |
492
|
0
|
|
|
|
|
|
$uri =~ s{/+[^/]*$}{}; |
493
|
0
|
|
|
|
|
|
return $uri; |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
## $auth = $dbcgi->uriAuthority($uri?) |
497
|
|
|
|
|
|
|
## $pquery = $dbcgi->uriPathQuery($uri?) |
498
|
|
|
|
|
|
|
## \@segs = $dbcgi->uriPathSegments($uri?) |
499
|
|
|
|
|
|
|
## $query = $dbcgi->uriQuery($uri?) |
500
|
|
|
|
|
|
|
## \%form = $dbcgi->uriQueryForm($uri?) |
501
|
|
|
|
|
|
|
## \@kws = $dbcgi->uriQueryKeywords($uri?) |
502
|
0
|
|
|
0
|
1
|
|
sub uriAuthority { $_[0]->uri($_[1])->authority; } |
503
|
0
|
|
|
0
|
1
|
|
sub uriPathQuery { $_[0]->uri($_[1])->path_query; } |
504
|
0
|
|
|
0
|
1
|
|
sub uriPathSegments { [$_[0]->uri($_[1])->path_segments]; } |
505
|
0
|
|
|
0
|
1
|
|
sub uriQuery { $_[0]->uri($_[1])->query; } |
506
|
0
|
|
|
0
|
1
|
|
sub uriQueryForm { {$_[0]->uri($_[1])->query_form}; } |
|
0
|
|
|
|
|
|
|
507
|
0
|
|
|
0
|
1
|
|
sub uriQueryKeywords { [$_[0]->uri($_[1])->query_keywords]; } |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
## $userinfo = $dbcgi->uriUserInfo($uri?) |
510
|
|
|
|
|
|
|
## $host = $dbcgi->uriHost($uri?) |
511
|
|
|
|
|
|
|
## $port = $dbcgi->uriPort($uri?) |
512
|
0
|
|
|
0
|
1
|
|
sub userinfo { $_[0]->uri($_[1])->userinfo; } |
513
|
0
|
|
|
0
|
1
|
|
sub uriHost { $_[0]->uri($_[1])->host; } |
514
|
0
|
|
|
0
|
1
|
|
sub uriPort { $_[0]->uri($_[1])->port; } |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
## $uristr = quri($base, \%form) |
517
|
|
|
|
|
|
|
sub quri { |
518
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
519
|
0
|
|
|
|
|
|
my ($base,$form)=@_; |
520
|
0
|
|
|
|
|
|
my $uri=URI->new($base); |
521
|
0
|
0
|
|
|
|
|
$uri->query_form($uri->query_form, map {utf8::is_utf8($_) ? Encode::encode_utf8($_) : $_} %{$form||{}}); |
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
522
|
0
|
|
|
|
|
|
return $uri->as_string; |
523
|
|
|
|
|
|
|
} |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
## $urisub = uuri($base, \%form) |
526
|
|
|
|
|
|
|
## $uristr = $urisub->(\%form) |
527
|
|
|
|
|
|
|
sub uuri { |
528
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
529
|
0
|
|
|
|
|
|
my $qbase = quri(@_); |
530
|
0
|
|
|
0
|
|
|
return sub { quri($qbase,@_); }; |
|
0
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
} |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
## $sqstring = sqstring($str) |
534
|
|
|
|
|
|
|
sub sqstring { |
535
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
536
|
0
|
|
|
|
|
|
(my $s=shift) =~ s/([\\\'])/\\$1/g; "'$s'" |
|
0
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
## $str = sprintf_(...) |
540
|
|
|
|
|
|
|
sub sprintf_ { |
541
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
542
|
0
|
|
|
|
|
|
return CORE::sprintf($_[0],@_[1..$#_]); |
543
|
|
|
|
|
|
|
} |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
## $mtime = $dbcgi->mtime($filename) |
546
|
|
|
|
|
|
|
sub mtime { |
547
|
0
|
|
|
0
|
1
|
|
my $dbcgi = shift; |
548
|
0
|
|
|
|
|
|
my $file = shift; |
549
|
0
|
0
|
|
|
|
|
$file =~ s/^.*?=(\w+).*$/$1/ if ($file =~ /^dbi:/); ##-- trim dsns |
550
|
0
|
|
|
|
|
|
my @stat = stat($file); |
551
|
0
|
|
|
|
|
|
return $stat[9]; |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
## $str = $dbcgi->timestamp() |
555
|
|
|
|
|
|
|
## + gets localtime timestamp |
556
|
|
|
|
|
|
|
sub timestamp { |
557
|
|
|
|
|
|
|
#my $dbcgi = shift; |
558
|
0
|
|
|
0
|
1
|
|
return POSIX::strftime('%Y-%m-%d %H:%M:%S', localtime()); |
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
## $json_str = PACKAGE->to_json($data) |
562
|
|
|
|
|
|
|
## $json_str = PACKAGE::to_json($data) |
563
|
|
|
|
|
|
|
## $json_str = PACKAGE->to_json($data,\%opts) |
564
|
|
|
|
|
|
|
## $json_str = PACKAGE::to_json($data,\%opts) |
565
|
|
|
|
|
|
|
sub to_json { |
566
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
567
|
0
|
0
|
|
|
|
|
return JSON::to_json($_[0]) if (@_==1); |
568
|
0
|
|
|
|
|
|
return JSON::to_json($_[0],$_[1]); |
569
|
|
|
|
|
|
|
} |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
## $json_str = PACKAGE->from_json($data) |
572
|
|
|
|
|
|
|
## $json_str = PACKAGE::from_json($data) |
573
|
|
|
|
|
|
|
sub from_json { |
574
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
575
|
0
|
|
|
|
|
|
return JSON::from_json(@_); |
576
|
|
|
|
|
|
|
} |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
## \@timeofday = PACKAGE->gettimeofday() |
579
|
|
|
|
|
|
|
## \@timeofday = PACKAGE::gettimeofday() |
580
|
|
|
|
|
|
|
sub gettimeofday { |
581
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
582
|
0
|
|
|
|
|
|
return [Time::HiRes::gettimeofday()]; |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
## $secs = PACKAGE->tv_interval($t0,$t1) |
586
|
|
|
|
|
|
|
## $secs = PACKAGE::tv_interval($t0,$t1) |
587
|
|
|
|
|
|
|
sub tv_interval { |
588
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
589
|
0
|
|
|
|
|
|
return Time::HiRes::tv_interval(@_); |
590
|
|
|
|
|
|
|
} |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
## \@timeofday = PACKAGE->t_start() |
593
|
|
|
|
|
|
|
## \@timeofday = PACKAGE->t_start() |
594
|
|
|
|
|
|
|
## + sets package variable $t_started |
595
|
|
|
|
|
|
|
our $t_started = [Time::HiRes::gettimeofday]; |
596
|
|
|
|
|
|
|
sub t_start { |
597
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
598
|
0
|
|
|
|
|
|
$t_started = [Time::HiRes::gettimeofday]; |
599
|
|
|
|
|
|
|
} |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
## $secs = PACKAGE->t_elapsed() |
602
|
|
|
|
|
|
|
## $secs = PACKAGE->t_elapsed($t1) |
603
|
|
|
|
|
|
|
## $secs = PACKAGE->t_elapsed($t0,$t1) |
604
|
|
|
|
|
|
|
## $secs = PACKAGE::t_elapsed() |
605
|
|
|
|
|
|
|
## $secs = PACKAGE::t_elapsed($t1) |
606
|
|
|
|
|
|
|
## $secs = PACKAGE::t_elapsed($t0,$t1) |
607
|
|
|
|
|
|
|
sub t_elapsed { |
608
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
609
|
0
|
|
|
|
|
|
my ($t0,$t1) = @_; |
610
|
0
|
0
|
|
|
|
|
return tv_interval($t_started,[Time::HiRes::gettimeofday]) if (!@_); |
611
|
0
|
0
|
|
|
|
|
return tv_interval($t_started,$_[0]) if (@_==1); |
612
|
0
|
|
|
|
|
|
return tv_interval($_[0],$_[1]); |
613
|
|
|
|
|
|
|
} |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
## $enc = PACKAGE->encode_utf8($str, $force=0) |
616
|
|
|
|
|
|
|
## $enc = PACKAGE::encode_utf8($str, $force=0) |
617
|
|
|
|
|
|
|
## + encodes only if $force is true or if not already flagged as a byte-string |
618
|
|
|
|
|
|
|
sub encode_utf8 { |
619
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
620
|
0
|
0
|
0
|
|
|
|
return $_[0] if (!$_[1] && !utf8::is_utf8($_[0])); |
621
|
0
|
|
|
|
|
|
return Encode::encode_utf8($_[0]); |
622
|
|
|
|
|
|
|
} |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
## $enc = PACKAGE->decode_utf8($str, $force=0) |
625
|
|
|
|
|
|
|
## $enc = PACKAGE::decode_utf8($str, $force=0) |
626
|
|
|
|
|
|
|
## + decodes only if $force is true or if not flagged as a byte-string |
627
|
|
|
|
|
|
|
sub decode_utf8 { |
628
|
0
|
0
|
|
0
|
1
|
|
shift if (isa($_[0],__PACKAGE__)); |
629
|
0
|
0
|
0
|
|
|
|
return $_[0] if (!$_[1] && utf8::is_utf8($_[0])); |
630
|
0
|
|
|
|
|
|
return Encode::decode_utf8($_[0]); |
631
|
|
|
|
|
|
|
} |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
1; ##-- be happy |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
__END__ |