function _DownloadFile($filename = "", $cacheSeconds = 1800, $contentType = "application/zip") { global $AR; $context = pobject::getContext(); $me = $context['arCurrentObject']; $size = filesize($this->_filename); ldSetContent($contentType, $size); $expires = time() + $cacheSeconds; if ($AR->user->data->login == "public" || $me->CheckPublic("read")) { ldSetClientCache(true, $expires); } if ($filename) { ldHeader("Content-Disposition: attachment; filename={$filename}"); ldHeader("Content-length:" . (string) $size); } readfile($this->_filename); }
public function CheckConfig($arCallFunction = "", $arCallArgs = "") { // returns true when cache isn't up to date and no other template is // defined for $path/$function. Else it takes care of output to the // browser. // All these templates must exist under a fixed directory, $AR->dir->templates global $nocache, $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls, $ARConfigChecked; $MAX_LOOP_COUNT = 10; // system templates (.phtml) have $arCallFunction=='', so the first check in the next line is to // make sure that loopcounts don't apply to those templates. if (0 && $arCallFunction && $ARBeenHere[$this->path][$arCallFunction] > $MAX_LOOP_COUNT) { // protect against infinite loops error(sprintf($ARnls["err:maxloopexceed"], $this->path, $arCallFunction, $arCallArgs)); $this->store->close(); exit; } else { $ARBeenHere[$this->path][$arCallFunction] += 1; // this will prevent the parents from setting the cache time $initialConfigChecked = $ARConfigChecked; $ARConfigChecked = true; $config = $ARConfig->cache[$this->path] ? $ARConfig->cache[$this->path] : $this->loadConfig(); $ARConfigChecked = $initialConfigChecked; $ARConfig->nls = $config->nls; // if a default language is entered in a parent and no language is // explicitly selected in the url, use that default. // The root starts with the system default (ariadne.phtml config file) if (!$ARCurrent->nls) { if ($config->root['nls']) { $this->reqnls = $config->root['nls']; if (!$ARConfigChecked) { $ARCurrent->nls = $this->reqnls; } } else { if ($config->nls->default) { $this->reqnls = $config->nls->default; $this->nls = $this->reqnls; if (!$ARConfigChecked) { $ARCurrent->nls = $this->nls; } } } } else { $this->reqnls = $ARCurrent->nls; } $nls =& $this->nls; $reqnls =& $this->reqnls; if (!$ARConfigChecked && is_object($ARnls)) { $ARnls->setLanguage($ARCurrent->nls); } if (!$ARCurrent->arContentTypeSent) { ldHeader("Content-Type: text/html; charset=UTF-8"); $ARCurrent->arContentTypeSent = true; } /* // FIXME: the acceptlang code works a bit too well.. it overrides psite configuration settings. if ($ARCurrent->acceptlang && !$ARCurrent->nls) { if ($ARCurrent->acceptlang && is_array($this->data->nls->list)) { $validlangs = array_intersect(array_keys($ARCurrent->acceptlang), array_keys($this->data->nls->list)); } if ($validlangs) { $reqnls=array_shift($validlangs); $ARCurrent->nls = $reqnls; } } */ if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom['none']) { $this->customdata = $this->data->custom['none']; } if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom[$nls]) { $this->customnlsdata = $this->data->custom[$nls]; } if (!$ARConfigChecked) { // this template is the first template called in this request. $eventData = new object(); $eventData->arCallArgs = $arCallArgs; $eventData->arCallFunction = $arCallFunction; $ARConfigChecked = true; $result = ar_events::fire('onbeforeview', $eventData); $ARConfigChecked = $initialConfigChecked; if (!$result) { //prevent default action: view return false; } } if (!$ARConfigChecked) { // if this object isn't available in the requested language, show // a language select dialog with all available languages for this object. if (isset($this->data->nls) && !$this->data->name) { if (!$ARCurrent->forcenls && (!isset($this->data->nls->list[$reqnls]) || !$config->nls->list[$reqnls])) { if (!$ARCurrent->nolangcheck && $arCallFunction != 'config.ini') { $ARCurrent->nolangcheck = 1; $eventData = new object(); $eventData->arCallFunction = $arCallFunction; $eventData->arCallArgs = $arCallArgs; $eventData->arRequestedNLS = $reqnls; $result = ar_events::fire('onlanguagenotfound', $eventData); if ($result) { // continue with default action: langaugeselect $result->arCallArgs["arOriginalFunction"] = $result->arCallFunction; $this->call("user.languageselect.html", $result->arCallArgs); return false; } } else { $this->nlsdata = $this->data->{$nls}; } } else { $this->nlsdata = $this->data->{$reqnls}; } } $ARCurrent->nolangcheck = 1; } /* Set ARConfigChecked to true to indicate that we have been here earlier. */ $ARConfigChecked = true; if ($arCallFunction) { // don't search for templates named '' // FIXME: Redirect code has to move to getPinpTemplate() $redirects = $ARCurrent->shortcut_redirect; if (isset($redirects) && is_array($redirects)) { $redirpath = $this->path; while (!$template['arTemplateId'] && ($redir = array_pop($redirects)) && $redir["keepurl"] && substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"]) { $template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"]); $redirpath = $redir['src']; } if (!$template["arTemplateId"] && $redirpath) { $template = $this->getPinpTemplate($arCallFunction, $redirpath); } } if (!$template["arTemplateId"]) { $template = $this->getPinpTemplate($arCallFunction); } if ($template["arCallTemplate"] && $template["arTemplateId"]) { if (!isset($ARCurrent->cacheTemplateChain)) { $ARCurrent->cacheTemplateChain = array(); } if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]])) { $ARCurrent->cacheTemplateChain[$template["arTemplateId"]] = array(); } if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']])) { $ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']] = array(); } if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']])) { $ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']] = 0; } $ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']]++; debug("CheckConfig: arCallTemplate=" . $template["arCallTemplate"] . ", arTemplateId=" . $template["arTemplateId"], "object"); // $arCallTemplate=$this->store->get_config("files")."templates".$arCallTemplate; // check if template exists, if it doesn't exist, then continue the original template that called CheckConfig $arTemplates = $this->store->get_filestore("templates"); $exists = ar('template')->exists($template['arCallTemplatePath'], $template["arCallTemplate"]); if ($exists) { // check if the requested language exists, if not do not display anything, // unless otherwise indicated by $ARCurrent->allnls // This triggers only for pinp templates called by other templates, // as the first template (in the url) will first trigger the language // choice dialogue instead. $arLibrary = $template['arLibrary']; if (is_int($arLibrary)) { // set the library name for unnamed libraries to 'current' // so that calls using getvar('arLibrary') will keep on working $arLibrary = "current"; } if (!is_string($arCallArgs)) { $arCallArgs['arCallFunction'] = $arCallFunction; $arCallArgs['arLibrary'] = $arLibrary; $arCallArgs['arLibraryPath'] = $template["arLibraryPath"]; } $ARCurrent->arCallStack[] = $arCallArgs; // start running a pinp template $this->pushContext(array("scope" => "pinp", "arLibrary" => $arLibrary, "arLibraryPath" => $template['arLibraryPath'], "arCallFunction" => $arCallFunction, "arCurrentObject" => $this, "arCallType" => $template['arCallType'], "arCallTemplateName" => $template['arCallTemplateName'], "arCallTemplateNLS" => $template['arCallTemplateNLS'], "arCallTemplateType" => $template['arCallTemplateType'], "arCallTemplatePath" => $template['arCallTemplatePath'], "arLibrariesSeen" => $template['arLibrariesSeen'])); // FIXME: is 2 het correcte getal? Kan dit minder magisch? if (count($ARCurrent->arCallStack) == 2 && true === $template['arPrivateTemplate']) { // Do not allow private templates to be called first in the stack. // echo "Bad request"; // FIXME: Echte header sturen? Of gewoon niet uitvoeren? Wat is het correcte gedrag? // Return true zorgt er voor dat de default 404 handler het oppikt alsof het template niet bestaat. $this->popContext(); array_pop($ARCurrent->arCallStack); return true; } else { if ($ARCurrent->forcenls || isset($this->data->nls->list[$reqnls])) { // the requested language is available. $this->nlsdata = $this->data->{$reqnls}; $this->nls = $reqnls; $continue = true; } else { if (!isset($this->data->nls)) { // the object has no language support $this->nlsdata = $this->data; $continue = true; } else { if ($ARCurrent->allnls || !$initialConfigChecked && $ARCurrent->nolangcheck) { // all objects must be displayed // $this->reqnls=$this->nls; // set requested nls, for checks $this->nls = isset($this->data->nls->default) ? $this->data->nls->default : $this->reqnls; $this->nlsdata = $this->data->{$nls} ?: $this->data->{$this->nls} ?: $this->data; $continue = true; } else { debug("CheckConfig: requested language not available, allnls not set", "object"); // -> skip this object (do not run template but do return false) $continue = false; } } } } if ($continue) { $eventData = new object(); if (!$AR->contextCallHandler) { /* prevent onbeforecall from re-entering here */ $AR->contextCallHandler = true; $eventData->arCallArgs = $arCallArgs; $eventData->arCallFunction = $arCallFunction; $eventData->arContext = $this->getContext(); $eventData = ar_events::fire('onbeforecall', $eventData); $ARCurrent->arResult = $eventData->arResult; $AR->contextCallHandler = false; $continue = $eventData != false; } if ($continue) { if (!isset($ARCurrent->cacheCallChainSettings)) { $ARCurrent->cacheCallChainSettings = array(); } if ($ARConfig->cache[$this->path]->inConfigIni == false) { $ARCurrent->cacheCallChainSettings[$this->id] = $config->cacheSettings; } if ($ARCurrent->ARShowTemplateBorders) { echo "<!-- arTemplateStart\nData: " . $this->type . " " . $this->path . " \nTemplate: " . $template["arCallTemplatePath"] . " " . $template["arCallTemplate"] . " \nLibrary:" . $template["arLibrary"] . " -->"; } set_error_handler(array('pobject', 'pinpErrorHandler'), error_reporting()); $func = ar('template')->get($template['arCallTemplatePath'], $template['arCallTemplate']); if (is_callable($func)) { $arResult = $func($this); } restore_error_handler(); if (isset($arResult)) { $ARCurrent->arResult = $arResult; } if ($ARCurrent->ARShowTemplateBorders) { echo "<!-- arTemplateEnd -->"; } if (!$AR->contextCallHandler) { /* prevent oncall from re-entering here */ $AR->contextCallHandler = true; $temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */ $eventData->arResult = $temp; ar_events::fire('oncall', $eventData); $ARCurrent->arResult = $temp; /* restore correct result */ $AR->contextCallHandler = false; } } } array_pop($ARCurrent->arCallStack); $this->popContext(); if (!$initialConfigChecked && $arCallFunction != 'config.ini') { // this template was the first template called in this request. $eventData = new object(); $eventData->arCallArgs = $arCallArgs; $eventData->arCallFunction = $arCallFunction; ar_events::fire('onview', $eventData); // no default action to prevent, so ignore return value. } return false; } else { debug("pobject: CheckConfig: no such file: " . $template["arTemplateId"] . $template["arCallTemplate"] . "", "all"); } } else { debug("CheckConfig: no arCallTemplate ({$arCallFunction} from '{$this->path}')", "object"); } } } return true; }
function ldSetContent($mimetype, $size = 0) { $result = ldHeader("Content-type: " . $mimetype); if ($size) { $result = ldHeader("Content-Length: " . $size); } return $result; }
<?php ldHeader('X-XSS-Protection: 0'); $ARCurrent->nolangcheck = true; if ($this->CheckLogin("layout") && $this->CheckConfig()) { include $this->store->get_config("code") . "widgets/wizard/code.php"; $wgWizFlow = array(array("current" => $this->getdata("wgWizCurrent", "none"), "template" => "dialog.templates.edit.form.php", "cancel" => "dialog.templates.edit.cancel.php", "save" => "dialog.templates.edit.save.php", "apply" => "dialog.templates.edit.apply.php", "delete" => "dialog.templates.edit.delete.php")); $wgWizButtons = array("cancel" => array("value" => $ARnls["cancel"], "location" => "left"), "delete" => array("value" => $ARnls["delete"], "location" => "left"), "apply" => array("value" => $ARnls["apply"]), "save" => array("value" => $ARnls["save"])); $wgWizTitle = sprintf($ARnls["edittemplate"], $this->path . ($function ? $function : $ARnls["new"])); $wgWizHeader = $wgWizTitle; $wgWizHeaderIcon = $AR->dir->images . 'icons/large/templates.png'; $yui_base = $AR->dir->www . "js/yui/"; $wgWizStyleSheets = array($yui_base . "datatable/assets/skins/sam/datatable.css", $yui_base . "menu/assets/skins/sam/menu.css", $yui_base . "container/assets/skins/sam/container.css", $AR->dir->styles . "templates.css"); $wgWizScripts = array($yui_base . "element/element-min.js", $yui_base . "datasource/datasource-min.js", $yui_base . "datatable/datatable-min.js", $yui_base . "container/container_core-min.js", $yui_base . "menu/menu-min.js", $AR->dir->www . "js/muze.js", $AR->dir->www . "js/muze/event.js", $AR->dir->www . "js/muze/dialog.js", $AR->dir->www . "js/muze/util/textarea.js", $AR->dir->www . "js/muze/ariadne/templates.js", $AR->dir->www . "js/muze/ariadne/cookie.js", $AR->dir->www . "js/muze/util/splitpane.js", $AR->dir->www . "js/muze/util/pngfix.js", $AR->dir->www . "js/muze/ariadne/registry.js", $AR->dir->www . "js/muze/ariadne/explore.js"); include $this->store->get_config("code") . "widgets/wizard/yui.wizard.html"; }
function head($options) { $path = $this->make_path($options['path']); debug("webdav:files:head ({$path})"); if (!$this->store->exists($path)) { debug("webdav:files:head {$path} does not exist"); $status = "404 Not Found"; } else { $info = current($this->store->call('webdav.files.get.info.phtml', '', $this->store->get($path))); // chop root $info['path'] = substr($info['path'], strlen($this->root) - 1); ldHeader("Last-Modified: " . gmdate(DATE_RFC1123, $info['props']['getlastmodified'])); ldHeader("Content-Length: " . (int) $info['props']['getcontentlength']); $status = "200 OK"; } debug("webdav:files:head [{$status}]"); return $status; }
<?php /****************************************************************** ******************************************************************/ if (!$this->validateFormSecret()) { error($ARnls['ariadne:err:invalidsession']); exit; } $this->call("system.save.custom.phtml", $arCallArgs); if (!$this->error) { if ($arReturnPage) { ldHeader("Location: " . $this->store->get_config("root") . $arReturnPage); } else { ?> <script> if (window.opener) { window.opener.muze.ariadne.explore.sidebar.view('<?php echo $this->path; ?> '); window.close(); } </script> <?php } } else { echo "<font color='red'>{$this->error}</font>"; }
function ldProcessRequest($AR_PATH_INFO = null) { global $AR; global $ARCurrent; global $store_config; global $auth_config; global $cache_config; global $store; global $context; global $DB; global $path; global $function; global $nls; $writecache = false; // go check for a sessionid $root = $AR->root; $session_id = 0; $re = "^/-(.{4})-/"; $originalPathInfo = $AR_PATH_INFO; // Store this to pass to the refresh cache on shutdown function; if (preg_match('|' . $re . '|', $AR_PATH_INFO, $matches)) { $session_id = $matches[1]; $AR_PATH_INFO = substr($AR_PATH_INFO, strlen($matches[0]) - 1); $AR->hideSessionIDfromURL = false; } elseif ($AR->hideSessionIDfromURL) { $cookies = (array) ldGetCredentials(); $current = ldGetCookieSession(); if (array_key_exists($current, $cookies)) { $session_id = $current; } } // set the default user (public) $AR->login = "******"; // look for the template $split = strrpos($AR_PATH_INFO, "/"); $path = substr($AR_PATH_INFO, 0, $split + 1); $function = substr($AR_PATH_INFO, $split + 1); if (!$function) { if (!isset($arDefaultFunction) || $arDefaultFunction == '') { $arDefaultFunction = "view.html"; } $function = $arDefaultFunction; if (isset($arFunctionPrefix) && $arFunctionPrefix != '') { $function = $arFunctionPrefix . $function; } $AR_PATH_INFO .= $function; } // yes, the extra '=' is needed, don't remove it. trust me. $ldCacheFilename = strtolower($AR_PATH_INFO) . "="; // for the new multiple domains per site option (per language), we need this // since the nls isn't literaly in the url anymore. $ldCacheFilename .= str_replace(':', '=', str_replace('/', '', $AR->host)) . '='; $qs = ldGetServerVar("QUERY_STRING"); if ($qs != '') { $ldCacheFilename .= sha1($qs); } if ($session_id) { $cachedimage = $store_config["files"] . "cache/session" . $ldCacheFilename; $cachedheader = $store_config["files"] . "cacheheaders/session" . $ldCacheFilename; } else { $cachedimage = $store_config["files"] . "cache/normal" . $ldCacheFilename; $cachedheader = $store_config["files"] . "cacheheaders/normal" . $ldCacheFilename; } if ($AR->ESI) { ob_start(); } $timecheck = time(); if (file_exists($cachedimage)) { $staleTotalTime = filemtime($cachedimage) - filectime($cachedimage); $staleCurrent = $timecheck - filectime($cachedimage); if ($staleTotalTime != 0) { $stalePercentage = sprintf("%.2f", 100 * $staleCurrent / $staleTotalTime); } else { $stalePercentage = 100; } if ($stalePercentage < 0) { $stalePercentage = 0; } else { if ($stalePercentage > 100) { $stalePercentage = 100; } } if (!headers_sent()) { header("X-Ariadne-Cache-Stale: {$stalePercentage}%"); } } // add min-fresh if the client asked for it if (isset($ARCurrent->RequestCacheControl["min-fresh"])) { $timecheck += $ARCurrent->RequestCacheControl["min-fresh"]; } if (file_exists($cachedimage) && (($mtime = @filemtime($cachedimage)) > $timecheck || $mtime == 0) && $_SERVER["REQUEST_METHOD"] != "POST" && $ARCurrent->RequestCacheControl["no-cache"] != true && $ARCurrent->refreshCacheOnShutdown !== true) { $ctime = filemtime($cachedimage); // FIXME: Waarom moet dit mtime zijn? Zonder mtime werkt de if-modified-since niet; if (rand(20, 80) < $stalePercentage) { header("X-Ariadne-Cache-Refresh: refreshing on shutdown"); register_shutdown_function("ldCacheRequest", $originalPathInfo); // Rerun the request with the original path info; } else { header("X-Ariadne-Cache-Refresh: skipped, still fresh enough"); } if (!$AR->ESI && $_SERVER['HTTP_IF_MODIFIED_SINCE'] && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $ctime) { // the mtime is used as expiration time, the ctime is the correct last modification time. // as an object clears the cache upon a save. // Send the original headers - they will already contain the correct max-age and expires values; if (file_exists($cachedheader)) { $filedata = file($cachedheader); if (is_array($filedata)) { while (list($key, $header) = each($filedata)) { ldHeader($header); } } } header("X-Ariadne-Cache: Hit"); ldHeader("HTTP/1.1 304 Not Modified"); } else { if (file_exists($cachedheader)) { // Cache header file also contains information about Cache-control; $filedata = file($cachedheader); if (is_array($filedata)) { while (list($key, $header) = each($filedata)) { ldHeader($header); } } } header("X-Ariadne-Cache: Hit"); // Send this after the cached headers to overwrite the cached cache-miss header; if ($AR->ESI) { if (false && $_SERVER['HTTP_IF_MODIFIED_SINCE'] && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $ctime) { ldHeader("HTTP/1.1 304 Not modified"); } else { $data = file_get_contents($cachedimage); include_once $store_config['code'] . "modules/mod_esi.php"; // Replace the session IDs before the ESI process call to pass the correct session ID information... if ($session_id && !$AR->hideSessionIDfromURL) { $tag = '{arSessionID}'; $data = str_replace($tag, "-{$session_id}-", $data); } $data = ESI::esiProcess($data); // ... and then replace the session IDs that were generated in de ESI case; $tag = '{arSessionID}'; if ($session_id && !$AR->hideSessionIDfromURL) { $data = str_replace($tag, "-{$session_id}-", $data); } else { if ($session_id && $AR->hideSessionIDfromURL) { $data = str_replace($tag, '', $data); } } $data_len = strlen($data); header("Content-Length: " . $data_len); echo $data; } } else { if ($session_id) { $tag = '{arSessionID}'; $data = file_get_contents($cachedimage); $tag = '{arSessionID}'; if (!$AR->hideSessionIDfromURL) { $data = str_replace($tag, "-{$session_id}-", $data); } else { $data = str_replace($tag, '', $data); } $data_len = strlen($data); header("Content-Length: " . $data_len); echo $data; } else { $data_len = filesize($cachedimage); header("Content-Length: " . $data_len); readfile($cachedimage); } } } $writecache = false; // Prevent recaching cached image; } else { if (!headers_sent()) { header("X-Ariadne-Cache: Miss"); } /* start output buffering */ ob_start(); global $ldOutputBufferActive; $ldOutputBufferActive = true; ob_implicit_flush(0); // look for the language $split = strpos(substr($AR_PATH_INFO, 1), "/"); $ARCurrent->nls = substr($path, 1, $split); if (!isset($AR->nls->list[$ARCurrent->nls])) { // not a valid language $ARCurrent->nls = ""; $nls = $AR->nls->default; // but we can find out if the user has any preferences preg_match_all("%([a-zA-Z]{2}|\\*)[a-zA-Z-]*(?:;q=([0-9.]+))?%", $_SERVER["HTTP_ACCEPT_LANGUAGE"], $regs, PREG_SET_ORDER); $ARCurrent->acceptlang = array(); $otherlangs = array(); $otherq = false; foreach ($regs as $reg) { if (!isset($reg[2])) { $reg[2] = 1; } if ($reg[1] == "*") { $otherq = $reg[2]; } else { if ($AR->nls->list[$reg[1]]) { $otherlangs[] = $reg[1]; $ARCurrent->acceptlang[$reg[1]] = $reg[2]; } } } if ($otherq !== false) { $otherlangs = array_diff(array_keys($AR->nls->list), $otherlangs); foreach ($otherlangs as $lang) { $ARCurrent->acceptlang[$lang] = $otherq; } } arsort($ARCurrent->acceptlang); } else { // valid language $path = substr($path, $split + 1); // ldSetNls($ARCurrent->nls); $nls = $ARCurrent->nls; } $args = array_merge($_GET, $_POST); // instantiate the store $inst_store = $store_config["dbms"] . "store"; $store = new $inst_store($root, $store_config); //$store->rootoptions = $rootoptions; if ($session_id) { ldStartSession($session_id); } // instantiate the ARnls if ($ARCurrent->nls != "") { ldSetNls($nls); } if (substr($function, -6) == ".phtml") { // system template: no language check $ARCurrent->nolangcheck = 1; } $ext = pathinfo($function, PATHINFO_EXTENSION); switch ($ext) { case 'css': ldSetContent('text/css; charset=utf-8'); break; case 'js': ldSetContent('application/javascript; charset=utf-8'); break; case 'json': ldSetContent('application/json; charset=utf-8'); break; case 'xml': ldSetContent('text/xml; charset=utf-8'); break; case 'jpg': ldSetContent('image/jpeg'); break; case 'gif': ldSetContent('image/gif'); break; case 'png': ldSetContent('image/png'); break; case 'svg': ldSetContent('image/svg+xml'); break; default: ldSetContent('text/html; charset=utf-8'); break; } $ARCurrent->arContentTypeSent = true; register_shutdown_function("ldOnFinish"); $auth_class = "mod_auth_" . $auth_config["method"]; $mod_auth = new $auth_class($auth_config); $username = isset($args["ARLogin"]) ? $args["ARLogin"] : null; $password = isset($args["ARPassword"]) ? $args["ARPassword"] : null; $result = $mod_auth->checkLogin($username, $password, $path); if ($result !== true) { if ($result == LD_ERR_ACCESS) { ldAccessDenied($path, $ARnls["accessdenied"], $args, $function); $function = false; } else { if ($result == LD_ERR_SESSION && !$AR->hideSessionIDfromURL) { ldAccessTimeout($path, $ARnls["sessiontimeout"], $args, $function); $function = false; } else { if ($result == LD_ERR_EXPIRED) { ldAccessPasswordExpired($path, $ARnls["sessionpasswordexpired"], $args, $function); $function = false; } } } } // valid new login, without a session, morph to login.redirect.php to redirect to a session containing url if (!$session_id && $args["ARLogin"] && $args["ARPassword"] && $function !== false && !$AR->hideSessionIDfromURL) { if (!$ARCurrent->session->get("oldArCallArgs", 1)) { $ARCurrent->session->put("oldGET", $_GET, 1); $ARCurrent->session->put("oldPOST", $_POST, 1); $ARCurrent->session->put("oldArCallArgs", $args, 1); $ARCurrent->session->save(0, true); } if ($arDefaultFunction !== $function) { $args["arRequestedTemplate"] = $function; } else { $args["arRequestedTemplate"] = ""; } $function = "login.redirect.php"; } else { if ($session_id) { if ($ARCurrent->session->get("ARSessionTimedout", 1)) { if (!$ARCurrent->session->get("oldArCallArgs", 1)) { $ARCurrent->session->put("oldGET", $_GET, 1); $ARCurrent->session->put("oldPOST", $_POST, 1); $ARCurrent->session->put("oldArCallArgs", $args, 1); $ARCurrent->session->save(0, true); } } else { if ($ARCurrent->session->get("oldArCallArgs", 1)) { $_GET = array_merge($_GET, (array) $ARCurrent->session->get("oldGET", 1)); $_POST = array_merge($_POST, (array) $ARCurrent->session->get("oldPOST", 1)); $args = $ARCurrent->session->get("oldArCallArgs", 1); $args = array_merge($_GET, $_POST, $args); // $args, $_GET, $_POST ); $ARCurrent->session->put("oldArCallArgs", "", 1); $ARCurrent->session->put("oldGET", "", 1); $ARCurrent->session->put("oldPOST", "", 1); } } } } $xss_vars = array(); ldGatherXSSInput($xss_vars, $_GET); ldGatherXSSInput($xss_vars, $_POST); $filenames = array_map(function ($e) { return $e['name']; }, $_FILES); ldGatherXSSInput($xss_vars, $filenames); ldGatherXSSInput($xss_vars, $function); ldGatherXSSInput($xss_vars, $path); global $ldXSSProtectionActive; if (count($xss_vars)) { $ldXSSProtectionActive = true; } if ($function !== false) { // finally call the requested object unset($store->total); if (ldCheckAllowedTemplate($function)) { $store->call($function, $args, $store->get($path)); $writecache = true; } if (!$store->total) { ldObjectNotFound($path, $function, $args); } } if (count($xss_vars)) { $image = ob_get_contents(); ob_clean(); $header = $ARCurrent->ldHeaders["content-type"]; $xssDetected = false; preg_match('/^content-type:\\s+([^ ;]+)/i', $header, $matches); $mimetype = strtolower($matches[1]); if (substr($mimetype, 0, 5) == 'text/') { krsort($xss_vars, SORT_NUMERIC); foreach ($xss_vars as $values) { if (is_array($values)) { foreach ($values as $value) { $occurances = substr_count($image, $value); if ($occurances > 0) { $xssDetected = true; break 2; } } } } } if ($xssDetected) { $newargs = array(); $newargs["arRequestedArgs"] = $args; $newargs["arRequestedTemplate"] = $function; $newargs["arSuspectedArgs"] = $xss_vars; $newargs["arResultOutput"] = $image; $store->call('user.xss.html', $newargs, $store->get($path)); } else { echo $image; } } } // now check for outputbuffering (caching) if ($image = ob_get_contents()) { // Calculate browser side cache settings based on settings collected in the call chain; // // Rules: do not cache wins. short cache time wins over longer cache time. Unset values don't get to play. // // Overlord rule: if the request method was not a get, or debugging was used, do not cache. Ever. // // If pinp says arDontCache, then do not cache; // // If ESI was used and hit a cached image, use the cache settings from the cache image; if ($_SERVER['REQUEST_METHOD'] != 'GET' || $DB["wasUsed"] > 0) { // Do not cache on client. ldSetBrowserCache(false); } else { if (is_array($ARCurrent->cache) && ($file = array_pop($ARCurrent->cache))) { // This will generate an error, do not cache on client; ldSetBrowserCache(false); } else { if ($ARCurrent->arDontCache) { // PINP told us not to cache; ldSetBrowserCache(false); } else { if (!$writecache) { // Image came from the cache, it already has browser cache headers; } else { // Defaults for browser caching; // Calls without session: public, max-age 1800; // Calls with session without call chain (disk templates): private, no-cache no-store must-revalidate max-age=0 // Calls with session with call chain (pinp templates): private, max-age=1800; // FIXME: Make the calls with session less trigger happy on not caching; /* if ($session_id && sizeof($ARCurrent->cacheCallChainSettings)) { // With session and pinp templates; $browserCachePrivate = true; $browserCacheMaxAge = 1800; $browserCacheNoStore = false; $browserCacheNoCache = false; $browserCacheMustRevalidate = false; } else */ if ($session_id) { // With session, disk templates only $browserCachePrivate = true; $browserCacheMaxAge = 0; $browserCacheNoStore = true; $browserCacheNoCache = true; $browserCacheMustRevalidate = true; } else { // Without session and all other corner cases; $browserCachePrivate = false; $defaultMaxAge = 1800; $browserCacheNoStore = false; $browserCacheNoCache = false; $browserCacheMustRevalidate = false; } $browserCachecacheSetting = 0; // Default = inherit; // FIXME: The defaults for with session ID are now to not cache; if (is_array($ARCurrent->cacheCallChainSettings)) { foreach ($ARCurrent->cacheCallChainSettings as $objectId => $pathCacheSetting) { $browserCachePrivate = $browserCachePrivate || $pathCacheSetting['browserCachePrivate']; // If anyone says 'private', make it so. $browserCacheNoStore = $browserCacheNoStore || $pathCacheSetting['browserCacheNoStore']; // If anyone says 'no-store', make it so. $browserCacheNoCache = $browserCacheNoCache || $pathCacheSetting['browserCacheNoCache']; // If anyone says 'no-cache', make it so. $browserCacheMustRevalidate = $browserCacheMustRevalidate || $pathCacheSetting['browserCacheMustRevalidate']; // If anyone says 'must-revalidate', make it so. $browserCacheNoTransform = $browserCacheNoTransform || $pathCacheSetting['browserCacheNoTransform']; // If anyone says 'no-transform', make it so. $browserCacheProxyRevalidate = $browserCacheProxyRevalidate || $pathCacheSetting['browserCacheProxyRevalidate']; // If anyone says 'proxy-revalidate', make it so. if (isset($pathCacheSetting['browserCacheMaxAge']) && is_numeric($pathCacheSetting['browserCacheMaxAge'])) { if (isset($browserCacheMaxAge)) { $browserCacheMaxAge = min($browserCacheMaxAge, $pathCacheSetting['browserCacheMaxAge']); } else { $browserCacheMaxAge = $pathCacheSetting['browserCacheMaxAge']; } } if (isset($pathCacheSetting['browserCacheSMaxAge']) && is_numeric($pathCacheSetting['browserCacheMaxAge'])) { if (isset($browserCacheSMaxAge)) { $browserCacheSMaxAge = min($browserCacheSMaxAge, $pathCacheSetting['browserCacheSMaxAge']); } else { $browserCacheSMaxAge = $pathCacheSetting['browserCacheSMaxAge']; } } } if (!isset($browserCacheMaxAge) && isset($defaultMaxAge)) { $browserCacheMaxAge = $defaultMaxAge; } } ldSetBrowserCache(array("browserCachePrivate" => $browserCachePrivate, "browserCacheNoStore" => $browserCacheNoStore, "browserCacheNoCache" => $browserCacheNoCache, "browserCacheMustRevalidate" => $browserCacheMustRevalidate, "browserCacheNoTransform" => $browserCacheNoTransform, "browserCacheProxyRevalidate" => $browserCacheProxyRevalidate, "browserCacheMaxAge" => $browserCacheMaxAge, "browserCacheSMaxAge" => $browserCacheSMaxAge)); } } } } $image_len = strlen($image); if ($ARCurrent->session && $ARCurrent->session->id) { $ldCacheFilename = "/session" . $ldCacheFilename; $image = str_replace('-' . $ARCurrent->session->id . '-', '{arSessionID}', $image); } else { $ldCacheFilename = "/normal" . $ldCacheFilename; } // because we have the full content, we can now also calculate the content length ldHeader("Content-Length: " . $image_len); // flush the buffer, this will send the contents to the browser ob_end_flush(); debug("loader: ob_end_flush()", "all"); // Calculate server side cache settings based on settings collected in the call chain; // // Rules: do not cache wins. short cache time wins over longer cache time. Unset values don't get to play. // // Overlord rule: if the request method was not a get, or debugging was used, do not cache. Ever. // // If pinp says arDontCache, then do not cache; // // If ESI was used and hit a cached image, do not write the image; if ($_SERVER['REQUEST_METHOD'] != 'GET' || $DB["wasUsed"] > 0) { // Do not cache on server. // header("X-Ariadne-Cache-Skipped: DB Used"); } else { if (is_array($ARCurrent->cache) && ($file = array_pop($ARCurrent->cache))) { error("cached() opened but not closed with savecache()"); // header("X-Ariadne-Cache-Skipped: cached problem."); } else { if ($ARCurrent->arDontCache) { // PINP told us not to cache; // header("X-Ariadne-Cache-Skipped: arDontCache"); } else { if (!$writecache) { // ESI was used and hit a cached image, do not write the image; // header("X-Ariadne-Cache-Skipped: cached image used"); } else { // header("X-Ariadne-Cache-Skipped: Writing cache now"); // Cache setting values: // -2 = Refresh on change; Set the cache time on server to 999 hours (unlimited); // -1 = Do not cache // 0 = Inherit // > 0: Refresh on request. The number is the amount of hours that the cache is 'fresh'. This can be a fraction/float value; $cacheSetting = 0; // Default = inherit; $serverCachePrivate = 0; // do not allow caching of sessions if (is_array($ARCurrent->cacheCallChainSettings)) { foreach ($ARCurrent->cacheCallChainSettings as $objectId => $pathCacheSetting) { // FIXME: also 'resolve' $serverCachePrivate $serverCache = $pathCacheSetting['serverCache']; if ($serverCache == 0 || !isset($serverCache)) { // This path does not want to play; $serverCache = $pathCacheSetting['serverCacheDefault']; } if ($serverCache == -2) { // Sorry, we meant that the cache image should be valid forever; $serverCache = 999; } if ($cacheSetting == 0) { $cacheSetting = $serverCache; } else { $cacheSetting = min($serverCache, $cacheSetting); } if ($cacheSetting == -1) { // If someone told us to not cache, skip checking because nothing anyone else tells us will change this fact. break; } } } // header("X-Ariadne-Cache-Setting: $cacheSetting"); if ($ARCurrent->session->id && $cacheSetting > 0) { // we have a session id, can we cache ? // FIXME: add support for $serverCachePrivate in the config and cache dialog if (!($serverCachePrivate === 1 || $ARCurrent->arDoCachePrivate != false)) { $cacheSetting = -1; } } if ($cacheSetting > 0) { // If we are allowed to cache, write the image now. if ($store) { // Sanity check to only write cache images if a store was initialized; // FIXME: cacheCallChainSettings contains the objects that were called for this cache image; // FIXME: cacheTemplateChain containers the templates that were called for this cache image; ldSetCache($ldCacheFilename, $cacheSetting, $image, @implode("\n", $ARCurrent->ldHeaders)); $cachestore = new cache($cache_config); $cachestore->save($ldCacheFilename, $ARCurrent->cacheCallChainSettings, $ARCurrent->cacheTemplateChain); } } } } } } } if ($AR->ESI > 0) { // Prevent ESI from looping when the ESI result has ESI tags in them. // Reducing the AR->ESI number by 1 gives the flexibility to allow 2 or 3 ESI loops if desired. // Setting it to false would mean you only get 1 ESI loop, which might not be the desired effect. $AR->ESI = (int) $AR->ESI; $AR->ESI--; $image = ob_get_contents(); ob_end_clean(); include_once $store_config['code'] . "modules/mod_esi.php"; $image = ESI::esiProcess($image); $image_len = strlen($image); if ($ARCurrent->arDontCache) { // FIXME: ook de cachetime 'niet cachen' uit het cachedialoog werkend maken... || $ARCurrent->cachetime == 0) { ldSetBrowserCache(false); } ldHeader("Content-Length: " . $image_len); echo $image; } }
function ldSetClientCache($cache_on, $expires = 0, $modified = 0) { global $ARCurrent; $now = time(); if ($cache_on) { if (!$expires) { $expires = $now + 1800; } if (!$modified) { $modified = $now; } ldHeader("Pragma: cache"); ldHeader("Cache-control: cache"); ldHeader("Expires: " . gmdate(DATE_RFC1123, $expires)); $result = ldHeader("Last-Modified: " . gmdate(DATE_RFC1123, $modified)); } else { if (!$modified) { $modified = time(); } ldHeader("Pragma: no-cache"); ldHeader("Cache-control: must-revalidate, max-age=0, private"); ldHeader("Expires: " . gmdate(DATE_RFC1123, $expires)); $result = ldHeader("Last-Modified: " . gmdate(DATE_RFC1123, $modified)); } return $result; }