Ejemplo n.º 1
0
 static function render($agent, $liveAgent)
 {
     $config_maxage = $CONFIG['maxage'];
     // Get the calling URI
     if (isset($_COOKIE['R$'])) {
         p::$uri = $_COOKIE['R$'];
         setcookie('R$', '', 1, '/');
         // Check the Referer header
         // T$ starts with 2 when the Referer's confidence is unknown
         //                1 when it is trusted
         if (isset($_SERVER['HTTP_REFERER']) && $_COOKIE['R$'] === $_SERVER['HTTP_REFERER']) {
             if (class_exists('SESSION', false)) {
                 $_COOKIE['T$'] = '1';
                 s::regenerateId();
             } else {
                 self::$antiCsrfToken[0] = '1';
                 setcookie('T$', self::$antiCsrfToken, 0, $CONFIG['session.cookie_path'], $CONFIG['session.cookie_domain']);
             }
         }
     } else {
         p::$uri = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : p::$base;
     }
     if ($liveAgent) {
         // The output is both html and js, but iframe transport layer needs html
         p::$binaryMode = true;
         header('Content-Type: text/html');
         echo '/*<script>/**/q="';
     } else {
         echo 'w(';
     }
     p::openMeta($agent);
     try {
         if (isset($_GET['T$']) && !p::$antiCsrfMatch) {
             throw new e\PrivateResource();
         }
         $a = new $agent($_GET);
         $group = p::closeGroupStage();
         if ($is_cacheable = 'POST' !== $_SERVER['REQUEST_METHOD'] && !in_array('private', $group)) {
             $cagent = p::agentCache($agent, $a->get, 'js.ser', $group);
             $dagent = p::getContextualCachePath('jsdata.' . $agent, 'js.ser', $cagent);
             if ($liveAgent) {
                 if (file_exists($dagent)) {
                     if (filemtime($dagent) > $_SERVER['REQUEST_TIME']) {
                         $data = unserialize(file_get_contents($dagent));
                         p::setMaxage($data['maxage']);
                         p::setExpires($data['expires']);
                         p::writeWatchTable($data['watch']);
                         array_map('header', $data['headers']);
                         p::closeMeta();
                         echo str_replace(array('\\', '"', '</'), array('\\\\', '\\"', '<\\/'), $data['rawdata']), '"//</script><script src="' . p::__BASE__() . 'js/QJsrsHandler"></script>';
                         return;
                     } else {
                         @(unlink($cagent) + unlink($dagent));
                     }
                 }
             } else {
                 if (file_exists($cagent)) {
                     if (filemtime($cagent) > $_SERVER['REQUEST_TIME']) {
                         $data = unserialize(file_get_contents($cagent));
                         p::setMaxage($data['maxage']);
                         p::setExpires($data['expires']);
                         p::writeWatchTable($data['watch']);
                         array_map('header', $data['headers']);
                         p::closeMeta();
                         echo $data['rawdata'];
                         return;
                     } else {
                         @(unlink($cagent) + unlink($dagent));
                     }
                 }
             }
         }
         ob_start();
         ++p::$ob_level;
         try {
             $data = (object) $a->compose((object) array());
             if (!p::$is_enabled) {
                 p::closeMeta();
                 return;
             }
             $template = $a->getTemplate();
             echo '{';
             $comma = '';
             foreach ($data as $key => $value) {
                 $key = jsquote($key);
                 is_string($key) || ($key = "'" . $key . "'");
                 echo $comma, $key, ':';
                 if ($value instanceof \loop) {
                     self::writeAgent($value);
                 } else {
                     echo jsquote($value);
                 }
                 $comma = ',';
             }
             echo '}';
         } catch (e\PrivateResource $data) {
             ob_end_clean();
             --p::$ob_level;
             p::closeMeta();
             throw $data;
         }
         $data = ob_get_clean();
         --p::$ob_level;
         $a->metaCompose();
         list($maxage, $group, $expires, $watch, $headers) = p::closeMeta();
     } catch (e\PrivateResource $data) {
         if ($liveAgent) {
             echo 'false";(window.E||alert)("You must provide an auth token to get this liveAgent:\\n"+', jsquote($_SERVER['REQUEST_URI']), ')';
             echo '//</script><script src="' . p::__BASE__() . 'js/QJsrsHandler"></script>';
         } else {
             if ($data->getMessage()) {
                 echo 'w.r(0,' . (int) (!DEBUG) . '));';
             } else {
                 echo ');window.E&&E("You must provide an auth token to get this agent:\\n"+', jsquote($_SERVER['REQUEST_URI']), ')';
             }
         }
         exit;
     }
     if ($liveAgent) {
         echo str_replace(array('\\', '"', '</'), array('\\\\', '\\"', '<\\/'), $data), '"//</script><script src="' . p::__BASE__() . 'js/QJsrsHandler"></script>';
     } else {
         echo $data;
     }
     if ('ontouch' === $expires && !($watch || $config_maxage == $maxage)) {
         $expires = 'auto';
     }
     $expires = 'auto' === $expires && ($watch || $config_maxage == $maxage) ? 'ontouch' : 'onmaxage';
     $is_cacheable = $is_cacheable && !in_array('private', $group) && ($maxage || 'ontouch' === $expires);
     if (!$liveAgent || $is_cacheable) {
         if ($is_cacheable) {
             ob_start();
         }
         if ($config_maxage == $maxage && Superloader::$turbo) {
             $ctemplate = p::getContextualCachePath("templates/{$template}", 'txt');
             $readHandle = true;
             if ($h = p::fopenX($ctemplate, $readHandle)) {
                 p::openMeta('agent__template/' . $template, false);
                 $template = new \ptlCompiler_js($template);
                 echo $template = ',' . $template->compile() . ')';
                 fwrite($h, $template);
                 flock($h, LOCK_UN);
                 fclose($h);
                 list(, , , $template) = p::closeMeta();
                 p::writeWatchTable($template, $ctemplate);
             } else {
                 fpassthru($readHandle);
                 flock($readHandle, LOCK_UN);
                 fclose($readHandle);
             }
             $watch[] = 'public/templates/js';
         } else {
             echo ',[1,', jsquote($template), ',0,0,0])';
         }
         if ($is_cacheable) {
             $ob = true;
             $template = array('maxage' => $maxage, 'expires' => $expires, 'watch' => $watch, 'headers' => $headers, 'rawdata' => $data);
             $expires = 'ontouch' === $expires ? $config_maxage : $maxage;
             if ($h = p::fopenX($dagent)) {
                 fwrite($h, serialize($template));
                 flock($h, LOCK_UN);
                 fclose($h);
                 touch($dagent, $_SERVER['REQUEST_TIME'] + $expires);
                 p::writeWatchTable($watch, $dagent);
             }
             if ($h = p::fopenX($cagent)) {
                 $ob = false;
                 $template['rawdata'] .= $liveAgent ? ob_get_clean() : ob_get_flush();
                 fwrite($h, serialize($template));
                 flock($h, LOCK_UN);
                 fclose($h);
                 touch($cagent, $_SERVER['REQUEST_TIME'] + $expires);
                 p::writeWatchTable($watch, $cagent);
             }
             if ($ob) {
                 $liveAgent ? ob_end_clean() : ob_end_flush();
             }
         }
     }
 }
