Esempio n. 1
0
 public function readFile($filePathOrData, $headerType = "plain", $localName = "", $data = false, $gzip = null, $realfileSystem = false, $byteOffset = -1, $byteLength = -1)
 {
     if ($gzip === null) {
         $gzip = ConfService::getCoreConf("GZIP_COMPRESSION");
     }
     if (!$realfileSystem && $this->wrapperClassName == "fsAccessWrapper") {
         $originalFilePath = $filePathOrData;
         $filePathOrData = fsAccessWrapper::patchPathForBaseDir($filePathOrData);
     }
     session_write_close();
     restore_error_handler();
     restore_exception_handler();
     set_exception_handler('download_exception_handler');
     set_error_handler('download_exception_handler');
     // required for IE, otherwise Content-disposition is ignored
     if (ini_get('zlib.output_compression')) {
         AJXP_Utils::safeIniSet('zlib.output_compression', 'Off');
     }
     $isFile = !$data && !$gzip;
     if ($byteLength == -1) {
         if ($data) {
             $size = strlen($filePathOrData);
         } else {
             if ($realfileSystem) {
                 $size = sprintf("%u", filesize($filePathOrData));
             } else {
                 $size = $this->filesystemFileSize($filePathOrData);
             }
         }
     } else {
         $size = $byteLength;
     }
     if ($gzip && ($size > ConfService::getCoreConf("GZIP_LIMIT") || !function_exists("gzencode") || @strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === FALSE)) {
         $gzip = false;
         // disable gzip
     }
     $localName = $localName == "" ? basename(isset($originalFilePath) ? $originalFilePath : $filePathOrData) : $localName;
     if ($headerType == "plain") {
         header("Content-type:text/plain");
     } else {
         if ($headerType == "image") {
             header("Content-Type: " . AJXP_Utils::getImageMimeType(basename($filePathOrData)) . "; name=\"" . $localName . "\"");
             header("Content-Length: " . $size);
             header('Cache-Control: public');
         } else {
             /*
             if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])) {
                 $localName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($localName)));
             }
             */
             if ($isFile) {
                 header("Accept-Ranges: 0-{$size}");
                 $this->logDebug("Sending accept range 0-{$size}");
             }
             // Check if we have a range header (we are resuming a transfer)
             if (isset($_SERVER['HTTP_RANGE']) && $isFile && $size != 0) {
                 if ($headerType == "stream_content") {
                     if (extension_loaded('fileinfo') && $this->wrapperClassName == "fsAccessWrapper") {
                         $fInfo = new fInfo(FILEINFO_MIME);
                         $realfile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $filePathOrData);
                         $mimeType = $fInfo->file($realfile);
                         $splitChar = explode(";", $mimeType);
                         $mimeType = trim($splitChar[0]);
                         $this->logDebug("Detected mime {$mimeType} for {$realfile}");
                     } else {
                         $mimeType = AJXP_Utils::getStreamingMimeType(basename($filePathOrData));
                     }
                     header('Content-type: ' . $mimeType);
                 }
                 // multiple ranges, which can become pretty complex, so ignore it for now
                 $ranges = explode('=', $_SERVER['HTTP_RANGE']);
                 $offsets = explode('-', $ranges[1]);
                 $offset = floatval($offsets[0]);
                 $length = floatval($offsets[1]) - $offset;
                 if (!$length) {
                     $length = $size - $offset;
                 }
                 if ($length + $offset > $size || $length < 0) {
                     $length = $size - $offset;
                 }
                 $this->logDebug('Content-Range: bytes ' . $offset . '-' . $length . '/' . $size);
                 header('HTTP/1.1 206 Partial Content');
                 header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
                 header("Content-Length: " . $length);
                 $file = fopen($filePathOrData, 'rb');
                 fseek($file, 0);
                 $relOffset = $offset;
                 while ($relOffset > 2000000000.0) {
                     // seek to the requested offset, this is 0 if it's not a partial content request
                     fseek($file, 2000000000, SEEK_CUR);
                     $relOffset -= 2000000000;
                     // This works because we never overcome the PHP 32 bit limit
                 }
                 fseek($file, $relOffset, SEEK_CUR);
                 while (ob_get_level()) {
                     ob_end_flush();
                 }
                 $readSize = 0.0;
                 $bufferSize = 1024 * 8;
                 while (!feof($file) && $readSize < $length && connection_status() == 0) {
                     $this->logDebug("dl reading {$readSize} to {$length}", $_SERVER["HTTP_RANGE"]);
                     echo fread($file, $bufferSize);
                     $readSize += $bufferSize;
                     flush();
                 }
                 fclose($file);
                 return;
             } else {
                 if ($gzip) {
                     $gzippedData = $data ? gzencode($filePathOrData, 9) : gzencode(file_get_contents($filePathOrData), 9);
                     $size = strlen($gzippedData);
                 }
                 HTMLWriter::generateAttachmentsHeader($localName, $size, $isFile, $gzip);
                 if ($gzip) {
                     print $gzippedData;
                     return;
                 }
             }
         }
     }
     if ($data) {
         print $filePathOrData;
     } else {
         if ($this->getFilteredOption("USE_XSENDFILE", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper") {
             if (!$realfileSystem) {
                 $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData);
             }
             $filePathOrData = str_replace("\\", "/", $filePathOrData);
             $server_name = $_SERVER["SERVER_SOFTWARE"];
             $regex = '/^(lighttpd\\/1.4).([0-9]{2}$|[0-9]{3}$|[0-9]{4}$)+/';
             if (preg_match($regex, $server_name)) {
                 $header_sendfile = "X-LIGHTTPD-send-file";
             } else {
                 $header_sendfile = "X-Sendfile";
             }
             header($header_sendfile . ": " . SystemTextEncoding::toUTF8($filePathOrData));
             header("Content-type: application/octet-stream");
             header('Content-Disposition: attachment; filename="' . basename($filePathOrData) . '"');
             return;
         }
         if ($this->getFilteredOption("USE_XACCELREDIRECT", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper" && array_key_exists("X-Accel-Mapping", $_SERVER)) {
             if (!$realfileSystem) {
                 $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData);
             }
             $filePathOrData = str_replace("\\", "/", $filePathOrData);
             $filePathOrData = SystemTextEncoding::toUTF8($filePathOrData);
             $mapping = explode('=', $_SERVER['X-Accel-Mapping']);
             $replacecount = 0;
             $accelfile = str_replace($mapping[0], $mapping[1], $filePathOrData, $replacecount);
             if ($replacecount == 1) {
                 header("X-Accel-Redirect: {$accelfile}");
                 header("Content-type: application/octet-stream");
                 header('Content-Disposition: attachment; filename="' . basename($accelfile) . '"');
                 return;
             } else {
                 $this->logError("X-Accel-Redirect", "Problem with X-Accel-Mapping for file {$filePathOrData}");
             }
         }
         $stream = fopen("php://output", "a");
         if ($realfileSystem) {
             $this->logDebug("realFS!", array("file" => $filePathOrData));
             $fp = fopen($filePathOrData, "rb");
             if ($byteOffset != -1) {
                 fseek($fp, $byteOffset);
             }
             $sentSize = 0;
             $readChunk = 4096;
             while (!feof($fp)) {
                 if ($byteLength != -1 && $sentSize + $readChunk >= $byteLength) {
                     // compute last chunk and break after
                     $readChunk = $byteLength - $sentSize;
                     $break = true;
                 }
                 $data = fread($fp, $readChunk);
                 $dataSize = strlen($data);
                 fwrite($stream, $data, $dataSize);
                 $sentSize += $dataSize;
                 if (isset($break)) {
                     break;
                 }
             }
             fclose($fp);
         } else {
             call_user_func(array($this->wrapperClassName, "copyFileInStream"), $filePathOrData, $stream);
         }
         fflush($stream);
         fclose($stream);
     }
 }
