From 8e190a5a97fd2be24370aa8d3f21b7641506ae92 Mon Sep 17 00:00:00 2001 From: Valerio Ponte Date: Fri, 19 Oct 2012 00:11:20 +0200 Subject: [PATCH] Moved X-Sendfile headers into OC_Files::get now should work with temp files too --- cron.php | 3 +++ lib/files.php | 59 ++++++++++++++++++++++++++++-------------- lib/filesystemview.php | 14 ---------- lib/helper.php | 30 +++++++++++++++++++++ 4 files changed, 72 insertions(+), 34 deletions(-) diff --git a/cron.php b/cron.php index cd2e155a49..a202ca60ba 100644 --- a/cron.php +++ b/cron.php @@ -56,6 +56,9 @@ if( !OC_Config::getValue( 'installed', false )) { // Handle unexpected errors register_shutdown_function('handleUnexpectedShutdown'); +// Delete temp folder +OC_Helper::cleanTmpNoClean(); + // Exit if background jobs are disabled! $appmode = OC_BackgroundJob::getExecutionType(); if( $appmode == 'none' ) { diff --git a/lib/files.php b/lib/files.php index e5bf78d032..24e3b4bfaa 100644 --- a/lib/files.php +++ b/lib/files.php @@ -42,20 +42,16 @@ class OC_Files { * - versioned */ public static function getFileInfo($path) { - $path = OC_Filesystem::normalizePath($path); if (($path == '/Shared' || substr($path, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) { if ($path == '/Shared') { list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); - } else { - $info = array(); - if (OC_Filesystem::file_exists($path)) { - $info['size'] = OC_Filesystem::filesize($path); - $info['mtime'] = OC_Filesystem::filemtime($path); - $info['ctime'] = OC_Filesystem::filectime($path); - $info['mimetype'] = OC_Filesystem::getMimeType($path); - $info['encrypted'] = false; - $info['versioned'] = false; - } + }else{ + $info['size'] = OC_Filesystem::filesize($path); + $info['mtime'] = OC_Filesystem::filemtime($path); + $info['ctime'] = OC_Filesystem::filectime($path); + $info['mimetype'] = OC_Filesystem::getMimeType($path); + $info['encrypted'] = false; + $info['versioned'] = false; } } else { $info = OC_FileCache::get($path); @@ -91,13 +87,13 @@ class OC_Files { foreach ($files as &$file) { $file['directory'] = $directory; $file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file'; - $permissions = OCP\PERMISSION_READ; + $permissions = OCP\Share::PERMISSION_READ; // NOTE: Remove check when new encryption is merged if (!$file['encrypted']) { - $permissions |= OCP\PERMISSION_SHARE; + $permissions |= OCP\Share::PERMISSION_SHARE; } if ($file['type'] == 'dir' && $file['writable']) { - $permissions |= OCP\PERMISSION_CREATE; + $permissions |= OCP\Share::PERMISSION_CREATE; } if ($file['writable']) { $permissions |= OCP\PERMISSION_UPDATE | OCP\PERMISSION_DELETE; @@ -140,6 +136,10 @@ class OC_Files { * @param boolean $only_header ; boolean to only send header of the request */ public static function get($dir, $files, $only_header = false) { + $xsendfile = false; + if (isset($_SERVER['MOD_X_SENDFILE_ENABLED']) || + isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) + $xsendfile = true; if(strpos($files, ';')) { $files=explode(';', $files); } @@ -149,8 +149,11 @@ class OC_Files { $executionTime = intval(ini_get('max_execution_time')); set_time_limit(0); $zip = new ZipArchive(); - $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { + if ($xsendfile) + $filename = OC_Helper::tmpFileNoClean('.zip'); + else + $filename = OC_Helper::tmpFile('.zip'); + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { exit("cannot open <$filename>\n"); } foreach($files as $file) { @@ -170,8 +173,11 @@ class OC_Files { $executionTime = intval(ini_get('max_execution_time')); set_time_limit(0); $zip = new ZipArchive(); - $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { + if ($xsendfile) + $filename = OC_Helper::tmpFileNoClean('.zip'); + else + $filename = OC_Helper::tmpFile('.zip'); + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { exit("cannot open <$filename>\n"); } $file=$dir.'/'.$files; @@ -191,8 +197,12 @@ class OC_Files { ini_set('zlib.output_compression', 'off'); header('Content-Type: application/zip'); header('Content-Length: ' . filesize($filename)); + self::addSendfileHeader($filename); }else{ header('Content-Type: '.OC_Filesystem::getMimeType($filename)); + $storage = OC_Filesystem::getStorage($filename); + if ($storage instanceof OC_Filestorage_Local) + self::addSendfileHeader(OC_Filesystem::getLocalFile($filename)); } }elseif($zip or !OC_Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); @@ -217,7 +227,8 @@ class OC_Files { flush(); } } - unlink($filename); + if (!$xsendfile) + unlink($filename); }else{ OC_Filesystem::readfile($filename); } @@ -228,11 +239,19 @@ class OC_Files { } } + private static function addSendfileHeader($filename) { + if (isset($_SERVER['MOD_X_SENDFILE_ENABLED'])) { + header("X-Sendfile: " . $filename); + } + if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) + header("X-Accel-Redirect: " . $filename); + } + public static function zipAddDir($dir, $zip, $internalDir='') { $dirname=basename($dir); $zip->addEmptyDir($internalDir.$dirname); $internalDir.=$dirname.='/'; - $files=OC_Files::getdirectorycontent($dir); + $files=OC_Files::getDirectoryContent($dir); foreach($files as $file) { $filename=$file['name']; $file=$dir.'/'.$filename; diff --git a/lib/filesystemview.php b/lib/filesystemview.php index a0ff527cd9..0229213ebc 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -195,7 +195,6 @@ class OC_FilesystemView { return $this->basicOperation('filesize', $path); } public function readfile($path) { - $this->addSendfileHeaders($path); @ob_end_clean(); $handle=$this->fopen($path, 'rb'); if ($handle) { @@ -209,19 +208,6 @@ class OC_FilesystemView { } return false; } - /* This adds the proper header to let the web server handle - * the file transfer, if it's configured through the right - * environment variable - */ - private function addSendfileHeaders($path) { - $storage = $this->getStorage($path); - if ($storage instanceof OC_Filestorage_Local) { - if (isset($_SERVER['MOD_X_ACCEL_REDIRECT_ENABLED'])) - header("X-Accel-Redirect: " . $this->getLocalFile($path)); - if (isset($_SERVER['MOD_X_SENDFILE_ENABLED'])) - header("X-Sendfile: " . $this->getLocalFile($path)); - } - } /** * @deprecated Replaced by isReadable() as part of CRUDS */ diff --git a/lib/helper.php b/lib/helper.php index ccceb58cd4..b5e2b8a0d4 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -524,6 +524,26 @@ class OC_Helper { return $file; } + /** + * create a temporary file with an unique filename. It will not be deleted + * automatically + * @param string $postfix + * @return string + * + */ + public static function tmpFileNoClean($postfix='') { + $tmpDirNoClean=get_temp_dir().'/oc-noclean/'; + if (!file_exists($tmpDirNoClean) || !is_dir($tmpDirNoClean)) { + if (file_exists($tmpDirNoClean)) + unlink($tmpDirNoClean); + mkdir($tmpDirNoClean); + } + $file=$tmpDirNoClean.md5(time().rand()).$postfix; + $fh=fopen($file,'w'); + fclose($fh); + return $file; + } + /** * create a temporary folder with an unique filename * @return string @@ -559,6 +579,16 @@ class OC_Helper { } } + /** + * remove all files created by self::tmpFileNoClean + */ + public static function cleanTmpNoClean() { + $tmpDirNoCleanFile=get_temp_dir().'/oc-noclean/'; + if(file_exists($tmpDirNoCleanFile)) { + self::rmdirr($tmpDirNoCleanFile); + } + } + /** * Adds a suffix to the name in case the file exists *