Ejemplo n.º 1
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);
 }