Esempio n. 2
0
 /**
  * Returns the mime type of a resource.
  *
  * Return the mime type of the resource identified by $path. If a mime type
  * extension is available it will be used to read the real mime type,
  * otherwise the original mime type passed by the client when uploading the
  * file will be returned. If no mimetype has ever been associated with the
  * file, the method will just return 'application/octet-stream'.
  * 
  * @param string $path 
  * @return string
  */
 protected function getMimeType($path)
 {
     // Check if extension pecl/fileinfo is usable.
     if ($this->options->useMimeExts && ezcBaseFeatures::hasExtensionSupport('fileinfo')) {
         $fInfo = new fInfo(FILEINFO_MIME);
         $mimeType = $fInfo->file($this->root . $path);
         // The documentation tells to do this, but it does not work with a
         // current version of pecl/fileinfo
         // $fInfo->close();
         return $mimeType;
     }
     // Check if extension ext/mime-magic is usable.
     if ($this->options->useMimeExts && ezcBaseFeatures::hasExtensionSupport('mime_magic') && ($mimeType = mime_content_type($this->root . $path)) !== false) {
         return $mimeType;
     }
     // Check if some browser submitted mime type is available.
     $storage = $this->getPropertyStorage($path);
     $properties = $storage->getAllProperties();
     if (isset($properties['DAV:']['getcontenttype'])) {
         return $properties['DAV:']['getcontenttype']->mime;
     }
     // Default to 'application/octet-stream' if nothing else is available.
     return 'application/octet-stream';
 }
 function readFile($filePathOrData, $headerType = "plain", $localName = "", $data = false, $gzip = null, $realfileSystem = false, $byteOffset = -1, $byteLength = -1)
 {
     if ($gzip === null) {
         $gzip = ConfService::getCoreConf("GZIP_COMPRESSION");
     }
     if (!$realfileSystem && $this->wrapperClassName == "fsAccessWrapper") {
         $originalFilePath = $filePathOrData;
         $filePathOrData = fsAccessWrapper::patchPathForBaseDir($filePathOrData);
     }
     session_write_close();
     restore_error_handler();
     restore_exception_handler();
     set_exception_handler('download_exception_handler');
     set_error_handler('download_exception_handler');
     // required for IE, otherwise Content-disposition is ignored
     if (ini_get('zlib.output_compression')) {
         AJXP_Utils::safeIniSet('zlib.output_compression', 'Off');
     }
     $isFile = !$data && !$gzip;
     if ($byteLength == -1) {
         if ($data) {
             $size = strlen($filePathOrData);
         } else {
             if ($realfileSystem) {
                 $size = sprintf("%u", filesize($filePathOrData));
             } else {
                 $size = $this->filesystemFileSize($filePathOrData);
             }
         }
     } else {
         $size = $byteLength;
     }
     if ($gzip && ($size > ConfService::getCoreConf("GZIP_LIMIT") || !function_exists("gzencode") || @strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === FALSE)) {
         $gzip = false;
         // disable gzip
     }
     $localName = $localName == "" ? basename(isset($originalFilePath) ? $originalFilePath : $filePathOrData) : $localName;
     if ($headerType == "plain") {
         header("Content-type:text/plain");
     } else {
         if ($headerType == "image") {
             header("Content-Type: " . AJXP_Utils::getImageMimeType(basename($filePathOrData)) . "; name=\"" . $localName . "\"");
             header("Content-Length: " . $size);
             header('Cache-Control: public');
         } else {
             /*
             			if(preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])){
             				$localName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($localName)));
             			}
             */
             if ($isFile) {
                 header("Accept-Ranges: 0-{$size}");
                 AJXP_Logger::debug("Sending accept range 0-{$size}");
             }
             // Check if we have a range header (we are resuming a transfer)
             if (isset($_SERVER['HTTP_RANGE']) && $isFile && $size != 0) {
                 if ($headerType == "stream_content") {
                     if (extension_loaded('fileinfo') && $this->wrapperClassName == "fsAccessWrapper") {
                         $fInfo = new fInfo(FILEINFO_MIME);
                         $realfile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $filePathOrData);
                         $mimeType = $fInfo->file($realfile);
                         $splitChar = explode(";", $mimeType);
                         $mimeType = trim($splitChar[0]);
                         AJXP_Logger::debug("Detected mime {$mimeType} for {$realfile}");
                     } else {
                         $mimeType = AJXP_Utils::getStreamingMimeType(basename($filePathOrData));
                     }
                     header('Content-type: ' . $mimeType);
                 }
                 // multiple ranges, which can become pretty complex, so ignore it for now
                 $ranges = explode('=', $_SERVER['HTTP_RANGE']);
                 $offsets = explode('-', $ranges[1]);
                 $offset = floatval($offsets[0]);
                 $length = floatval($offsets[1]) - $offset;
                 if (!$length) {
                     $length = $size - $offset;
                 }
                 if ($length + $offset > $size || $length < 0) {
                     $length = $size - $offset;
                 }
                 AJXP_Logger::debug('Content-Range: bytes ' . $offset . '-' . $length . '/' . $size);
                 header('HTTP/1.1 206 Partial Content');
                 header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
                 header("Content-Length: " . $length);
                 $file = fopen($filePathOrData, 'rb');
                 fseek($file, 0);
                 $relOffset = $offset;
                 while ($relOffset > 2000000000.0) {
                     // seek to the requested offset, this is 0 if it's not a partial content request
                     fseek($file, 2000000000, SEEK_CUR);
                     $relOffset -= 2000000000;
                     // This works because we never overcome the PHP 32 bit limit
                 }
                 fseek($file, $relOffset, SEEK_CUR);
                 while (ob_get_level()) {
                     ob_end_flush();
                 }
                 $readSize = 0.0;
                 $bufferSize = 1024 * 8;
                 while (!feof($file) && $readSize < $length && connection_status() == 0) {
                     AJXP_Logger::debug("dl reading {$readSize} to {$length}", $_SERVER["HTTP_RANGE"]);
                     echo fread($file, $bufferSize);
                     $readSize += $bufferSize;
                     flush();
                 }
                 fclose($file);
                 return;
             } else {
                 if ($gzip) {
                     $gzippedData = $data ? gzencode($filePathOrData, 9) : gzencode(file_get_contents($filePathOrData), 9);
                     $size = strlen($gzippedData);
                 }
                 HTMLWriter::generateAttachmentsHeader($localName, $size, $isFile, $gzip);
                 /*
                 				header("Content-Type: application/force-download; name=\"".$localName."\"");
                 				header("Content-Transfer-Encoding: binary");
                 				if($gzip){
                 					header("Content-Encoding: gzip");
                 					// If gzip, recompute data size!
                 					$gzippedData = ($data?gzencode($filePathOrData,9):gzencode(file_get_contents($filePathOrData), 9));
                 					$size = strlen($gzippedData);
                 				}
                 				header("Content-Length: ".$size);
                 				if ($isFile && ($size != 0)) header("Content-Range: bytes 0-" . ($size - 1) . "/" . $size . ";");
                 				header("Content-Disposition: attachment; filename=\"".$localName."\"");
                 				header("Expires: 0");
                 				header("Cache-Control: no-cache, must-revalidate");
                 				header("Pragma: no-cache");
                 				if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])){
                 					header("Cache-Control: max_age=0");
                 					header("Pragma: public");
                 				}
                 
                 // IE8 is dumb
                 				if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']))
                 {
                     header("Pragma: public");
                     header("Expires: 0");
                     header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                     header("Cache-Control: private",false);
                 //                    header("Content-Type: application/octet-stream");
                 }
                 
                 				// For SSL websites there is a bug with IE see article KB 323308
                 				// therefore we must reset the Cache-Control and Pragma Header
                 				if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']))
                 				{
                 					header("Cache-Control:");
                 					header("Pragma:");
                 				}
                 */
                 if ($gzip) {
                     print $gzippedData;
                     return;
                 }
             }
         }
     }
     if ($data) {
         print $filePathOrData;
     } else {
         if ($this->pluginConf["USE_XSENDFILE"] && $this->wrapperClassName == "fsAccessWrapper") {
             if (!$realfileSystem) {
                 $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData);
             }
             $filePathOrData = str_replace("\\", "/", $filePathOrData);
             header("X-Sendfile: " . SystemTextEncoding::toUTF8($filePathOrData));
             header("Content-type: application/octet-stream");
             header('Content-Disposition: attachment; filename="' . basename($filePathOrData) . '"');
             return;
         }
         $stream = fopen("php://output", "a");
         if ($realfileSystem) {
             AJXP_Logger::debug("realFS!", array("file" => $filePathOrData));
             $fp = fopen($filePathOrData, "rb");
             if ($byteOffset != -1) {
                 fseek($fp, $byteOffset);
             }
             $sentSize = 0;
             $readChunk = 4096;
             while (!feof($fp)) {
                 if ($byteLength != -1 && $sentSize + $readChunk >= $byteLength) {
                     // compute last chunk and break after
                     $readChunk = $byteLength - $sentSize;
                     $break = true;
                 }
                 $data = fread($fp, $readChunk);
                 $dataSize = strlen($data);
                 fwrite($stream, $data, $dataSize);
                 $sentSize += $dataSize;
                 if (isset($break)) {
                     break;
                 }
             }
             fclose($fp);
         } else {
             call_user_func(array($this->wrapperClassName, "copyFileInStream"), $filePathOrData, $stream);
         }
         fflush($stream);
         fclose($stream);
     }
 }