1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/****************************************************************** |
3
|
|
|
loader.web.php Muze Ariadne |
4
|
|
|
------------------------------------------------------------------ |
5
|
|
|
Author: Muze ([email protected]) |
6
|
|
|
Date: 11 december 2002 |
7
|
|
|
|
8
|
|
|
Copyright 2002 Muze |
9
|
|
|
|
10
|
|
|
This file is part of Ariadne. |
11
|
|
|
|
12
|
|
|
Ariadne is free software; you can redistribute it and/or modify |
13
|
|
|
it under the terms of the GNU General Public License as published |
14
|
|
|
by the Free Software Foundation; either version 2 of the License, |
15
|
|
|
or (at your option) any later version. |
16
|
|
|
|
17
|
|
|
Ariadne is distributed in the hope that it will be useful, |
18
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
19
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20
|
|
|
GNU General Public License for more details. |
21
|
|
|
|
22
|
|
|
You should have received a copy of the GNU General Public License |
23
|
|
|
along with Ariadne; if not, write to the Free Software |
24
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
25
|
|
|
02111-1307 USA |
26
|
|
|
|
27
|
|
|
------------------------------------------------------------------- |
28
|
|
|
|
29
|
|
|
Description: |
30
|
|
|
|
31
|
|
|
This is loader that contains all functions for the Ariadne web |
32
|
|
|
interface. |
33
|
|
|
|
34
|
|
|
******************************************************************/ |
35
|
|
|
|
36
|
|
|
$ERRMODE="htmljs"; // alternative: "text"/"html"/"js" |
|
|
|
|
37
|
|
|
|
38
|
|
|
define('LD_ERR_ACCESS', -1); |
39
|
|
|
define('LD_ERR_SESSION', -2); |
40
|
|
|
|
41
|
|
|
include_once($store_config['code']."includes/loader.web.auth.php"); |
42
|
|
|
include_once($store_config['code']."objects/pobject.phtml"); |
43
|
|
|
|
44
|
|
|
function ldCheckAllowedMethods($method = null) { |
45
|
|
|
global $AR; |
46
|
|
|
if ( |
47
|
|
|
is_array($AR->loader->web['AllowedMethods']) && isset($method) && |
48
|
|
|
!(in_array(strtoupper($method), $AR->loader->web['AllowedMethods'])) |
49
|
|
|
) { |
50
|
|
|
header("HTTP/1.1 405 Method Not Allowed"); |
51
|
|
|
exit(1); |
|
|
|
|
52
|
|
|
} |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
function debug_print( $text ) { |
56
|
|
|
echo "<b>".$text."</b><br>"; |
57
|
|
|
flush(); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
View Code Duplication |
function error($text) { |
|
|
|
|
61
|
|
|
global $ERRMODE; |
62
|
|
|
switch ($ERRMODE) { |
63
|
|
|
case "html" : |
|
|
|
|
64
|
|
|
echo "<b><font color='red'>Error: $text</font></b><BR>\n"; |
65
|
|
|
break; |
66
|
|
|
case "js" : |
|
|
|
|
67
|
|
|
echo "\nalert('Error: $text');\n"; |
68
|
|
|
break; |
69
|
|
|
case "text" : |
|
|
|
|
70
|
|
|
echo "\nERROR: $text\n"; |
71
|
|
|
break; |
72
|
|
|
case "htmljs" : |
|
|
|
|
73
|
|
|
default: |
74
|
|
|
echo "// <b><font color='red'>Error: $text</font></b><BR>\n<!--\nalert('Error: $text');\n// -->\n"; |
75
|
|
|
break; |
76
|
|
|
} |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
function ldRegisterFile($field = "file", &$error) { |
|
|
|
|
80
|
|
|
global $ARnls, $store; |
81
|
|
|
|
82
|
|
|
require_once($store->get_config("code")."modules/mod_mimemagic.php"); |
83
|
|
|
$result = Array(); |
84
|
|
|
$http_post_file = Array('name' => '', 'type' => '', 'tmp_name' => '', 'error' => '', 'size' => ''); |
85
|
|
|
$subfields = explode('[', $field); |
86
|
|
|
$field = array_shift($subfields); |
87
|
|
|
$subfield = false; |
88
|
|
|
foreach ($http_post_file as $key => $value) { |
89
|
|
|
$value = &$_FILES[$field][$key]; |
90
|
|
|
foreach ($subfields as $subfield) { |
91
|
|
|
$subfield = substr($subfield, 0, -1); |
92
|
|
|
$value = &$value[$subfield]; |
93
|
|
|
} |
94
|
|
|
$http_post_file[$key] = $value; |
95
|
|
|
} |
96
|
|
|
if ($subfield) { |
|
|
|
|
97
|
|
|
$field = $subfield; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
if ($http_post_file['error']) { |
101
|
|
|
switch ($http_post_file['error']) { |
102
|
|
|
case UPLOAD_ERR_INI_SIZE: |
103
|
|
|
$error = $ARnls['ariadne:err:upload_ini_size']; // "The uploaded file exceeds the upload_max_filesize directive in php.ini"; |
104
|
|
|
break; |
105
|
|
|
case UPLOAD_ERR_FORM_SIZE: |
106
|
|
|
$error = $ARnls['ariadne:err:upload_form_size']; // The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"; |
107
|
|
|
break; |
108
|
|
|
case UPLOAD_ERR_PARTIAL: |
109
|
|
|
$error = $ARnls['ariadne:err:upload_partial']; // "The uploaded file was only partially uploaded"; |
110
|
|
|
break; |
111
|
|
|
case UPLOAD_ERR_NO_FILE: |
112
|
|
|
// Note: this is not an error |
113
|
|
|
//$error = $ARnls['ariadne:err:upload_no_file']; // No file was uploaded"; |
|
|
|
|
114
|
|
|
break; |
115
|
|
|
case UPLOAD_ERR_NO_TMP_DIR: |
116
|
|
|
$error = $ARnls['ariadne:err:upload_no_tmp_dir']; // "Missing a temporary folder"; |
117
|
|
|
break; |
118
|
|
|
case UPLOAD_ERR_CANT_WRITE: |
119
|
|
|
$error = $ARnls['ariadne:err:upload_cant_write']; // "Failed to write file to disk"; |
120
|
|
|
break; |
121
|
|
|
case UPLOAD_ERR_EXTENSION: |
122
|
|
|
$error = $ARnls['ariadne:err:upload_extension']; // "File upload stopped by extension"; |
123
|
|
|
break; |
124
|
|
|
|
125
|
|
|
default: |
126
|
|
|
$error = sprintf($ARnls['ariadne:err:upload_error'], $http_post_file['error']); // "Unknown upload error %s"; |
127
|
|
|
break; |
128
|
|
|
} |
129
|
|
|
return $result; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
$file_temp = $http_post_file['tmp_name']; |
133
|
|
|
$file = $http_post_file['name']; |
134
|
|
|
if ($file && is_uploaded_file($file_temp)) { |
135
|
|
|
// new file uploaded -> save it before PHP deletes it |
136
|
|
|
$file_artemp=tempnam($store->get_config("files")."temp","upload"); |
137
|
|
|
if (move_uploaded_file($file_temp, $file_artemp)) { |
138
|
|
|
// now make the new values available to wgWizKeepVars() |
139
|
|
|
$result[$field]=$file; |
140
|
|
|
$result[$field."_temp"]=basename($file_artemp); |
141
|
|
|
$result[$field."_size"]=(int)$http_post_file['size']; |
142
|
|
|
$type = get_mime_type($file_artemp); |
143
|
|
|
$ext = substr($file, strrpos($file, '.')); |
144
|
|
|
if (!$type) { |
145
|
|
|
$type = get_mime_type($file, MIME_EXT); |
146
|
|
|
} |
147
|
|
|
$result[$field."_type"] = get_content_type($type, $ext); |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
return $result; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
function ldOnFinish() { |
154
|
|
|
global $ARCurrent, $store; |
155
|
|
|
$error = error_get_last(); |
156
|
|
|
if ($error['type'] == 1) { // Fatal error |
157
|
|
|
$context = pobject::getContext(); |
158
|
|
|
if ($context['scope'] == 'pinp') { |
159
|
|
|
pobject::pinpErrorHandler($error['type'], $error['message'], $error['file'], $error['line'], null); |
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
if ($ARCurrent->session) { |
163
|
|
|
$ARCurrent->session->save(); |
164
|
|
|
} |
165
|
|
|
if ($store) { |
166
|
|
|
$store->close(); |
167
|
|
|
} |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
function ldObjectNotFound($requestedpath, $requestedtemplate, $requestedargs = null ) { |
|
|
|
|
171
|
|
|
global $store, $AR, $ARCurrent, $args; |
172
|
|
|
$path=$requestedpath; |
173
|
|
|
if ( !$requestedargs ) { |
174
|
|
|
$requestedargs = $args; |
175
|
|
|
} |
176
|
|
|
if (!$path) { |
177
|
|
|
error("Empty path requested with template: $requestedtemplate"); |
178
|
|
|
} else { |
179
|
|
|
$prevPath = null; |
180
|
|
View Code Duplication |
while ($path !== $prevPath && !$store->exists($path)) { |
181
|
|
|
$prevPath = $path; |
182
|
|
|
$path = $store->make_path($path, ".."); |
183
|
|
|
} |
184
|
|
|
if(count($ARCurrent->arCallStack) == 0) { |
185
|
|
|
$arCallArgs = $requestedargs; |
186
|
|
|
} else { |
187
|
|
|
$arCallArgs = @array_pop($ARCurrent->arCallStack); |
188
|
|
|
@array_push($ARCurrent->arCallStack, $arCallArgs); |
|
|
|
|
189
|
|
|
} |
190
|
|
|
if ($prevPath==$path) { |
191
|
|
|
error("Database is not initialised, please run <a href=\"".$AR->dir->www."install/install.php\">the installer</a>"); |
192
|
|
|
} else { |
193
|
|
|
// make sure the config check has been run: |
194
|
|
|
$ob = current( $store->call('system.get.phtml', array(), $store->get($path) ) ); |
195
|
|
|
$ob->loadConfig(); //CheckConfig(); |
196
|
|
|
|
197
|
|
|
$ob->pushContext( array( |
198
|
|
|
"arSuperContext" => Array(), |
199
|
|
|
"arCurrentObject" => $ob, |
200
|
|
|
"scope" => "php", |
201
|
|
|
"arCallFunction" => $requestedtemplate |
202
|
|
|
) ); |
203
|
|
|
|
204
|
|
|
$eventData = new object(); |
205
|
|
|
$eventData->arCallPath = $requestedpath; |
|
|
|
|
206
|
|
|
$eventData->arCallFunction = $requestedtemplate; |
|
|
|
|
207
|
|
|
$eventData->arCallArgs = $arCallArgs; |
|
|
|
|
208
|
|
|
$eventData = ar_events::fire( 'onnotfound', $eventData ); |
|
|
|
|
209
|
|
|
if ( $eventData ) { |
210
|
|
|
// no results: page couldn't be found, show user definable 404 message |
211
|
|
|
$arCallArgs = (array) $eventData->arCallArgs; |
212
|
|
|
$requestedargs = $arCallArgs; |
213
|
|
|
$myarCallArgs = array_merge($arCallArgs, |
214
|
|
|
Array( "arRequestedPath" => $requestedpath, |
215
|
|
|
"arRequestedTemplate" => $requestedtemplate, |
216
|
|
|
"arRequestedArgs" => $requestedargs |
217
|
|
|
) |
218
|
|
|
); |
219
|
|
|
$store->call("user.notfound.html",$myarCallArgs, |
220
|
|
|
$store->get($path)); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
$ob->popContext(); |
224
|
|
|
} |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
|
229
|
|
|
|
230
|
|
|
|
231
|
|
View Code Duplication |
function ldSetRoot($session='', $nls='') { |
|
|
|
|
232
|
|
|
global $store, $AR, $ARCurrent, $root, $rootoptions; |
233
|
|
|
|
234
|
|
|
$root=$AR->root; |
235
|
|
|
$rootoptions=""; |
236
|
|
|
if ($session && !$AR->hideSessionIDfromURL) { |
237
|
|
|
$rootoptions.="/-".$session."-"; |
238
|
|
|
$ARCurrent->session->id=$session; |
239
|
|
|
} |
240
|
|
|
if ($nls) { |
241
|
|
|
$rootoptions.="/$nls"; |
242
|
|
|
$ARCurrent->nls=$nls; |
243
|
|
|
} |
244
|
|
|
$root.=$rootoptions; |
245
|
|
|
if ($store) { // loader.php uses this function before the store is initialized. |
246
|
|
|
$store->root=$root; |
247
|
|
|
$store->rootoptions=$rootoptions; |
248
|
|
|
} |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
function ldSetNls($nls) { |
|
|
|
|
252
|
|
|
global $ARCurrent, $ARnls; |
253
|
|
|
|
254
|
|
|
$session=$ARCurrent->session->id; |
255
|
|
|
ldSetRoot($session, $nls); |
256
|
|
|
|
257
|
|
|
if( is_object( $ARnls ) ) { |
258
|
|
|
$ARnls->setLanguage($nls); |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
function ldGetRequestedHost() { |
|
|
|
|
263
|
|
|
global $AR; |
264
|
|
|
$requestedHost = $_SERVER['HTTP_X_FORWARDED_HOST']; |
265
|
|
|
if (!$requestedHost) { |
266
|
|
|
$requestedHost = $_SERVER['HTTP_HOST']; |
267
|
|
|
} |
268
|
|
|
$protocol = 'http://'; |
269
|
|
|
if ($_SERVER['HTTPS']=='on') { |
270
|
|
|
$protocol = 'https://'; |
271
|
|
|
} |
272
|
|
|
return $protocol . $requestedHost; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
function ldSetSession($session='') { |
|
|
|
|
276
|
|
|
global $AR, $ARCurrent; |
277
|
|
|
$nls=$ARCurrent->nls; |
278
|
|
|
if ($AR->hideSessionIDfromURL) { |
279
|
|
|
$cookies = (array) ldGetCredentials(); |
280
|
|
|
$https = ($_SERVER['HTTPS']=='on'); |
281
|
|
|
if( !isset($cookies[$ARCurrent->session->id]) && $ARCurrent->session->id !== 0) { |
282
|
|
|
$data = array(); |
283
|
|
|
$data['timestamp']=time(); |
284
|
|
|
$cookie=ldEncodeCookie($data); |
285
|
|
|
$cookiename = "ARSessionCookie[".$ARCurrent->session->id."]"; |
286
|
|
|
debug("setting cookie (".$ARCurrent->session->id.")(".$cookie.")"); |
287
|
|
|
header('P3P: CP="NOI CUR OUR"'); |
288
|
|
|
setcookie('ARCurrentSession', $ARCurrent->session->id, 0, '/', false, $https, true); |
289
|
|
|
setcookie($cookiename,$cookie, 0, '/', false, $https, true); |
290
|
|
|
} |
291
|
|
|
} |
292
|
|
|
ldSetRoot($session, $nls); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
View Code Duplication |
function ldStartSession($sessionid='') { |
|
|
|
|
296
|
|
|
global $ARCurrent, $AR, $ariadne; |
297
|
|
|
|
298
|
|
|
require($ariadne."/configs/sessions.phtml"); |
299
|
|
|
$ARCurrent->session=new session($session_config,$sessionid); |
|
|
|
|
300
|
|
|
ldSetSession($ARCurrent->session->id); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
function ldGetCookieSession() { |
|
|
|
|
304
|
|
|
return $_COOKIE['ARCurrentSession']; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
function ldSetCache($file, $time, $image, $headers) { |
|
|
|
|
308
|
|
|
global $store; |
309
|
|
|
|
310
|
|
|
debug("ldSetCache($file, $time, [image], [headers])","object"); |
311
|
|
View Code Duplication |
if ($time==-2) { |
312
|
|
|
$time=0; |
313
|
|
|
} else { |
314
|
|
|
$time=time()+($time*3600); |
315
|
|
|
} |
316
|
|
|
if (!preg_match("/\.\./",$file)) { |
317
|
|
|
if ($image) { |
318
|
|
|
$path=substr($file, 1, strrpos($file, "/")-1); |
319
|
|
View Code Duplication |
if (!file_exists($store->get_config("files")."cache/".$path)) { |
320
|
|
|
ldMkDir("cache/".$path); |
321
|
|
|
ldMkDir("cacheheaders/".$path); |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
$imagetemp = tempnam($store->get_config("files")."cache/".$path."/","ARCacheImage"); |
325
|
|
|
$headertemp = tempnam($store->get_config("files")."cacheheaders/".$path."/","ARCacheImage"); |
326
|
|
|
|
327
|
|
|
$fileimage = $store->get_config("files")."cache".$file; |
328
|
|
|
$fileheaders = $store->get_config("files")."cacheheaders".$file; |
329
|
|
|
|
330
|
|
|
$fpi=@fopen($imagetemp, "wb"); |
331
|
|
|
$fph=@fopen($headertemp, "wb"); |
332
|
|
|
|
333
|
|
|
if($fpi && $fph) { |
334
|
|
|
fwrite($fph, $headers); |
335
|
|
|
fclose($fph); |
336
|
|
|
$imagesize = fwrite($fpi, $image); |
337
|
|
|
fclose($fpi); |
338
|
|
|
|
339
|
|
|
if ( !touch($imagetemp, $time)) { |
340
|
|
|
debug("ldSetCache: ERROR: couldn't touch image","object"); |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
if (filesize($imagetemp) == $imagesize ) { |
344
|
|
|
rename($headertemp,$fileheaders); |
345
|
|
|
rename($imagetemp,$fileimage); |
346
|
|
|
} else { |
347
|
|
|
@unlink($imagetemp); |
|
|
|
|
348
|
|
|
@unlink($headertemp); |
|
|
|
|
349
|
|
|
} |
350
|
|
|
} else { |
351
|
|
|
if($fpi) { |
352
|
|
|
fclose($fpi); |
353
|
|
|
@unlink($imagetemp); |
|
|
|
|
354
|
|
|
} |
355
|
|
|
if($fph) { |
356
|
|
|
fclose($fph); |
357
|
|
|
@unlink($headertemp); |
|
|
|
|
358
|
|
|
} |
359
|
|
|
} |
360
|
|
|
} |
361
|
|
|
} |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
function ldMkDir($dir) { |
|
|
|
|
365
|
|
|
global $store; |
366
|
|
|
|
367
|
|
|
debug("ldMkDir($dir)","object"); |
368
|
|
|
$curr=$store->get_config("files"); |
369
|
|
|
@mkdir($curr.'/'.$dir, 0755, true); |
|
|
|
|
370
|
|
|
} |
371
|
|
|
|
372
|
|
View Code Duplication |
function ldGetUserCookie($cookiename="ARUserCookie") { |
|
|
|
|
373
|
|
|
$cookie = false; |
374
|
|
|
|
375
|
|
|
if( $_COOKIE[$cookiename] && !($cookiename == "ARSessionCookie") && !($cookiename == 'ARCurrentSession') ) { |
376
|
|
|
$ARUserCookie = $_COOKIE[$cookiename]; |
377
|
|
|
debug("ldGetUserCookie() = $ARUserCookie","object"); |
378
|
|
|
$cookie = json_decode($ARUserCookie,true); |
379
|
|
|
if ($cookie === null) { |
380
|
|
|
$cookie = unserialize($ARUserCookie); |
381
|
|
|
} |
382
|
|
|
} |
383
|
|
|
return $cookie; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
function ldSetConsentedCookie($cookie, $cookiename="ARUserCookie", $expire=0, $path="/", $domain="", $secure=0) { |
387
|
|
|
// Sets a cookie, but only when ARCookieConsent has been given. |
388
|
|
|
return ldSetUserCookie($cookie, $cookiename, $expire, $path, $domain, $secure, true); |
|
|
|
|
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
function ldSetUserCookie($cookie, $cookiename="ARUserCookie", $expire=0, $path="/", $domain="", $secure=0, $consentneeded=false) { |
|
|
|
|
392
|
|
|
$result = false; |
393
|
|
|
|
394
|
|
|
if (substr($cookiename, 0, strlen('ARSessionCookie'))=='ARSessionCookie' || $cookiename=='ARCurrentSession' ) { |
395
|
|
|
return false; |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
$cookieconsent = ldGetUserCookie("ARCookieConsent"); |
399
|
|
|
if (!$consentneeded || ($cookieconsent == true)) { // Only set cookies when consent has been given, or no consent is needed for this cookie. |
400
|
|
View Code Duplication |
if( $cookiename != "ARSessionCookie" && $cookiename != "ARCurrentSession" ) { |
401
|
|
|
$ARUserCookie=json_encode($cookie); |
402
|
|
|
debug("ldSetUserCookie(".$ARUserCookie.")","object"); |
403
|
|
|
header('P3P: CP="NOI CUR OUR"'); |
404
|
|
|
$result = setcookie($cookiename,$ARUserCookie, $expire, $path, $domain, $secure); |
405
|
|
|
} |
406
|
|
|
} else { |
407
|
|
|
debug("ldSetUserCookie: no consent. (".$ARUserCookie.")","object"); |
|
|
|
|
408
|
|
|
} |
409
|
|
|
return $result; |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
function ldRedirect($uri) { |
|
|
|
|
413
|
|
|
return ldHeader("Location: $uri"); |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
function ldHeader($header,$replace=true) { |
|
|
|
|
417
|
|
|
global $ARCurrent; |
418
|
|
|
$result=false; |
419
|
|
|
if ( !Headers_sent() && !$ARCurrent->arNoHeaders ) { |
420
|
|
|
$result=true; |
421
|
|
|
list($key,$value) = explode(':',$header,2); |
|
|
|
|
422
|
|
|
Header($header,$replace); |
423
|
|
View Code Duplication |
if($replace){ |
424
|
|
|
$ARCurrent->ldHeaders[strtolower($key)]=$header; |
425
|
|
|
} else { |
426
|
|
|
$ARCurrent->ldHeaders[strtolower($key)].=$header; |
427
|
|
|
} |
428
|
|
|
} |
429
|
|
|
return $result; |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
function ldSetBrowserCache( $settings ) { |
433
|
|
|
if ($settings === false) { |
434
|
|
|
return ldHeader("Cache-control: no-store, no-cache, must-revalidate, max-age=0, private"); |
435
|
|
|
} |
436
|
|
|
$cacheControl = "Cache-control: "; |
437
|
|
|
$cacheControl .= ($settings['browserCachePrivate'] ? "private" : "public"); |
438
|
|
|
$cacheControl .= ($settings['browserCacheNoStore'] ? ", no-store" : ""); |
439
|
|
|
$cacheControl .= ($settings['browserCacheNoCache'] ? ", no-cache" : ""); |
440
|
|
|
$cacheControl .= ($settings['browserCacheMustRevalidate'] ? ", must-revalidate" : ""); |
441
|
|
|
$cacheControl .= ($settings['browserCacheProxyRevalidate'] ? ", proxy-revalidate" : ""); |
442
|
|
|
$cacheControl .= ($settings['browserCacheNoTransform'] ? ", no-transform" : ""); |
443
|
|
|
$cacheControl .= ($settings['browserCacheMaxAge'] ? ", max-age=" . $settings['browserCacheMaxAge'] : ", max-age=0"); |
444
|
|
|
$cacheControl .= ($settings['browserCacheSMaxAge'] ? ", s-max-age=" . $settings['browserCacheMaxAge'] : ""); |
445
|
|
|
|
446
|
|
|
ldHeader($cacheControl); |
447
|
|
|
} |
448
|
|
|
|
449
|
|
|
function ldSetClientCache( $cache_on, $expires = null, $modified = null ) { |
|
|
|
|
450
|
|
|
$now = time(); |
451
|
|
|
if ($cache_on) { |
452
|
|
|
if ( !isset($expires) ) { |
453
|
|
|
$expires = $now + 1800; |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
// Give the client the max-age |
457
|
|
|
$maxage = $expires - $now; |
458
|
|
|
ldHeader("Cache-control: public, max-age=$maxage, must-revalidate"); |
459
|
|
|
ldHeader("X-Ariadne-Expires: $expires"); |
460
|
|
|
} else { |
461
|
|
|
ldHeader("Cache-control: no-store, no-cache, must-revalidate, max-age=0, private"); |
462
|
|
|
} |
463
|
|
|
return $result; |
|
|
|
|
464
|
|
|
} |
465
|
|
|
|
466
|
|
View Code Duplication |
function ldSetContent($mimetype, $size=0) { |
|
|
|
|
467
|
|
|
global $ARCurrent; |
468
|
|
|
$result=ldHeader("Content-Type: ".$mimetype); |
469
|
|
|
$ARCurrent->arContentTypeSent = true; |
470
|
|
|
if ($size) { |
471
|
|
|
$result=ldHeader("Content-Length: ".$size); |
472
|
|
|
} |
473
|
|
|
return $result; |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
function ldGetServerVar($server_var = "") { |
|
|
|
|
477
|
|
|
if (!$server_var) { |
478
|
|
|
return $_SERVER; |
479
|
|
|
} |
480
|
|
|
return $_SERVER[$server_var]; |
481
|
|
|
} |
482
|
|
|
|
483
|
|
View Code Duplication |
function ldGetClientVar($client_var) { |
|
|
|
|
484
|
|
|
// not all environment variables should be disclosed |
485
|
|
|
switch($client_var) { |
486
|
|
|
case "REMOTE_ADDR": $result = getenv("REMOTE_ADDR"); break; |
|
|
|
|
487
|
|
|
case "HTTP_USER_AGENT": $result = getenv("HTTP_USER_AGENT"); break; |
|
|
|
|
488
|
|
|
case "HTTP_ACCEPT": $result = getenv("HTTP_ACCEPT"); break; |
|
|
|
|
489
|
|
|
case "HTTP_ACCEPT_LANGUAGE": $result = getenv("HTTP_ACCEPT_LANGUAGE"); break; |
|
|
|
|
490
|
|
|
default: $result = false; break; |
|
|
|
|
491
|
|
|
} |
492
|
|
|
return $result; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
function ldDisablePostProcessing() { |
|
|
|
|
496
|
|
|
global $ARCurrent,$ldXSSProtectionActive,$ldOutputBufferActive; |
497
|
|
|
|
498
|
|
|
// only disable the cache when we don't have xss protection active |
499
|
|
|
if($ldXSSProtectionActive !== true && $ldOutputBufferActive === true) { |
500
|
|
|
/* |
501
|
|
|
kill the innermost output buffer, if there is any other buffering layers active |
502
|
|
|
in the end this will remove the outputbuffer used in the loader |
503
|
|
|
*/ |
504
|
|
|
|
505
|
|
|
ob_end_flush(); |
506
|
|
|
|
507
|
|
|
// because we are forceing the output, we can't cache it anymore, disable it for safety sake |
508
|
|
|
$ARCurrent->arDontCache = true; |
509
|
|
|
$ldOutputBufferActive=false; |
510
|
|
|
return true; |
511
|
|
|
} else if ($ldXSSProtectionActive === true) { |
512
|
|
|
return false; |
513
|
|
|
} else if ($ldOutputBufferActive === false) { |
514
|
|
|
return 2; |
515
|
|
|
} |
516
|
|
|
} |
517
|
|
|
|
518
|
|
|
function ldProcessCacheControl() { |
|
|
|
|
519
|
|
|
global $ARCurrent; |
520
|
|
|
if (isset($_SERVER["HTTP_CACHE_CONTROL"])) { |
521
|
|
|
$cc = $_SERVER["HTTP_CACHE_CONTROL"]; |
522
|
|
|
$parts = explode(',', $cc); |
523
|
|
|
foreach($parts as $part) { |
524
|
|
|
$part = trim ($part); |
525
|
|
|
list($key,$value) = explode('=', $part,2); |
526
|
|
|
$key = trim($key); |
527
|
|
|
switch($key) { |
528
|
|
|
case "no-cache": |
529
|
|
|
case "no-store": |
530
|
|
|
case "no-transform": |
531
|
|
|
case "only-if-cached": |
532
|
|
|
$ARCurrent->RequestCacheControl[$key] = true; |
533
|
|
|
break; |
534
|
|
|
case "max-age": |
535
|
|
|
case "max-stale": |
536
|
|
|
case "min-fresh": |
537
|
|
|
$value = (int)filter_var($value,FILTER_SANITIZE_NUMBER_INT); |
538
|
|
|
$ARCurrent->RequestCacheControl[$key] = $value; |
539
|
|
|
break; |
540
|
|
|
default: |
541
|
|
|
// do nothing |
542
|
|
|
break; |
543
|
|
|
} |
544
|
|
|
} |
545
|
|
|
} |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
function ldGatherXSSInput(&$xss, $input) { |
549
|
|
|
if (is_array($input)) { |
550
|
|
|
foreach ($input as $value) { |
551
|
|
|
ldGatherXSSInput($xss, $value); |
552
|
|
|
} |
553
|
|
|
} else { |
554
|
|
|
$input = (string)$input; |
555
|
|
|
if (strlen($input) > 10) { |
556
|
|
|
if (preg_match('/[\'"<>]/', $input)) { |
557
|
|
|
$xss[strlen($input)][$input] = $input; |
558
|
|
|
} |
559
|
|
|
} |
560
|
|
|
} |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
function ldCheckAllowedTemplate($template) { |
564
|
|
|
// Check if a template is allowed to be called directly from the URL. |
565
|
|
|
if ($template == "system.list.folders.json.php") { |
566
|
|
|
// FIXME: this template is used to fetch folders in explore - it should be renamed to explore.list.folders.json.php; |
|
|
|
|
567
|
|
|
return true; |
568
|
|
|
} else if ($template == "system.list.objects.json.php") { |
569
|
|
|
// FIXME: this template is used to fetch objects in explore - it should be renamed to explore.list.objects.json.php; |
|
|
|
|
570
|
|
|
return true; |
571
|
|
|
} else if (preg_match('/^(system|ftp|webdav|soap)\./', $template)) { |
572
|
|
|
// Disallow all direct calls to system.*, ftp.*, webdav.*, soap.* templates; |
573
|
|
|
// FTP, webdav, soap should use their own loader instead. |
574
|
|
|
return false; |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
return true; |
578
|
|
|
} |
579
|
|
|
|
580
|
|
|
function ldCacheRequest($AR_PATH_INFO=null) { |
581
|
|
|
ob_start(); |
582
|
|
|
|
583
|
|
|
global $ARCurrent; |
584
|
|
|
$ARCurrent->refreshCacheOnShutdown = true; |
585
|
|
|
ldProcessRequest($AR_PATH_INFO); |
586
|
|
|
ob_end_clean(); |
587
|
|
|
} |
588
|
|
|
|
589
|
|
|
function ldProcessRequest($AR_PATH_INFO=null) { |
|
|
|
|
590
|
|
|
global $AR; |
591
|
|
|
global $ARCurrent; |
592
|
|
|
global $store_config; |
593
|
|
|
global $auth_config; |
594
|
|
|
global $cache_config; |
595
|
|
|
global $store; |
596
|
|
|
global $context; |
597
|
|
|
global $DB; |
598
|
|
|
global $path; |
599
|
|
|
global $function; |
600
|
|
|
global $nls; |
601
|
|
|
|
602
|
|
|
$writecache = false; |
603
|
|
|
|
604
|
|
|
// go check for a sessionid |
605
|
|
|
$root=$AR->root; |
606
|
|
|
$session_id=0; |
607
|
|
|
$re="^/-(.{4})-/"; |
608
|
|
|
|
609
|
|
|
$originalPathInfo = $AR_PATH_INFO; // Store this to pass to the refresh cache on shutdown function; |
610
|
|
|
|
611
|
|
|
if (preg_match( '|'.$re.'|' , $AR_PATH_INFO , $matches )) { |
612
|
|
|
$session_id=$matches[1]; |
613
|
|
|
$AR_PATH_INFO=substr($AR_PATH_INFO,strlen($matches[0])-1); |
614
|
|
|
$AR->hideSessionIDfromURL=false; |
615
|
|
|
} elseif ($AR->hideSessionIDfromURL) { |
616
|
|
|
$cookies = (array) ldGetCredentials(); |
617
|
|
|
$current = ldGetCookieSession(); |
618
|
|
|
if ( array_key_exists( $current, $cookies ) ) { |
619
|
|
|
$session_id = $current; |
620
|
|
|
} |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
// set the default user (public) |
624
|
|
|
$AR->login="public"; |
625
|
|
|
|
626
|
|
|
|
627
|
|
|
// look for the template |
628
|
|
|
$split=strrpos($AR_PATH_INFO, "/"); |
629
|
|
|
$path=substr($AR_PATH_INFO,0,$split+1); |
630
|
|
|
$function=substr($AR_PATH_INFO,$split+1); |
631
|
|
|
if (!$function ) { |
632
|
|
|
if (!isset($arDefaultFunction) || $arDefaultFunction == '' ) { |
|
|
|
|
633
|
|
|
$arDefaultFunction="view.html"; |
634
|
|
|
} |
635
|
|
|
$function=$arDefaultFunction; |
636
|
|
|
if (isset($arFunctionPrefix) && $arFunctionPrefix != '' ) { |
|
|
|
|
637
|
|
|
$function=$arFunctionPrefix.$function; |
638
|
|
|
} |
639
|
|
|
$AR_PATH_INFO.=$function; |
640
|
|
|
} |
641
|
|
|
|
642
|
|
|
// yes, the extra '=' is needed, don't remove it. trust me. |
643
|
|
|
$ldCacheFilename=strtolower($AR_PATH_INFO)."="; |
644
|
|
|
// for the new multiple domains per site option (per language), we need this |
645
|
|
|
// since the nls isn't literaly in the url anymore. |
646
|
|
|
$ldCacheFilename.=str_replace(':','=',str_replace('/','',$AR->host)).'='; |
647
|
|
|
|
648
|
|
|
$qs = ldGetServerVar("QUERY_STRING"); |
649
|
|
|
if ($qs != '') { |
650
|
|
|
$ldCacheFilename.=sha1($qs); |
651
|
|
|
} |
652
|
|
|
|
653
|
|
|
if ( $session_id ) { |
654
|
|
|
$cachedimage=$store_config["files"]."cache/session".$ldCacheFilename; |
655
|
|
|
$cachedheader=$store_config["files"]."cacheheaders/session".$ldCacheFilename; |
656
|
|
|
} else { |
657
|
|
|
$cachedimage=$store_config["files"]."cache/normal".$ldCacheFilename; |
658
|
|
|
$cachedheader=$store_config["files"]."cacheheaders/normal".$ldCacheFilename; |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
if ($AR->ESI) { |
662
|
|
|
ob_start(); |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
$timecheck=time(); |
666
|
|
|
|
667
|
|
|
if (file_exists($cachedimage)) { |
668
|
|
|
$staleTotalTime = filemtime($cachedimage) - filectime($cachedimage); |
669
|
|
|
$staleCurrent = $timecheck - filectime($cachedimage); |
670
|
|
|
if( $staleTotalTime != 0) { |
671
|
|
|
$stalePercentage = sprintf("%.2f", 100 * $staleCurrent / $staleTotalTime); |
672
|
|
|
} else { |
673
|
|
|
$stalePercentage = 100; |
674
|
|
|
} |
675
|
|
|
if ($stalePercentage < 0) { |
676
|
|
|
$stalePercentage = 0; |
677
|
|
|
} else if ($stalePercentage > 100) { |
678
|
|
|
$stalePercentage = 100; |
679
|
|
|
} |
680
|
|
|
if (!headers_sent()) { |
681
|
|
|
header("X-Ariadne-Cache-Stale: $stalePercentage%"); |
682
|
|
|
} |
683
|
|
|
} |
684
|
|
|
|
685
|
|
|
// add min-fresh if the client asked for it |
686
|
|
|
if (isset($ARCurrent->RequestCacheControl["min-fresh"])) { |
687
|
|
|
$timecheck += $ARCurrent->RequestCacheControl["min-fresh"]; |
688
|
|
|
} |
689
|
|
|
|
690
|
|
|
if ( |
691
|
|
|
file_exists($cachedimage) && |
692
|
|
|
((($mtime=@filemtime($cachedimage)) > $timecheck) || ($mtime==0)) && |
693
|
|
|
($_SERVER["REQUEST_METHOD"]!="POST") && |
694
|
|
|
($ARCurrent->RequestCacheControl["no-cache"] != true ) && |
695
|
|
|
($ARCurrent->refreshCacheOnShutdown !== true) |
696
|
|
|
) { |
697
|
|
|
$ctime=filemtime($cachedimage); // FIXME: Waarom moet dit mtime zijn? Zonder mtime werkt de if-modified-since niet; |
|
|
|
|
698
|
|
|
|
699
|
|
|
if (rand(20,80) < $stalePercentage) { |
|
|
|
|
700
|
|
|
header("X-Ariadne-Cache-Refresh: refreshing on shutdown"); |
701
|
|
|
register_shutdown_function("ldCacheRequest", $originalPathInfo); // Rerun the request with the original path info; |
702
|
|
|
} else { |
703
|
|
|
header("X-Ariadne-Cache-Refresh: skipped, still fresh enough"); |
704
|
|
|
} |
705
|
|
|
|
706
|
|
|
if (!$AR->ESI && $_SERVER['HTTP_IF_MODIFIED_SINCE'] && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $ctime) { |
707
|
|
|
// the mtime is used as expiration time, the ctime is the correct last modification time. |
708
|
|
|
// as an object clears the cache upon a save. |
709
|
|
|
|
710
|
|
|
// Send the original headers - they will already contain the correct max-age and expires values; |
711
|
|
View Code Duplication |
if (file_exists($cachedheader)) { |
712
|
|
|
$filedata = file($cachedheader); |
713
|
|
|
if (is_array($filedata)) { |
714
|
|
|
while (list($key, $header)=each($filedata)) { |
|
|
|
|
715
|
|
|
ldHeader($header); |
716
|
|
|
} |
717
|
|
|
} |
718
|
|
|
} |
719
|
|
|
header("X-Ariadne-Cache: Hit"); |
720
|
|
|
ldHeader("HTTP/1.1 304 Not Modified"); |
721
|
|
|
} else { |
722
|
|
View Code Duplication |
if (file_exists($cachedheader)) { |
723
|
|
|
// Cache header file also contains information about Cache-control; |
724
|
|
|
$filedata = file($cachedheader); |
725
|
|
|
if (is_array($filedata)) { |
726
|
|
|
while (list($key, $header)=each($filedata)) { |
|
|
|
|
727
|
|
|
ldHeader($header); |
728
|
|
|
} |
729
|
|
|
} |
730
|
|
|
} |
731
|
|
|
header("X-Ariadne-Cache: Hit"); // Send this after the cached headers to overwrite the cached cache-miss header; |
732
|
|
|
|
733
|
|
|
if ($AR->ESI) { |
734
|
|
|
if (false && $_SERVER['HTTP_IF_MODIFIED_SINCE'] && (strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $ctime)) { |
735
|
|
|
ldHeader("HTTP/1.1 304 Not modified"); |
736
|
|
|
} else { |
737
|
|
|
$data = file_get_contents($cachedimage); |
738
|
|
|
include_once($store_config['code']."modules/mod_esi.php"); |
739
|
|
|
|
740
|
|
|
// Replace the session IDs before the ESI process call to pass the correct session ID information... |
741
|
|
View Code Duplication |
if ($session_id && !$AR->hideSessionIDfromURL) { |
742
|
|
|
$tag = '{arSessionID}'; |
743
|
|
|
$data = str_replace($tag, "-$session_id-", $data); |
744
|
|
|
} |
745
|
|
|
|
746
|
|
|
$data = ESI::esiProcess($data); |
747
|
|
|
|
748
|
|
|
// ... and then replace the session IDs that were generated in de ESI case; |
749
|
|
|
$tag = '{arSessionID}'; |
750
|
|
|
if ($session_id && !$AR->hideSessionIDfromURL) { |
751
|
|
|
$data = str_replace($tag, "-$session_id-", $data); |
752
|
|
|
} else if ($session_id && $AR->hideSessionIDfromURL ) { |
753
|
|
|
$data = str_replace($tag, '', $data); |
754
|
|
|
} |
755
|
|
|
echo $data; |
756
|
|
|
} |
757
|
|
|
|
758
|
|
|
} else if ($session_id) { |
759
|
|
|
$tag = '{arSessionID}'; |
|
|
|
|
760
|
|
|
$data = file_get_contents($cachedimage); |
761
|
|
|
$tag = '{arSessionID}'; |
762
|
|
View Code Duplication |
if (!$AR->hideSessionIDfromURL) { |
763
|
|
|
$data = str_replace($tag, "-$session_id-", $data); |
764
|
|
|
} else { |
765
|
|
|
$data = str_replace($tag, '', $data); |
766
|
|
|
} |
767
|
|
|
echo $data; |
768
|
|
|
} else { |
769
|
|
|
readfile($cachedimage); |
770
|
|
|
} |
771
|
|
|
} |
772
|
|
|
$writecache = false; // Prevent recaching cached image; |
773
|
|
|
} else { |
774
|
|
|
if (!headers_sent()) { |
775
|
|
|
header("X-Ariadne-Cache: Miss"); |
776
|
|
|
} |
777
|
|
|
|
778
|
|
|
/* |
779
|
|
|
start output buffering |
780
|
|
|
*/ |
781
|
|
|
ob_start(); |
782
|
|
|
global $ldOutputBufferActive; |
783
|
|
|
$ldOutputBufferActive = true; |
784
|
|
|
ob_implicit_flush(0); |
785
|
|
|
|
786
|
|
|
// look for the language |
787
|
|
|
$split=strpos(substr($AR_PATH_INFO, 1), "/"); |
788
|
|
|
$ARCurrent->nls=substr($path, 1, $split); |
789
|
|
|
if (!isset($AR->nls->list[$ARCurrent->nls]) ) { |
790
|
|
|
// not a valid language |
791
|
|
|
$ARCurrent->nls=""; |
792
|
|
|
$nls=$AR->nls->default; |
793
|
|
|
// but we can find out if the user has any preferences |
794
|
|
|
preg_match_all("%([a-zA-Z]{2}|\\*)[a-zA-Z-]*(?:;q=([0-9.]+))?%", $_SERVER["HTTP_ACCEPT_LANGUAGE"], $regs, PREG_SET_ORDER); |
795
|
|
|
$ARCurrent->acceptlang=array(); |
796
|
|
|
$otherlangs=array(); |
797
|
|
|
$otherq=false; |
798
|
|
View Code Duplication |
foreach ($regs as $reg) { |
|
|
|
|
799
|
|
|
if (!isset($reg[2])) { |
800
|
|
|
$reg[2]=1; |
801
|
|
|
} |
802
|
|
|
if ($reg[1]=="*") { |
803
|
|
|
$otherq=$reg[2]; |
804
|
|
|
} else if ($AR->nls->list[$reg[1]]) { |
805
|
|
|
$otherlangs[]=$reg[1]; |
806
|
|
|
$ARCurrent->acceptlang[$reg[1]]=$reg[2]; |
807
|
|
|
} |
808
|
|
|
} |
809
|
|
View Code Duplication |
if ($otherq !== false) { |
810
|
|
|
$otherlangs=array_diff(array_keys($AR->nls->list), $otherlangs); |
811
|
|
|
foreach ($otherlangs as $lang) { |
812
|
|
|
$ARCurrent->acceptlang[$lang]=$otherq; |
813
|
|
|
} |
814
|
|
|
} |
815
|
|
|
arsort($ARCurrent->acceptlang); |
816
|
|
|
} else { |
817
|
|
|
// valid language |
818
|
|
|
$path=substr($path, $split+1); |
819
|
|
|
// ldSetNls($ARCurrent->nls); |
|
|
|
|
820
|
|
|
$nls=$ARCurrent->nls; |
821
|
|
|
} |
822
|
|
|
|
823
|
|
|
$args=array_merge($_GET,$_POST); |
824
|
|
|
|
825
|
|
|
// instantiate the store |
826
|
|
|
$inst_store = $store_config["dbms"]."store"; |
827
|
|
|
$store=new $inst_store($root,$store_config); |
828
|
|
|
//$store->rootoptions = $rootoptions; |
|
|
|
|
829
|
|
|
|
830
|
|
|
if ($session_id) { |
831
|
|
|
ldStartSession($session_id); |
832
|
|
|
} |
833
|
|
|
|
834
|
|
|
// instantiate the ARnls |
835
|
|
|
if( $ARCurrent->nls != "" ) { |
836
|
|
|
ldSetNls($nls); |
837
|
|
|
} |
838
|
|
|
|
839
|
|
|
|
840
|
|
|
if (substr($function, -6)==".phtml") { |
841
|
|
|
// system template: no language check |
842
|
|
|
$ARCurrent->nolangcheck=1; |
843
|
|
|
} |
844
|
|
|
$ext = pathinfo($function, PATHINFO_EXTENSION); |
845
|
|
|
switch ( $ext ) { |
846
|
|
|
case 'css': |
847
|
|
|
ldSetContent('text/css; charset=utf-8'); |
848
|
|
|
break; |
849
|
|
|
case 'js': |
850
|
|
|
ldSetContent('application/javascript; charset=utf-8'); |
851
|
|
|
break; |
852
|
|
|
case 'json': |
853
|
|
|
ldSetContent('application/json; charset=utf-8'); |
854
|
|
|
break; |
855
|
|
|
case 'xml': |
856
|
|
|
ldSetContent('text/xml; charset=utf-8'); |
857
|
|
|
break; |
858
|
|
|
case 'jpg': |
859
|
|
|
ldSetContent('image/jpeg'); |
860
|
|
|
break; |
861
|
|
|
case 'gif': |
862
|
|
|
ldSetContent('image/gif'); |
863
|
|
|
break; |
864
|
|
|
case 'png': |
865
|
|
|
ldSetContent('image/png'); |
866
|
|
|
break; |
867
|
|
|
case 'svg': |
868
|
|
|
ldSetContent('image/svg+xml'); |
869
|
|
|
break; |
870
|
|
|
default: |
871
|
|
|
ldSetContent('text/html; charset=utf-8'); |
872
|
|
|
break; |
873
|
|
|
} |
874
|
|
|
$ARCurrent->arContentTypeSent = true; |
875
|
|
|
|
876
|
|
|
register_shutdown_function("ldOnFinish"); |
877
|
|
|
|
878
|
|
|
$auth_class = "mod_auth_".$auth_config["method"]; |
879
|
|
|
$mod_auth = new $auth_class($auth_config); |
880
|
|
|
$username = ( isset($args["ARLogin"]) ? $args["ARLogin"] : null ); |
881
|
|
|
$password = ( isset($args["ARPassword"]) ? $args["ARPassword"] : null ); |
882
|
|
|
$result = $mod_auth->checkLogin($username, $password, $path); |
883
|
|
|
if ($result!==true) { |
884
|
|
|
if ($result == LD_ERR_ACCESS) { |
885
|
|
|
ldAccessDenied($path, $ARnls["accessdenied"], $args, $function); |
|
|
|
|
886
|
|
|
$function = false; |
887
|
|
|
} else if ($result == LD_ERR_SESSION && !$AR->hideSessionIDfromURL ) { |
888
|
|
|
ldAccessTimeout($path, $ARnls["sessiontimeout"], $args, $function); |
889
|
|
|
$function = false; |
890
|
|
|
} else if ($result == LD_ERR_EXPIRED) { |
891
|
|
|
ldAccessPasswordExpired($path, $ARnls["sessionpasswordexpired"], $args, $function); |
892
|
|
|
$function = false; |
893
|
|
|
} |
894
|
|
|
} |
895
|
|
|
|
896
|
|
|
// valid new login, without a session, morph to login.redirect.php to redirect to a session containing url |
897
|
|
|
if( !$session_id && $args["ARLogin"] && $args["ARPassword"] && $function !== false && !$AR->hideSessionIDfromURL ) { |
898
|
|
View Code Duplication |
if (!$ARCurrent->session->get("oldArCallArgs", 1)) { |
899
|
|
|
$ARCurrent->session->put("oldGET", $_GET, 1); |
900
|
|
|
$ARCurrent->session->put("oldPOST", $_POST, 1); |
901
|
|
|
$ARCurrent->session->put("oldArCallArgs", $args, 1); |
902
|
|
|
$ARCurrent->session->save(0, true); |
903
|
|
|
} |
904
|
|
|
if ($arDefaultFunction !== $function) { |
|
|
|
|
905
|
|
|
$args["arRequestedTemplate"] = $function; |
906
|
|
|
} else { |
907
|
|
|
$args["arRequestedTemplate"] = ""; |
908
|
|
|
} |
909
|
|
|
$function = "login.redirect.php"; |
910
|
|
|
} else if( $session_id ) { |
911
|
|
|
if ($ARCurrent->session->get("ARSessionTimedout", 1)) { |
912
|
|
View Code Duplication |
if (!$ARCurrent->session->get("oldArCallArgs", 1)) { |
913
|
|
|
$ARCurrent->session->put("oldGET", $_GET, 1); |
914
|
|
|
$ARCurrent->session->put("oldPOST", $_POST, 1); |
915
|
|
|
$ARCurrent->session->put("oldArCallArgs", $args, 1); |
916
|
|
|
$ARCurrent->session->save(0, true); |
917
|
|
|
} |
918
|
|
|
} else { |
919
|
|
|
if ($ARCurrent->session->get("oldArCallArgs", 1)) { |
920
|
|
|
$_GET = array_merge( $_GET, (array)$ARCurrent->session->get("oldGET", 1) ); |
921
|
|
|
$_POST = array_merge( $_POST, (array)$ARCurrent->session->get("oldPOST", 1) ); |
922
|
|
|
$args = $ARCurrent->session->get("oldArCallArgs", 1); |
923
|
|
|
$args = array_merge( $_GET, $_POST, $args); // $args, $_GET, $_POST ); |
|
|
|
|
924
|
|
|
$ARCurrent->session->put("oldArCallArgs", "", 1); |
925
|
|
|
$ARCurrent->session->put("oldGET", "", 1); |
926
|
|
|
$ARCurrent->session->put("oldPOST", "", 1); |
927
|
|
|
} |
928
|
|
|
} |
929
|
|
|
} |
930
|
|
|
|
931
|
|
|
$xss_vars = array(); |
932
|
|
|
ldGatherXSSInput($xss_vars, $_GET); |
933
|
|
|
ldGatherXSSInput($xss_vars, $_POST); |
934
|
|
|
$filenames = array_map(function ($e) { return $e['name']; }, $_FILES); |
935
|
|
|
ldGatherXSSInput($xss_vars, $filenames); |
936
|
|
|
|
937
|
|
|
ldGatherXSSInput( $xss_vars, $function ); |
938
|
|
|
ldGatherXSSInput( $xss_vars, $path ); |
939
|
|
|
global $ldXSSProtectionActive; |
940
|
|
|
if (count($xss_vars)) { |
941
|
|
|
$ldXSSProtectionActive = true; |
942
|
|
|
} |
943
|
|
|
|
944
|
|
|
if ($function!==false) { |
945
|
|
|
// finally call the requested object |
946
|
|
|
unset($store->total); |
947
|
|
|
if (ldCheckAllowedTemplate($function) ) { |
948
|
|
|
$store->call($function, $args, $store->get($path)); |
949
|
|
|
$writecache = true; |
950
|
|
|
} |
951
|
|
|
if (!$store->total) { |
952
|
|
|
ldObjectNotFound($path, $function, $args); |
|
|
|
|
953
|
|
|
} |
954
|
|
|
} |
955
|
|
|
|
956
|
|
|
if (count($xss_vars)) { |
957
|
|
|
$image = ob_get_contents(); |
958
|
|
|
ob_clean(); |
959
|
|
|
|
960
|
|
|
$header = $ARCurrent->ldHeaders["content-type"]; |
961
|
|
|
$xssDetected = false; |
962
|
|
|
preg_match('/^content-type:\s+([^ ;]+)/i', $header, $matches); |
963
|
|
|
$mimetype = strtolower($matches[1]); |
964
|
|
|
if (substr($mimetype, 0, 5) == 'text/') { |
965
|
|
|
krsort($xss_vars, SORT_NUMERIC); |
966
|
|
|
foreach ($xss_vars as $values) { |
967
|
|
|
if (is_array($values)) { |
968
|
|
|
foreach ($values as $value) { |
969
|
|
|
$occurances = substr_count($image, $value); |
970
|
|
|
if ($occurances > 0 ) { |
971
|
|
|
$xssDetected = true; |
972
|
|
|
break 2; |
973
|
|
|
} |
974
|
|
|
} |
975
|
|
|
} |
976
|
|
|
} |
977
|
|
|
} |
978
|
|
|
|
979
|
|
|
if ($xssDetected) { |
980
|
|
|
$newargs = array(); |
981
|
|
|
$newargs["arRequestedArgs"] = $args; |
982
|
|
|
$newargs["arRequestedTemplate"] = $function; |
983
|
|
|
$newargs["arSuspectedArgs"] = $xss_vars; |
984
|
|
|
$newargs["arResultOutput"] = $image; |
985
|
|
|
$store->call('user.xss.html', $newargs, $store->get($path)); |
986
|
|
|
} else { |
987
|
|
|
echo $image; |
988
|
|
|
} |
989
|
|
|
} |
990
|
|
|
} |
991
|
|
|
|
992
|
|
|
// now check for outputbuffering (caching) |
993
|
|
|
if ($image=ob_get_contents()) { |
994
|
|
|
// Calculate browser side cache settings based on settings collected in the call chain; |
995
|
|
|
// |
996
|
|
|
// Rules: do not cache wins. short cache time wins over longer cache time. Unset values don't get to play. |
997
|
|
|
// |
998
|
|
|
// Overlord rule: if the request method was not a get, or debugging was used, do not cache. Ever. |
999
|
|
|
// |
1000
|
|
|
// If pinp says arDontCache, then do not cache; |
1001
|
|
|
// |
1002
|
|
|
// If ESI was used and hit a cached image, use the cache settings from the cache image; |
1003
|
|
|
if ($_SERVER['REQUEST_METHOD']!='GET' || ($DB["wasUsed"] > 0)) { |
1004
|
|
|
// Do not cache on client. |
1005
|
|
|
ldSetBrowserCache(false); |
1006
|
|
|
} else if (is_array($ARCurrent->cache) && ($file=array_pop($ARCurrent->cache))) { |
1007
|
|
|
// This will generate an error, do not cache on client; |
1008
|
|
|
ldSetBrowserCache(false); |
1009
|
|
|
} else if ($ARCurrent->arDontCache) { |
1010
|
|
|
// PINP told us not to cache; |
1011
|
|
|
ldSetBrowserCache(false); |
1012
|
|
|
} else if (!$writecache) { |
|
|
|
|
1013
|
|
|
// Image came from the cache, it already has browser cache headers; |
1014
|
|
|
} else { |
1015
|
|
|
// Defaults for browser caching; |
1016
|
|
|
// Calls without session: public, max-age 1800; |
1017
|
|
|
// Calls with session without call chain (disk templates): private, no-cache no-store must-revalidate max-age=0 |
1018
|
|
|
// Calls with session with call chain (pinp templates): private, max-age=1800; |
1019
|
|
|
// FIXME: Make the calls with session less trigger happy on not caching; |
|
|
|
|
1020
|
|
|
|
1021
|
|
|
/* if ($session_id && sizeof($ARCurrent->cacheCallChainSettings)) { |
|
|
|
|
1022
|
|
|
// With session and pinp templates; |
1023
|
|
|
$browserCachePrivate = true; |
1024
|
|
|
$browserCacheMaxAge = 1800; |
1025
|
|
|
$browserCacheNoStore = false; |
1026
|
|
|
$browserCacheNoCache = false; |
1027
|
|
|
$browserCacheMustRevalidate = false; |
1028
|
|
|
} else */ |
1029
|
|
|
if ($session_id) { |
1030
|
|
|
// With session, disk templates only |
1031
|
|
|
$browserCachePrivate = true; |
1032
|
|
|
$browserCacheMaxAge = 0; |
1033
|
|
|
$browserCacheNoStore = true; |
1034
|
|
|
$browserCacheNoCache = true; |
1035
|
|
|
$browserCacheMustRevalidate = true; |
1036
|
|
|
} else { |
1037
|
|
|
// Without session and all other corner cases; |
1038
|
|
|
$browserCachePrivate = false; |
1039
|
|
|
$defaultMaxAge = 1800; |
1040
|
|
|
$browserCacheNoStore = false; |
1041
|
|
|
$browserCacheNoCache = false; |
1042
|
|
|
$browserCacheMustRevalidate = false; |
1043
|
|
|
} |
1044
|
|
|
|
1045
|
|
|
$browserCachecacheSetting = 0; // Default = inherit; |
|
|
|
|
1046
|
|
|
|
1047
|
|
|
// FIXME: The defaults for with session ID are now to not cache; |
|
|
|
|
1048
|
|
|
if(is_array($ARCurrent->cacheCallChainSettings) ) { |
1049
|
|
|
foreach ($ARCurrent->cacheCallChainSettings as $objectId => $pathCacheSetting) { |
1050
|
|
|
$browserCachePrivate = $browserCachePrivate || $pathCacheSetting['browserCachePrivate']; // If anyone says 'private', make it so. |
1051
|
|
|
$browserCacheNoStore = $browserCacheNoStore || $pathCacheSetting['browserCacheNoStore']; // If anyone says 'no-store', make it so. |
1052
|
|
|
$browserCacheNoCache = $browserCacheNoCache || $pathCacheSetting['browserCacheNoCache']; // If anyone says 'no-cache', make it so. |
1053
|
|
|
$browserCacheMustRevalidate = $browserCacheMustRevalidate || $pathCacheSetting['browserCacheMustRevalidate']; // If anyone says 'must-revalidate', make it so. |
1054
|
|
|
$browserCacheNoTransform = $browserCacheNoTransform || $pathCacheSetting['browserCacheNoTransform']; // If anyone says 'no-transform', make it so. |
|
|
|
|
1055
|
|
|
$browserCacheProxyRevalidate = $browserCacheProxyRevalidate || $pathCacheSetting['browserCacheProxyRevalidate']; // If anyone says 'proxy-revalidate', make it so. |
|
|
|
|
1056
|
|
|
|
1057
|
|
View Code Duplication |
if (isset($pathCacheSetting['browserCacheMaxAge']) && is_numeric($pathCacheSetting['browserCacheMaxAge'])) { |
1058
|
|
|
if (isset($browserCacheMaxAge)) { |
1059
|
|
|
$browserCacheMaxAge = min($browserCacheMaxAge, $pathCacheSetting['browserCacheMaxAge']); |
1060
|
|
|
} else { |
1061
|
|
|
$browserCacheMaxAge = $pathCacheSetting['browserCacheMaxAge']; |
1062
|
|
|
} |
1063
|
|
|
} |
1064
|
|
|
|
1065
|
|
View Code Duplication |
if (isset($pathCacheSetting['browserCacheSMaxAge']) && is_numeric($pathCacheSetting['browserCacheMaxAge'])) { |
1066
|
|
|
if (isset($browserCacheSMaxAge)) { |
1067
|
|
|
$browserCacheSMaxAge = min($browserCacheSMaxAge, $pathCacheSetting['browserCacheSMaxAge']); |
1068
|
|
|
} else { |
1069
|
|
|
$browserCacheSMaxAge = $pathCacheSetting['browserCacheSMaxAge']; |
1070
|
|
|
} |
1071
|
|
|
} |
1072
|
|
|
} |
1073
|
|
|
|
1074
|
|
|
if (!isset($browserCacheMaxAge) && isset($defaultMaxAge)) { |
1075
|
|
|
$browserCacheMaxAge = $defaultMaxAge; |
1076
|
|
|
} |
1077
|
|
|
} |
1078
|
|
|
|
1079
|
|
|
ldSetBrowserCache( |
1080
|
|
|
array( |
1081
|
|
|
"browserCachePrivate" => $browserCachePrivate, |
1082
|
|
|
"browserCacheNoStore" => $browserCacheNoStore, |
1083
|
|
|
"browserCacheNoCache" => $browserCacheNoCache, |
1084
|
|
|
"browserCacheMustRevalidate" => $browserCacheMustRevalidate, |
1085
|
|
|
"browserCacheNoTransform" => $browserCacheNoTransform, |
1086
|
|
|
"browserCacheProxyRevalidate" => $browserCacheProxyRevalidate, |
1087
|
|
|
"browserCacheMaxAge" => $browserCacheMaxAge, |
|
|
|
|
1088
|
|
|
"browserCacheSMaxAge" => $browserCacheSMaxAge |
|
|
|
|
1089
|
|
|
) |
1090
|
|
|
); |
1091
|
|
|
} |
1092
|
|
|
|
1093
|
|
|
|
1094
|
|
|
$image_len = strlen($image); |
1095
|
|
|
|
1096
|
|
|
if ($ARCurrent->session && $ARCurrent->session->id) { |
1097
|
|
|
$ldCacheFilename = "/session".$ldCacheFilename; |
1098
|
|
|
$image = str_replace('-'.$ARCurrent->session->id.'-', '{arSessionID}', $image); |
1099
|
|
|
} else { |
1100
|
|
|
$ldCacheFilename = "/normal".$ldCacheFilename; |
1101
|
|
|
} |
1102
|
|
|
// because we have the full content, we can now also calculate the content length |
1103
|
|
|
ldHeader("Content-Length: ".$image_len); |
1104
|
|
|
|
1105
|
|
|
|
1106
|
|
|
// flush the buffer, this will send the contents to the browser |
1107
|
|
|
ob_end_flush(); |
1108
|
|
|
debug("loader: ob_end_flush()","all"); |
1109
|
|
|
|
1110
|
|
|
|
1111
|
|
|
// Calculate server side cache settings based on settings collected in the call chain; |
1112
|
|
|
// |
1113
|
|
|
// Rules: do not cache wins. short cache time wins over longer cache time. Unset values don't get to play. |
1114
|
|
|
// |
1115
|
|
|
// Overlord rule: if the request method was not a get, or debugging was used, do not cache. Ever. |
1116
|
|
|
// |
1117
|
|
|
// If pinp says arDontCache, then do not cache; |
1118
|
|
|
// |
1119
|
|
|
// If ESI was used and hit a cached image, do not write the image; |
1120
|
|
|
|
1121
|
|
|
if ($_SERVER['REQUEST_METHOD']!='GET' || ($DB["wasUsed"] > 0)) { |
|
|
|
|
1122
|
|
|
// Do not cache on server. |
1123
|
|
|
// header("X-Ariadne-Cache-Skipped: DB Used"); |
|
|
|
|
1124
|
|
|
} else if (is_array($ARCurrent->cache) && ($file=array_pop($ARCurrent->cache))) { |
1125
|
|
|
error("cached() opened but not closed with savecache()"); |
1126
|
|
|
// header("X-Ariadne-Cache-Skipped: cached problem."); |
|
|
|
|
1127
|
|
|
} else if ($ARCurrent->arDontCache) { |
|
|
|
|
1128
|
|
|
// PINP told us not to cache; |
1129
|
|
|
// header("X-Ariadne-Cache-Skipped: arDontCache"); |
|
|
|
|
1130
|
|
|
} else if (!$writecache) { |
|
|
|
|
1131
|
|
|
// ESI was used and hit a cached image, do not write the image; |
1132
|
|
|
// header("X-Ariadne-Cache-Skipped: cached image used"); |
|
|
|
|
1133
|
|
|
} else { |
1134
|
|
|
// header("X-Ariadne-Cache-Skipped: Writing cache now"); |
|
|
|
|
1135
|
|
|
// Cache setting values: |
1136
|
|
|
// -2 = Refresh on change; Set the cache time on server to 999 hours (unlimited); |
1137
|
|
|
// -1 = Do not cache |
1138
|
|
|
// 0 = Inherit |
1139
|
|
|
// > 0: Refresh on request. The number is the amount of hours that the cache is 'fresh'. This can be a fraction/float value; |
1140
|
|
|
|
1141
|
|
|
$cacheSetting = 0; // Default = inherit; |
1142
|
|
|
$serverCachePrivate = 0; // do not allow caching of sessions |
1143
|
|
|
if( is_array($ARCurrent->cacheCallChainSettings)) { |
1144
|
|
|
foreach ($ARCurrent->cacheCallChainSettings as $objectId => $pathCacheSetting) { |
1145
|
|
|
// FIXME: also 'resolve' $serverCachePrivate |
|
|
|
|
1146
|
|
|
$serverCache = $pathCacheSetting['serverCache']; |
1147
|
|
|
|
1148
|
|
|
if ($serverCache == 0 || !isset($serverCache)) { |
1149
|
|
|
// This path does not want to play; |
1150
|
|
|
$serverCache = $pathCacheSetting['serverCacheDefault']; |
1151
|
|
|
} |
1152
|
|
|
|
1153
|
|
|
if ($serverCache == -2) { |
1154
|
|
|
// Sorry, we meant that the cache image should be valid forever; |
1155
|
|
|
$serverCache = 999; |
1156
|
|
|
} |
1157
|
|
|
|
1158
|
|
|
if ($cacheSetting == 0) { |
1159
|
|
|
$cacheSetting = $serverCache; |
1160
|
|
|
} else { |
1161
|
|
|
$cacheSetting = min($serverCache, $cacheSetting); |
1162
|
|
|
} |
1163
|
|
|
|
1164
|
|
|
if ($cacheSetting == -1) { |
1165
|
|
|
// If someone told us to not cache, skip checking because nothing anyone else tells us will change this fact. |
1166
|
|
|
break; |
1167
|
|
|
} |
1168
|
|
|
} |
1169
|
|
|
} |
1170
|
|
|
// header("X-Ariadne-Cache-Setting: $cacheSetting"); |
|
|
|
|
1171
|
|
|
if ($ARCurrent->session->id && $cacheSetting > 0) { |
1172
|
|
|
// we have a session id, can we cache ? |
1173
|
|
|
// FIXME: add support for $serverCachePrivate in the config and cache dialog |
|
|
|
|
1174
|
|
|
if ( ! ( $serverCachePrivate === 1 || $ARCurrent->arDoCachePrivate != false ) ) { |
1175
|
|
|
$cacheSetting = -1; |
1176
|
|
|
} |
1177
|
|
|
} |
1178
|
|
|
|
1179
|
|
|
if ($cacheSetting > 0) { |
1180
|
|
|
// If we are allowed to cache, write the image now. |
1181
|
|
|
if ($store) { // Sanity check to only write cache images if a store was initialized; |
1182
|
|
|
// FIXME: cacheCallChainSettings contains the objects that were called for this cache image; |
|
|
|
|
1183
|
|
|
// FIXME: cacheTemplateChain containers the templates that were called for this cache image; |
|
|
|
|
1184
|
|
|
|
1185
|
|
|
ldSetCache($ldCacheFilename, $cacheSetting, $image, @implode("\n",$ARCurrent->ldHeaders)); |
1186
|
|
|
$cachestore=new cache($cache_config); |
1187
|
|
|
$cachestore->save($ldCacheFilename, $ARCurrent->cacheCallChainSettings, $ARCurrent->cacheTemplateChain); |
1188
|
|
|
} |
1189
|
|
|
} |
1190
|
|
|
} |
1191
|
|
|
|
1192
|
|
|
} |
1193
|
|
|
|
1194
|
|
|
if ($AR->ESI > 0) { |
1195
|
|
|
// Prevent ESI from looping when the ESI result has ESI tags in them. |
1196
|
|
|
// Reducing the AR->ESI number by 1 gives the flexibility to allow 2 or 3 ESI loops if desired. |
1197
|
|
|
// Setting it to false would mean you only get 1 ESI loop, which might not be the desired effect. |
1198
|
|
|
$AR->ESI = (int) $AR->ESI; |
1199
|
|
|
$AR->ESI--; |
1200
|
|
|
|
1201
|
|
|
$image = ob_get_contents(); |
1202
|
|
|
ob_end_clean(); |
1203
|
|
|
include_once($store_config['code']."modules/mod_esi.php"); |
1204
|
|
|
$image = ESI::esiProcess($image); |
1205
|
|
|
$image_len = strlen($image); |
1206
|
|
|
|
1207
|
|
|
if ($ARCurrent->arDontCache) { |
1208
|
|
|
// FIXME: ook de cachetime 'niet cachen' uit het cachedialoog werkend maken... || $ARCurrent->cachetime == 0) { |
|
|
|
|
1209
|
|
|
ldSetBrowserCache(false); |
1210
|
|
|
} |
1211
|
|
|
ldHeader("Content-Length: ".$image_len); |
1212
|
|
|
echo $image; |
1213
|
|
|
} |
1214
|
|
|
} |
1215
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.