Merge pull request #2491 from riso/xsendfile_fix_zip

improved handling of xsendfile zip generation race condition
This commit is contained in:
Bart Visscher 2013-05-03 05:37:01 -07:00
commit 05a0b4533b
2 changed files with 22 additions and 20 deletions

View File

@ -59,11 +59,7 @@ class OC_Files {
$executionTime = intval(ini_get('max_execution_time')); $executionTime = intval(ini_get('max_execution_time'));
set_time_limit(0); set_time_limit(0);
$zip = new ZipArchive(); $zip = new ZipArchive();
if ($xsendfile) { $filename = OC_Helper::tmpFile('.zip');
$filename = OC_Helper::tmpFileNoClean('.zip');
}else{
$filename = OC_Helper::tmpFile('.zip');
}
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
exit("cannot open <$filename>\n"); exit("cannot open <$filename>\n");
} }
@ -78,6 +74,9 @@ class OC_Files {
} }
} }
$zip->close(); $zip->close();
if ($xsendfile) {
$filename = OC_Helper::moveToNoClean($filename);
}
$basename = basename($dir); $basename = basename($dir);
if ($basename) { if ($basename) {
$name = $basename . '.zip'; $name = $basename . '.zip';
@ -91,17 +90,16 @@ class OC_Files {
$executionTime = intval(ini_get('max_execution_time')); $executionTime = intval(ini_get('max_execution_time'));
set_time_limit(0); set_time_limit(0);
$zip = new ZipArchive(); $zip = new ZipArchive();
if ($xsendfile) { $filename = OC_Helper::tmpFile('.zip');
$filename = OC_Helper::tmpFileNoClean('.zip');
}else{
$filename = OC_Helper::tmpFile('.zip');
}
if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
exit("cannot open <$filename>\n"); exit("cannot open <$filename>\n");
} }
$file = $dir . '/' . $files; $file = $dir . '/' . $files;
self::zipAddDir($file, $zip); self::zipAddDir($file, $zip);
$zip->close(); $zip->close();
if ($xsendfile) {
$filename = OC_Helper::moveToNoClean($filename);
}
$name = $files . '.zip'; $name = $files . '.zip';
set_time_limit($executionTime); set_time_limit($executionTime);
} else { } else {

View File

@ -541,13 +541,15 @@ class OC_Helper {
} }
/** /**
* create a temporary file with an unique filename. It will not be deleted * move a file to oc-noclean temp dir
* automatically * @param string $filename
* @param string $postfix * @return mixed
* @return string
* *
*/ */
public static function tmpFileNoClean($postfix='') { public static function moveToNoClean($filename='') {
if ($filename == '') {
return false;
}
$tmpDirNoClean=get_temp_dir().'/oc-noclean/'; $tmpDirNoClean=get_temp_dir().'/oc-noclean/';
if (!file_exists($tmpDirNoClean) || !is_dir($tmpDirNoClean)) { if (!file_exists($tmpDirNoClean) || !is_dir($tmpDirNoClean)) {
if (file_exists($tmpDirNoClean)) { if (file_exists($tmpDirNoClean)) {
@ -555,10 +557,12 @@ class OC_Helper {
} }
mkdir($tmpDirNoClean); mkdir($tmpDirNoClean);
} }
$file=$tmpDirNoClean.md5(time().rand()).$postfix; $newname=$tmpDirNoClean.basename($filename);
$fh=fopen($file, 'w'); if (rename($filename, $newname)) {
fclose($fh); return $newname;
return $file; } else {
return false;
}
} }
/** /**
@ -597,7 +601,7 @@ class OC_Helper {
} }
/** /**
* remove all files created by self::tmpFileNoClean * remove all files in PHP /oc-noclean temp dir
*/ */
public static function cleanTmpNoClean() { public static function cleanTmpNoClean() {
$tmpDirNoCleanFile=get_temp_dir().'/oc-noclean/'; $tmpDirNoCleanFile=get_temp_dir().'/oc-noclean/';