Ejemplo n.º 2
0
 static function readfile($file, $mime = true, $filename = true)
 {
     $h = patchworkPath($file);
     if (!$h || !file_exists($h) || is_dir($h)) {
         user_error(__METHOD__ . "(..): invalid file ({$file})");
         return;
     }
     $file = $h;
     if (true === $mime) {
         $mime = strtolower(strrchr($file, '.'));
         $mime = isset(self::$contentType[$mime]) ? self::$contentType[$mime] : false;
     }
     $mime || ($mime = isset(p::$headers['content-type']) ? substr(p::$headers['content-type'], 14) : 'application/octet-stream');
     $mime = strtolower($mime);
     $head = 'HEAD' == $_SERVER['REQUEST_METHOD'];
     $gzip = p::gzipAllowed($mime);
     $filter = $gzip || $head || !$CONFIG['xsendfile'] || in_array($mime, self::$ieSniffedTypes_edit) || in_array($mime, p::$ieSniffedTypes_download);
     header('Content-Type: ' . $mime);
     if ($filename) {
         $filename = basename(true === $filename ? $_SERVER['PATCHWORK_REQUEST'] : $filename);
         $size = false;
         if (!$filter) {
             // Force IE>=8 to respect attachment content disposition
             header('X-Download-Options: noopen');
         }
         // It seems that IE assumes that filename is represented in its local system charset...
         // But we don't want to introduce "Vary: User-Agent" just because of this.
         if (('POST' === $_SERVER['REQUEST_METHOD'] || p::$private) && isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') && !strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') && preg_match('/[\\x80-\\xFF]/', $filename)) {
             if (stripos(p::$headers['content-type'], 'octet-stream') && preg_match('#(.*)(\\.[- -,/-~]+)$#D', $filename, $size)) {
                 // Don't search any rational here, it's IE...
                 header('Content-Disposition: attachment; filename=' . rawurlencode($size[1]) . str_replace('"', "''", $size[2]));
             } else {
                 $filename = Patchwork\Utf8::toAscii($filename);
             }
         }
         $size || header('Content-Disposition: attachment; filename="' . str_replace('"', "''", $filename) . '"');
         // If only RFC 2231 were in use... See http://greenbytes.de/tech/tc2231/
         //header('Content-Disposition: attachment; filename*=utf-8''" . rawurlencode($filename));
     } else {
         if (false !== strpos($mime, 'html')) {
             header('P3P: CP="' . $CONFIG['P3P'] . '"');
             header('X-XSS-Protection: 1; mode=block');
         }
     }
     $size = filesize($file);
     p::$ETag = $size . '-' . p::$LastModified . '-' . fileinode($file);
     p::$LastModified = filemtime($file);
     p::$binaryMode = true;
     p::disable();
     class_exists('SESSION', false) && s::close();
     class_exists('adapter_DB', false) && \adapter_DB::__free();
     $gzip || ob_start();
     $filter && ob_start(array(__CLASS__, 'ob_filterOutput'), 32768);
     // Transform relative URLs to absolute ones
     if ($gzip) {
         if (0 === strncasecmp($mime, 'text/css', 8)) {
             self::$filterRx = "@([\\s:]url\\(\\s*[\"']?)(?![/\\\\#\"']|[^\\)\n\r:/\"']+?:)@i";
             ob_start(array(__CLASS__, 'filter'), 32768);
         } else {
             if (0 === strncasecmp($mime, 'text/html', 9) || 0 === strncasecmp($mime, 'text/x-component', 16)) {
                 self::$filterRx = "@(<[^<>]+?\\s(?:href|src)\\s*=\\s*[\"']?)(?![/\\\\#\"']|[^\n\r:/\"']+?:)@i";
                 ob_start(array(__CLASS__, 'filter'), 32768);
             }
         }
     }
     if ($filter) {
         $h = fopen($file, 'rb');
         echo $starting_data = fread($h, 256);
         // For p::ob_filterOutput to fix IE
         if ($gzip) {
             if ($head) {
                 ob_end_clean();
             }
             $data = '';
             $starting_data = false;
         } else {
             ob_end_flush();
             $data = ob_get_clean();
             $size += strlen($data) - strlen($starting_data);
             $starting_data = $data == $starting_data;
         }
     } else {
         $starting_data = true;
     }
     if (!$head) {
         if ($starting_data && $CONFIG['xsendfile']) {
             header(sprintf($CONFIG['xsendfile'], $file));
         } else {
             if ($range = $starting_data && !$gzip) {
                 header('Accept-Ranges: bytes');
                 $range = isset($_SERVER['HTTP_RANGE']) ? p\HttpRange::negociate($size, p::$ETag, p::$LastModified) : false;
             } else {
                 header('Accept-Ranges: none');
             }
             set_time_limit(0);
             ignore_user_abort(false);
             if ($range) {
                 unset(p::$headers['content-type']);
                 p\HttpRange::sendChunks($range, $h, $mime, $size);
             } else {
                 $gzip || header('Content-Length: ' . $size);
                 echo $data;
                 feof($h) || fpassthru($h);
             }
         }
     }
     $filter && fclose($h);
 }