line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# iNcom.pm - Main module of the iNcom package. |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# This file is part of Apache::iNcom |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# Author: Francis J. Lacoste |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# Copyright (C) 1999 Francis J. Lacoste, iNsu Innovations |
9
|
|
|
|
|
|
|
# |
10
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify |
11
|
|
|
|
|
|
|
# it under the terms of the GNU General Public License as published by |
12
|
|
|
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or |
13
|
|
|
|
|
|
|
# (at your option) any later version. |
14
|
|
|
|
|
|
|
# |
15
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful, |
16
|
|
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
17
|
|
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18
|
|
|
|
|
|
|
# GNU General Public License for more details. |
19
|
|
|
|
|
|
|
# |
20
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License |
21
|
|
|
|
|
|
|
# along with this program; if not, write to the Free Software |
22
|
|
|
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23
|
|
|
|
|
|
|
# |
24
|
|
|
|
|
|
|
package Apache::iNcom; |
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
1
|
|
988
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
49
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
require 5.005; |
29
|
|
|
|
|
|
|
|
30
|
1
|
|
|
1
|
|
2459
|
use DBI; |
|
1
|
|
|
|
|
23640
|
|
|
1
|
|
|
|
|
86
|
|
31
|
|
|
|
|
|
|
|
32
|
1
|
|
|
1
|
|
1751
|
use Apache; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
use Apache::Log; |
34
|
|
|
|
|
|
|
use Apache::Cookie; |
35
|
|
|
|
|
|
|
use Apache::Request; |
36
|
|
|
|
|
|
|
use Apache::File; |
37
|
|
|
|
|
|
|
use Apache::Constants qw( :common :response HTTP_PRECONDITION_FAILED ); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use HTML::Embperl; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
use Apache::iNcom::Request; |
42
|
|
|
|
|
|
|
use Apache::iNcom::Localizer; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
use vars qw($VERSION); |
45
|
|
|
|
|
|
|
BEGIN { |
46
|
|
|
|
|
|
|
($VERSION) = '0.09'; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
my %VALID_PNOTES = map { $_ => 1 } qw ( |
50
|
|
|
|
|
|
|
INCOM_SESSION INCOM_DBH INCOM_LOCALIZER INCOM_COOKIES |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Grabbed from CGI.pm by Lincoln Stein |
54
|
|
|
|
|
|
|
sub offset_calc { |
55
|
|
|
|
|
|
|
my($time) = @_; |
56
|
|
|
|
|
|
|
my(%mult) = ('s'=>1, |
57
|
|
|
|
|
|
|
'm'=>60, |
58
|
|
|
|
|
|
|
'h'=>60*60, |
59
|
|
|
|
|
|
|
'd'=>60*60*24, |
60
|
|
|
|
|
|
|
'M'=>60*60*24*30, |
61
|
|
|
|
|
|
|
'y'=>60*60*24*365); |
62
|
|
|
|
|
|
|
# format for time can be in any of the forms... |
63
|
|
|
|
|
|
|
# "now" -- expire immediately |
64
|
|
|
|
|
|
|
# "+180s" -- in 180 seconds |
65
|
|
|
|
|
|
|
# "+2m" -- in 2 minutes |
66
|
|
|
|
|
|
|
# "+12h" -- in 12 hours |
67
|
|
|
|
|
|
|
# "+1d" -- in 1 day |
68
|
|
|
|
|
|
|
# "+3M" -- in 3 months |
69
|
|
|
|
|
|
|
# "+2y" -- in 2 years |
70
|
|
|
|
|
|
|
# "-3m" -- 3 minutes ago(!) |
71
|
|
|
|
|
|
|
my($offset); |
72
|
|
|
|
|
|
|
if (!$time || (lc($time) eq 'now')) { |
73
|
|
|
|
|
|
|
$offset = 0; |
74
|
|
|
|
|
|
|
} elsif ($time=~/^([+-]?(?:\d+|\d*\.\d*))([mhdMy]?)/) { |
75
|
|
|
|
|
|
|
$offset = ($mult{$2} || 1)*$1; |
76
|
|
|
|
|
|
|
} else { |
77
|
|
|
|
|
|
|
die "invalid expiration offset: $time\n"; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
return ($offset); |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub db_init { |
83
|
|
|
|
|
|
|
my $r = shift; |
84
|
|
|
|
|
|
|
my $dsn = $r->dir_config( "INCOM_DBI_DSN" ); |
85
|
|
|
|
|
|
|
my $user = $r->dir_config( "INCOM_DBI_USER" ); |
86
|
|
|
|
|
|
|
my $passwd = $r->dir_config( "INCOM_DBI_PASSWD" ); |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
unless ( $dsn ) { |
89
|
|
|
|
|
|
|
$r->log_error( "iNcom configuration error: INCOM_DBI_DSN is not defined" ); |
90
|
|
|
|
|
|
|
return SERVER_ERROR; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
my $dbh; |
94
|
|
|
|
|
|
|
eval { |
95
|
|
|
|
|
|
|
$dbh = DBI->connect( $dsn, $user, $passwd, { RaiseError => 1, |
96
|
|
|
|
|
|
|
AutoCommit => 0, |
97
|
|
|
|
|
|
|
} ); |
98
|
|
|
|
|
|
|
my $trace_lvl = $r->dir_config( "INCOM_DBI_TRACE" ); |
99
|
|
|
|
|
|
|
my $trace_file = $r->dir_config( "INCOM_DBI_LOG" ); |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# Turn tracing on if requested |
102
|
|
|
|
|
|
|
if ( $trace_lvl ) { |
103
|
|
|
|
|
|
|
$trace_file = $r->server_root_relative( $trace_file ) |
104
|
|
|
|
|
|
|
if defined $trace_file; |
105
|
|
|
|
|
|
|
$dbh->trace( $trace_lvl, $trace_file ); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# Saves it in the request record for access from |
109
|
|
|
|
|
|
|
# other handlers |
110
|
|
|
|
|
|
|
$r->pnotes( INCOM_DBH => $dbh ); |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
}; |
113
|
|
|
|
|
|
|
if ($@ ) { |
114
|
|
|
|
|
|
|
$r->log_error( "error opening connection to database: $@" ); |
115
|
|
|
|
|
|
|
return return_error( $r, SERVER_ERROR ); |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
return OK; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub i18n_init { |
121
|
|
|
|
|
|
|
my $r = shift; |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
my $langs = $r->header_in( "Accept-Language" ); |
124
|
|
|
|
|
|
|
my @languages; |
125
|
|
|
|
|
|
|
if ( $langs ) { |
126
|
|
|
|
|
|
|
my $q = 100; |
127
|
|
|
|
|
|
|
@languages = map { |
128
|
|
|
|
|
|
|
$_->[0]; |
129
|
|
|
|
|
|
|
} sort { $b->[1] <=> $a->[1] } map { |
130
|
|
|
|
|
|
|
my $l; |
131
|
|
|
|
|
|
|
if ( /([-\w]+)\s*;\s*q=([\d.]+)/ ) { |
132
|
|
|
|
|
|
|
$l = [$1, $2 ]; |
133
|
|
|
|
|
|
|
} else { |
134
|
|
|
|
|
|
|
$l = [$_, $q--]; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
} split /\s*,\s*/, $langs; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# Add the language set in cookies |
140
|
|
|
|
|
|
|
my $cookies = $r->pnotes( "INCOM_COOKIES" ); |
141
|
|
|
|
|
|
|
unshift @languages, $cookies->{INCOM_LANGUAGE}->value |
142
|
|
|
|
|
|
|
if $cookies->{INCOM_LANGUAGE}; |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# Check each languages tags for validity |
145
|
|
|
|
|
|
|
my $localizer = |
146
|
|
|
|
|
|
|
new Apache::iNcom::Localizer( $r->dir_config( "INCOM_DEFAULT_LANGUAGE" ) || "en", |
147
|
|
|
|
|
|
|
@languages |
148
|
|
|
|
|
|
|
); |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# Set environment variables so that other parts of the system |
151
|
|
|
|
|
|
|
# does hopefully the Right Things(tm) |
152
|
|
|
|
|
|
|
$ENV{LANG} = $localizer->preferred_lang; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Long live GNU ! |
155
|
|
|
|
|
|
|
$ENV{LANGUAGE} = join ":", $localizer->preferred_langs, |
156
|
|
|
|
|
|
|
$localizer->default_lang; |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Cache it for further use. |
159
|
|
|
|
|
|
|
$r->pnotes( "INCOM_LOCALIZER", $localizer ); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
return OK; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
*Apache::iNcom::handler = \&request_init; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub request_init { |
167
|
|
|
|
|
|
|
my $r = shift; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# If we are in a subrequest, just copy |
170
|
|
|
|
|
|
|
# what was initialized to the new request |
171
|
|
|
|
|
|
|
if ( $r->is_main ) { |
172
|
|
|
|
|
|
|
my $prefix = $r->dir_config( "INCOM_URL_PREFIX" ) || "/"; |
173
|
|
|
|
|
|
|
unless ( $prefix =~ m|/$| ) { |
174
|
|
|
|
|
|
|
$r->log_error( "iNcom configuration error: INCOM_URL_PREFIX must ends with /" ); |
175
|
|
|
|
|
|
|
return SERVER_ERROR; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# Parse cookies |
179
|
|
|
|
|
|
|
my $c = $r->header_in( "Cookie" ); |
180
|
|
|
|
|
|
|
my $cookies = Apache::Cookie->new( $r )->parse( $c ); |
181
|
|
|
|
|
|
|
$r->pnotes( "INCOM_COOKIES", $cookies ); |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
# Parse languages |
184
|
|
|
|
|
|
|
my $rv = i18n_init( $r ); |
185
|
|
|
|
|
|
|
return $rv if $rv != OK; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
} else { |
188
|
|
|
|
|
|
|
my $prev = $r->prev; |
189
|
|
|
|
|
|
|
foreach my $name ( keys %VALID_PNOTES ) { |
190
|
|
|
|
|
|
|
$r->pnotes( $name, $prev->pnotes( $name ) ); |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
return OK; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# Next handler is dispatch_handler |
196
|
|
|
|
|
|
|
$r->push_handlers( PerlTransHandler => \&dispatch_handler ); |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
return OK; |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub bake_session_cookie { |
202
|
|
|
|
|
|
|
my ($r, $session_id) = @_; |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
my $prefix = $r->dir_config( "INCOM_URL_PREFIX" ) || "/"; |
205
|
|
|
|
|
|
|
my $session_secure = $r->dir_config( "INCOM_SESSION_SECURE" ); |
206
|
|
|
|
|
|
|
my $session_domain = $r->dir_config( "INCOM_SESSION_DOMAIN" ); |
207
|
|
|
|
|
|
|
my $session_expires = $r->dir_config( "INCOM_SESSION_EXPIRES" ); |
208
|
|
|
|
|
|
|
my $session_path = $r->dir_config( "INCOM_SESSION_PATH" ) |
209
|
|
|
|
|
|
|
|| $prefix; |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
my $cookie = new Apache::Cookie( $r, |
212
|
|
|
|
|
|
|
-name => "INCOM_SESSION", |
213
|
|
|
|
|
|
|
-value => $session_id, |
214
|
|
|
|
|
|
|
-path => $session_path |
215
|
|
|
|
|
|
|
); |
216
|
|
|
|
|
|
|
$cookie->domain( $session_domain ) if $session_domain; |
217
|
|
|
|
|
|
|
$cookie->expires( $session_expires ) if $session_expires; |
218
|
|
|
|
|
|
|
$cookie->secure( 1 ) if $session_secure; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# Add cookie to outgoing headers |
221
|
|
|
|
|
|
|
$cookie->bake; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub session_init { |
225
|
|
|
|
|
|
|
my $r = shift; |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
my %session; |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
# Check if there is a session id in the cookies |
230
|
|
|
|
|
|
|
my $cookies = $r->pnotes( "INCOM_COOKIES" ); |
231
|
|
|
|
|
|
|
if ( $cookies->{INCOM_SESSION} ) { |
232
|
|
|
|
|
|
|
my $session_id = $cookies->{INCOM_SESSION}->value; |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# Load the user's session |
235
|
|
|
|
|
|
|
eval { |
236
|
|
|
|
|
|
|
# Make sure it looks like a session id |
237
|
|
|
|
|
|
|
die "Invalid session id: $session_id\n" |
238
|
|
|
|
|
|
|
unless length $session_id == 32 && |
239
|
|
|
|
|
|
|
$session_id =~ tr/a-fA-F0-9/a-fA-F0-9/ == 32; |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
tie %session, 'Apache::iNcom::Session', $session_id, |
242
|
|
|
|
|
|
|
{ dbh => $r->pnotes( "INCOM_DBH"), |
243
|
|
|
|
|
|
|
Serialize => $r->dir_config( "INCOM_SESSION_SERIALIZE_ACCESS" ), |
244
|
|
|
|
|
|
|
}; |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# Save the session for future handlers |
247
|
|
|
|
|
|
|
$r->pnotes( INCOM_SESSION => \%session ); |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
if ( $r->dir_config( "INCOM_SESSION_EXPIRES" ) ) { |
250
|
|
|
|
|
|
|
# If session doesn't expire with the browser session |
251
|
|
|
|
|
|
|
# we must renew the cookie. |
252
|
|
|
|
|
|
|
bake_session_cookie( $r, $session_id ); |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
}; |
256
|
|
|
|
|
|
|
if ( $@ ) { |
257
|
|
|
|
|
|
|
# The session ID is probably invalid |
258
|
|
|
|
|
|
|
chomp $@; |
259
|
|
|
|
|
|
|
$r->warn( "error loading session: $@" ); |
260
|
|
|
|
|
|
|
} else { |
261
|
|
|
|
|
|
|
# Return ref to session to indicate success |
262
|
|
|
|
|
|
|
return \%session; |
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# No valid session could be loaded |
267
|
|
|
|
|
|
|
return undef; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# Return the requested error code but sets a custom response |
272
|
|
|
|
|
|
|
# if the error condition is present in the error map. |
273
|
|
|
|
|
|
|
sub return_error { |
274
|
|
|
|
|
|
|
my ( $r, $status ) = @_; |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
my $prefix = $r->dir_config( "INCOM_URL_PREFIX" ) || "/"; |
277
|
|
|
|
|
|
|
my $map = $r->dir_config( "INCOM_ERROR_PROFILE" ); |
278
|
|
|
|
|
|
|
return $status unless $map; |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
$map = $r->server_root_relative( $map ); |
281
|
|
|
|
|
|
|
unless ( -e $map && -f _ && -r _ ) { |
282
|
|
|
|
|
|
|
$r->warn( "INCOM_ERROR_PROFILE is not valid" ); |
283
|
|
|
|
|
|
|
return $status; |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
my $response = eval { |
287
|
|
|
|
|
|
|
my $profile = do $map; |
288
|
|
|
|
|
|
|
unless ( ref $profile eq "HASH" ) { |
289
|
|
|
|
|
|
|
$r->warn( "INCOM_ERROR_PROFILE didn't return an hash ref" ); |
290
|
|
|
|
|
|
|
return $status; |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
my $error_cond = $r->pnotes( "INCOM_ERROR" ); |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
$profile->{$error_cond} || $profile->{$status}; |
296
|
|
|
|
|
|
|
}; |
297
|
|
|
|
|
|
|
if ( $@) { |
298
|
|
|
|
|
|
|
$r->warn( "error while evaluating error profile: $@" ); |
299
|
|
|
|
|
|
|
return $status; |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
$r->custom_response( $status, $prefix . "/incom_error/" . $response ) if $response; |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
return $status; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
# This is a handler used to transform the request |
308
|
|
|
|
|
|
|
# to an action. It is invoked during the URI |
309
|
|
|
|
|
|
|
# translation phase of the request |
310
|
|
|
|
|
|
|
# |
311
|
|
|
|
|
|
|
# It is responsible for loading the user session. If |
312
|
|
|
|
|
|
|
# there is no session it sets the content handler to |
313
|
|
|
|
|
|
|
# the new_session_handler |
314
|
|
|
|
|
|
|
sub dispatch_handler { |
315
|
|
|
|
|
|
|
my $r = shift; |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
# Get configuration |
318
|
|
|
|
|
|
|
my $prefix = $r->dir_config( "INCOM_URL_PREFIX" ) || "/"; |
319
|
|
|
|
|
|
|
my $index_file = $r->dir_config( "INCOM_INDEX" ) || "index.html"; |
320
|
|
|
|
|
|
|
my $incom_root = $r->dir_config( "INCOM_ROOT" ) |
321
|
|
|
|
|
|
|
|| $r->document_root; |
322
|
|
|
|
|
|
|
$incom_root = $r->server_root_relative( $incom_root ); |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
my $uri = $r->uri; |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
# Decline to handle this unless the request URI match our prefix |
327
|
|
|
|
|
|
|
return DECLINED unless $uri =~ s!^$prefix/*!!; |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
# Only support GET or POST |
330
|
|
|
|
|
|
|
return NOT_IMPLEMENTED unless $r->method =~ /^(GET|POST)$/; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
if ( $r->is_main ) { |
333
|
|
|
|
|
|
|
# On the first request, we open the connection to the database |
334
|
|
|
|
|
|
|
# and loads the user session |
335
|
|
|
|
|
|
|
my $rc = db_init( $r ); |
336
|
|
|
|
|
|
|
session_init( $r ); |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
# To clean DB connection and Session |
339
|
|
|
|
|
|
|
$r->push_handlers( PerlCleanupHandler => \&request_cleanup ); |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
# Determine the handler |
343
|
|
|
|
|
|
|
if ( $uri =~ s!^incom_cookie_check/!! ) { |
344
|
|
|
|
|
|
|
# Check if the session was loaded properly |
345
|
|
|
|
|
|
|
if ( ref $r->pnotes( "INCOM_SESSION") ) { |
346
|
|
|
|
|
|
|
# Cookie test suceeded. Tell browser to refetch |
347
|
|
|
|
|
|
|
# original file |
348
|
|
|
|
|
|
|
$r->pnotes( "INCOM_REDIRECT_TO", $prefix . $uri ); |
349
|
|
|
|
|
|
|
$r->push_handlers( PerlHandler => \&redirect_handler ); |
350
|
|
|
|
|
|
|
$r->handler( "perl-script" ); |
351
|
|
|
|
|
|
|
} else { |
352
|
|
|
|
|
|
|
# Cookie test failed |
353
|
|
|
|
|
|
|
$r->pnotes( "INCOM_ERROR", "no_cookies" ); |
354
|
|
|
|
|
|
|
return return_error( $r, HTTP_PRECONDITION_FAILED ); |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
} elsif ( $uri =~ s!^incom_set_lang/([-\w]+)/!! ) { |
357
|
|
|
|
|
|
|
$r->pnotes( "INCOM_NEW_LANG", "$1" ); |
358
|
|
|
|
|
|
|
$r->pnotes( "INCOM_REDIRECT_TO", $prefix . $uri ); |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
$r->push_handlers( PerlHandler => \&set_lang_handler ); |
361
|
|
|
|
|
|
|
$r->handler( "perl-script" ); |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
# incom_error magic URL should only be called as a subrequest. |
364
|
|
|
|
|
|
|
} elsif ( (!$r->main) && $uri =~ s!^incom_error/!! ) { |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
$incom_root = $r->dir_config( "INCOM_ERROR_ROOT" ) || $incom_root; |
367
|
|
|
|
|
|
|
$incom_root = $r->server_root_relative( $incom_root ); |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
$r->push_handlers( PerlHandler => \&error_handler ); |
370
|
|
|
|
|
|
|
$r->handler( "perl-script" ); |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
} elsif ( not ref $r->pnotes( "INCOM_SESSION" ) ) { |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
# The user doesn't belong to an existing session |
375
|
|
|
|
|
|
|
$r->push_handlers( PerlHandler => \&new_session_handler ); |
376
|
|
|
|
|
|
|
$r->handler( "perl-script" ); |
377
|
|
|
|
|
|
|
} else { |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
# Default handler |
380
|
|
|
|
|
|
|
$r->push_handlers( PerlHandler => \&default_handler ); |
381
|
|
|
|
|
|
|
$r->handler( "perl-script" ); |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
# Set the filename |
385
|
|
|
|
|
|
|
$uri ||= $index_file; |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
# Handle directory index |
388
|
|
|
|
|
|
|
$uri =~ s!/$!/$index_file!; |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# Find the properly localized file |
391
|
|
|
|
|
|
|
my $localizer = $r->pnotes( "INCOM_LOCALIZER" ); |
392
|
|
|
|
|
|
|
my $file = $localizer->find_localized_file( $incom_root . "/" . $uri ); |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
# Set filename of the request |
395
|
|
|
|
|
|
|
$r->filename( $file ); |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
# Request should never be cached |
398
|
|
|
|
|
|
|
$r->header_out( 'Pragma', 'no-cache' ); |
399
|
|
|
|
|
|
|
$r->header_out( 'Cache-control', 'no-cache' ); |
400
|
|
|
|
|
|
|
$r->no_cache(1); |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
# Default content-type |
403
|
|
|
|
|
|
|
$r->content_type( "text/html" ); |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
return OK; |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
# Content handler invoked when the request is not |
409
|
|
|
|
|
|
|
# part of a session. |
410
|
|
|
|
|
|
|
# |
411
|
|
|
|
|
|
|
# It creates a new session. Sets a cookie to it |
412
|
|
|
|
|
|
|
# and redirect the user to resubmit the request |
413
|
|
|
|
|
|
|
# to a rewritten URL. |
414
|
|
|
|
|
|
|
sub new_session_handler { |
415
|
|
|
|
|
|
|
my $r = shift; |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
my %session; |
418
|
|
|
|
|
|
|
eval { |
419
|
|
|
|
|
|
|
tie %session, 'Apache::iNcom::Session', undef, |
420
|
|
|
|
|
|
|
{ dbh => $r->pnotes( "INCOM_DBH"), |
421
|
|
|
|
|
|
|
Serialize => $r->dir_config( "INCOM_SESSION_SERIALIZE_ACCESS" ), |
422
|
|
|
|
|
|
|
}; |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
bake_session_cookie( $r, $session{_session_id} ); |
425
|
|
|
|
|
|
|
}; |
426
|
|
|
|
|
|
|
if ($@) { |
427
|
|
|
|
|
|
|
$r->log_error( "error creating session: $@" ); |
428
|
|
|
|
|
|
|
return return_error( $r, SERVER_ERROR ); |
429
|
|
|
|
|
|
|
} |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
# Tell the browser to repost its request. We will then be |
432
|
|
|
|
|
|
|
# able to check if he has cookie turn on |
433
|
|
|
|
|
|
|
my $prefix = $r->dir_config( "INCOM_URL_PREFIX" ) || "/"; |
434
|
|
|
|
|
|
|
my $uri = $r->uri; |
435
|
|
|
|
|
|
|
$uri =~ s!^$prefix/*!${prefix}incom_cookie_check/!; |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
$r->content_type( "text/html" ); |
438
|
|
|
|
|
|
|
$r->header_out( Location => $uri ); |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
return REDIRECT; |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
sub redirect_handler { |
444
|
|
|
|
|
|
|
my $r = shift; |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
$r->content_type( "text/html" ); |
447
|
|
|
|
|
|
|
$r->header_out( Location => $r->pnotes( "INCOM_REDIRECT_TO" ) ); |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
return REDIRECT; |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
sub set_lang_handler { |
453
|
|
|
|
|
|
|
my $r = shift; |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
my $prefix = $r->dir_config( "INCOM_URL_PREFIX" ) || "/"; |
456
|
|
|
|
|
|
|
my $session_domain = $r->dir_config( "INCOM_SESSION_DOMAIN" ); |
457
|
|
|
|
|
|
|
my $session_path = $r->dir_config( "INCOM_SESSION_PATH" ) |
458
|
|
|
|
|
|
|
|| $prefix; |
459
|
|
|
|
|
|
|
my $session_expires = $r->dir_config( "INCOM_SESSION_EXPIRES" ); |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
# Create a cookie which has the same lifespan than |
462
|
|
|
|
|
|
|
# the session cookie. |
463
|
|
|
|
|
|
|
my $cookie = new Apache::Cookie( $r, |
464
|
|
|
|
|
|
|
-name => "INCOM_LANGUAGE", |
465
|
|
|
|
|
|
|
-value => $r->pnotes( "INCOM_NEW_LANG" ), |
466
|
|
|
|
|
|
|
-path => $session_path, |
467
|
|
|
|
|
|
|
); |
468
|
|
|
|
|
|
|
$cookie->domain( $session_domain ) if $session_domain; |
469
|
|
|
|
|
|
|
$cookie->expires( $session_expires ) if $session_expires; |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
# Add cookie to outgoing headers |
472
|
|
|
|
|
|
|
$cookie->bake; |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
# Tell the browser to repost its request. The next |
475
|
|
|
|
|
|
|
# request will favorise the new language. |
476
|
|
|
|
|
|
|
$r->content_type( "text/html" ); |
477
|
|
|
|
|
|
|
$r->header_out( Location => $r->pnotes( "INCOM_REDIRECT_TO" ) ); |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
return REDIRECT; |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
sub package_name { |
483
|
|
|
|
|
|
|
my $r = shift; |
484
|
|
|
|
|
|
|
my $file = shift; |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
my $host = $r->server->server_hostname; |
487
|
|
|
|
|
|
|
my $root = $r->dir_config( "INCOM_ROOT" ) || $r->document_root; |
488
|
|
|
|
|
|
|
$root = $r->server_root_relative( $root ); |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# Remove document root |
491
|
|
|
|
|
|
|
$file =~ s!^$root/!!; |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
# Remove trailing suffixes of the last component |
494
|
|
|
|
|
|
|
# of the path name |
495
|
|
|
|
|
|
|
$file =~ s!\.[^/]*$!!; |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
# Munge invalid character |
498
|
|
|
|
|
|
|
$file =~ tr/a-zA-Z0-9/_/cs; |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
# Munge invalid character in hostname |
501
|
|
|
|
|
|
|
$host =~ tr/a-zA-Z0-9/_/cs; |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
return "Apache::iNcom::" . $host . "::" . $file; |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
sub error_handler { |
507
|
|
|
|
|
|
|
my $r = shift; |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
my $filename = $r->filename; |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
unless ( -e $r->finfo ) { |
512
|
|
|
|
|
|
|
$r->log_reason( "nonexistent file", $filename ); |
513
|
|
|
|
|
|
|
return NOT_FOUND; |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
unless ( -f _ ) { |
517
|
|
|
|
|
|
|
$r->log_reason( "not a regular file", $filename ); |
518
|
|
|
|
|
|
|
return FORBIDDEN; |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
unless ( -r _ ) { |
522
|
|
|
|
|
|
|
$r->log_reason( "No permissions to read", $filename ); |
523
|
|
|
|
|
|
|
return FORBIDDEN; |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
# Determine the package name of this error page |
527
|
|
|
|
|
|
|
# Package is Apache::iNcom::basename of the page |
528
|
|
|
|
|
|
|
my $package = package_name( $r, $filename ); |
529
|
|
|
|
|
|
|
my $req = new Apache::iNcom::Request( $r, $package ); |
530
|
|
|
|
|
|
|
# Play magic |
531
|
|
|
|
|
|
|
$req->setup_aliases; |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
# Send the response |
534
|
|
|
|
|
|
|
my $output; |
535
|
|
|
|
|
|
|
$r->content_type( "text/html" ); |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
my $debug = $r->dir_config( "EMBPERL_DEBUG" ) || $ENV{EMBPERL_DEBUG} || 0; |
538
|
|
|
|
|
|
|
my $options = $r->dir_config( "EMBPERL_OPTIONS" ) || |
539
|
|
|
|
|
|
|
$ENV{EMBPERL_OPTIONS} || 16; # Default = optRawInput |
540
|
|
|
|
|
|
|
# optDisableFormData,optReturnError |
541
|
|
|
|
|
|
|
$options |= 256 | 262144; |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
my $params = { |
544
|
|
|
|
|
|
|
package => $package, |
545
|
|
|
|
|
|
|
output => \$output, |
546
|
|
|
|
|
|
|
inputfile => $filename, |
547
|
|
|
|
|
|
|
req_rec => $r, |
548
|
|
|
|
|
|
|
debug => $debug, |
549
|
|
|
|
|
|
|
options => $options, |
550
|
|
|
|
|
|
|
param => $r->prev->pnotes( "INCOM_HTML_EMBPERL_ERRORS" ), |
551
|
|
|
|
|
|
|
}; |
552
|
|
|
|
|
|
|
my $rc = HTML::Embperl::Execute( $params ); |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
$req->cleanup_aliases; |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
my $dbh = $r->pnotes( "INCOM_DBH" ); |
557
|
|
|
|
|
|
|
if ($rc != OK && $rc != MOVED && $rc != REDIRECT ) { |
558
|
|
|
|
|
|
|
# If there was an error, rollback all changes |
559
|
|
|
|
|
|
|
# to the database |
560
|
|
|
|
|
|
|
eval { $dbh->rollback; }; |
561
|
|
|
|
|
|
|
$r->log_error( "error reverting changes to database: $@" ) if $@; |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
$r->log_reason( "error in embperl code", $filename ); |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
return $rc; |
566
|
|
|
|
|
|
|
} else { |
567
|
|
|
|
|
|
|
# Commit all changes to the database |
568
|
|
|
|
|
|
|
eval { $dbh->commit; }; |
569
|
|
|
|
|
|
|
$r->log_error( "error commiting changes to database: $@" ) if $@; |
570
|
|
|
|
|
|
|
$r->header_out( "Content-Length", length $output ); |
571
|
|
|
|
|
|
|
$r->send_http_header; |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
$r->print( $output ); |
574
|
|
|
|
|
|
|
return OK; |
575
|
|
|
|
|
|
|
} |
576
|
|
|
|
|
|
|
} |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
sub default_handler { |
579
|
|
|
|
|
|
|
# Create an Apache::Request object for |
580
|
|
|
|
|
|
|
# parsing POST and GET request |
581
|
|
|
|
|
|
|
my $r = new Apache::Request( shift ); |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
my $filename = $r->filename; |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
unless ( -e $r->finfo ) { |
586
|
|
|
|
|
|
|
$r->log_reason( "nonexistent file", $filename ); |
587
|
|
|
|
|
|
|
return return_error( $r, NOT_FOUND ); |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
unless ( -f _ ) { |
591
|
|
|
|
|
|
|
$r->log_reason( "not a regular file", $filename ); |
592
|
|
|
|
|
|
|
return return_error( $r, FORBIDDEN ); |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
unless ( -r _ ) { |
596
|
|
|
|
|
|
|
$r->log_reason( "No permissions to read", $filename ); |
597
|
|
|
|
|
|
|
return return_error( $r, FORBIDDEN ); |
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
# Read the POST data or the Query stringn |
601
|
|
|
|
|
|
|
my $status = $r->parse; |
602
|
|
|
|
|
|
|
unless ( $status == OK ) { |
603
|
|
|
|
|
|
|
$r->log_reason( "error reading request body: " . |
604
|
|
|
|
|
|
|
$r->notes( "error-notes"), $filename); |
605
|
|
|
|
|
|
|
return return_error( $r, $status ); |
606
|
|
|
|
|
|
|
} |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
# Copy the elements into the fdat hash |
609
|
|
|
|
|
|
|
my %fdat = (); |
610
|
|
|
|
|
|
|
my @ffld = (); |
611
|
|
|
|
|
|
|
for my $key ( $r->param ) { |
612
|
|
|
|
|
|
|
# Discard empty fields |
613
|
|
|
|
|
|
|
my @values = grep { $_ ne "" } $r->param( $key ); |
614
|
|
|
|
|
|
|
next unless @values; |
615
|
|
|
|
|
|
|
push @ffld, $key; |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
# This is what is expected from HTML::Embperl |
618
|
|
|
|
|
|
|
$fdat{$key} = join "\t", @values; |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
# Determine the package name of this page |
622
|
|
|
|
|
|
|
# Package is Apache::iNcom::basename of the page |
623
|
|
|
|
|
|
|
my $package = package_name( $r, $filename ); |
624
|
|
|
|
|
|
|
my $req = new Apache::iNcom::Request( $r, $package ); |
625
|
|
|
|
|
|
|
# Play magic |
626
|
|
|
|
|
|
|
$req->setup_aliases; |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
# Send the response |
629
|
|
|
|
|
|
|
my $output; |
630
|
|
|
|
|
|
|
$r->content_type( "text/html" ); |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
my $debug = $r->dir_config( "EMBPERL_DEBUG" ) || $ENV{EMBPERL_DEBUG} || 0; |
633
|
|
|
|
|
|
|
my $options = $r->dir_config( "EMBPERL_OPTIONS" ) || |
634
|
|
|
|
|
|
|
$ENV{EMBPERL_OPTIONS} || 16; # Default = optRawInput |
635
|
|
|
|
|
|
|
# optDisableFormData,optReturnError |
636
|
|
|
|
|
|
|
$options |= 256 | 262144; |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
my $params = { |
639
|
|
|
|
|
|
|
package => $package, |
640
|
|
|
|
|
|
|
output => \$output, |
641
|
|
|
|
|
|
|
inputfile => $filename, |
642
|
|
|
|
|
|
|
req_rec => $r, |
643
|
|
|
|
|
|
|
errors => [], |
644
|
|
|
|
|
|
|
debug => $debug, |
645
|
|
|
|
|
|
|
options => $options, |
646
|
|
|
|
|
|
|
fdat => \%fdat, |
647
|
|
|
|
|
|
|
ffld => \@ffld, |
648
|
|
|
|
|
|
|
}; |
649
|
|
|
|
|
|
|
my $rc = HTML::Embperl::Execute( $params ); |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
$req->cleanup_aliases; |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
my $dbh = $r->pnotes( "INCOM_DBH" ); |
654
|
|
|
|
|
|
|
if ($rc != OK && $rc != MOVED && $rc != REDIRECT ) { |
655
|
|
|
|
|
|
|
# If there was an error, rollback all changes |
656
|
|
|
|
|
|
|
# to the database |
657
|
|
|
|
|
|
|
eval { $dbh->rollback; }; |
658
|
|
|
|
|
|
|
$r->log_error( "error reverting changes to database: $@" ) if $@; |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
$r->log_reason( "error in embperl code", $filename ); |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
# Save HTML error messages for the error page |
663
|
|
|
|
|
|
|
$r->pnotes( "INCOM_HTML_EMBPERL_ERRORS", $params->{errors} ); |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
return return_error( $r, $rc ); |
666
|
|
|
|
|
|
|
} else { |
667
|
|
|
|
|
|
|
# Commit all changes to the database |
668
|
|
|
|
|
|
|
eval { $dbh->commit; }; |
669
|
|
|
|
|
|
|
$r->log_error( "error commiting changes to database: $@" ) if $@; |
670
|
|
|
|
|
|
|
$r->header_out( "Content-Length", length $output ); |
671
|
|
|
|
|
|
|
$r->send_http_header; |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
$r->print( $output ); |
674
|
|
|
|
|
|
|
return OK; |
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
} |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
sub request_cleanup { |
679
|
|
|
|
|
|
|
my $r = shift; |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
my $session = $r->pnotes( "INCOM_SESSION" ); |
682
|
|
|
|
|
|
|
if ( $session ) { |
683
|
|
|
|
|
|
|
eval { untie %$session; }; |
684
|
|
|
|
|
|
|
$r->log_error( "error untying session: $@" ) if $@; |
685
|
|
|
|
|
|
|
} |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
my $dbh = $r->pnotes( "INCOM_DBH" ); |
688
|
|
|
|
|
|
|
if ( $dbh ) { |
689
|
|
|
|
|
|
|
# Delete expired sessions on 5% of the requests |
690
|
|
|
|
|
|
|
if ( rand 100 < 5 ) { |
691
|
|
|
|
|
|
|
eval { |
692
|
|
|
|
|
|
|
my $session_expires = |
693
|
|
|
|
|
|
|
$r->dir_config( "INCOM_SESSION_EXPIRES" ); |
694
|
|
|
|
|
|
|
my $offset; |
695
|
|
|
|
|
|
|
if ( $session_expires ) { |
696
|
|
|
|
|
|
|
$offset = offset_calc( $session_expires ); |
697
|
|
|
|
|
|
|
} else { |
698
|
|
|
|
|
|
|
$offset = 3600 * 24; # One day |
699
|
|
|
|
|
|
|
} |
700
|
|
|
|
|
|
|
# XXX Is this really portable ???? |
701
|
|
|
|
|
|
|
my $time = localtime ( time - $offset); |
702
|
|
|
|
|
|
|
$dbh->do( "DELETE FROM sessions WHERE last_update < '$time'" ); |
703
|
|
|
|
|
|
|
$dbh->commit; |
704
|
|
|
|
|
|
|
}; |
705
|
|
|
|
|
|
|
$r->log_error( "error removing old sessions: $@" ) if $@; |
706
|
|
|
|
|
|
|
} |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
eval { |
709
|
|
|
|
|
|
|
$dbh->disconnect unless $dbh; |
710
|
|
|
|
|
|
|
}; |
711
|
|
|
|
|
|
|
$r->log_error( "error closing connection to database: $@" ) if $@; |
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
return OK; |
715
|
|
|
|
|
|
|
} |
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
1; |
718
|
|
|
|
|
|
|
__END__ |