Merge pull request #114 from riso/xsendfile

Implement X-Sendfile support
This commit is contained in:
Thomas Müller 2012-11-18 04:35:46 -08:00
commit ea80a8b9e3
3 changed files with 67 additions and 4 deletions

View File

@ -56,6 +56,9 @@ if( !OC_Config::getValue( 'installed', false )) {
// Handle unexpected errors // Handle unexpected errors
register_shutdown_function('handleUnexpectedShutdown'); register_shutdown_function('handleUnexpectedShutdown');
// Delete temp folder
OC_Helper::cleanTmpNoClean();
// Exit if background jobs are disabled! // Exit if background jobs are disabled!
$appmode = OC_BackgroundJob::getExecutionType(); $appmode = OC_BackgroundJob::getExecutionType();
if( $appmode == 'none' ) { if( $appmode == 'none' ) {

View File

@ -140,6 +140,11 @@ class OC_Files {
* @param boolean $only_header ; boolean to only send header of the request * @param boolean $only_header ; boolean to only send header of the request
*/ */
public static function get($dir, $files, $only_header = false) { 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, ';')) { if(strpos($files, ';')) {
$files=explode(';', $files); $files=explode(';', $files);
} }
@ -149,7 +154,11 @@ 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();
$filename = OC_Helper::tmpFile('.zip'); if ($xsendfile) {
$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");
} }
@ -170,7 +179,11 @@ 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();
$filename = OC_Helper::tmpFile('.zip'); if ($xsendfile) {
$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");
} }
@ -191,8 +204,13 @@ class OC_Files {
ini_set('zlib.output_compression', 'off'); ini_set('zlib.output_compression', 'off');
header('Content-Type: application/zip'); header('Content-Type: application/zip');
header('Content-Length: ' . filesize($filename)); header('Content-Length: ' . filesize($filename));
self::addSendfileHeader($filename);
}else{ }else{
header('Content-Type: '.OC_Filesystem::getMimeType($filename)); 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)) { }elseif($zip or !OC_Filesystem::file_exists($filename)) {
header("HTTP/1.0 404 Not Found"); header("HTTP/1.0 404 Not Found");
@ -217,7 +235,9 @@ class OC_Files {
flush(); flush();
} }
} }
unlink($filename); if (!$xsendfile) {
unlink($filename);
}
}else{ }else{
OC_Filesystem::readfile($filename); OC_Filesystem::readfile($filename);
} }
@ -228,11 +248,20 @@ 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='') { public static function zipAddDir($dir, $zip, $internalDir='') {
$dirname=basename($dir); $dirname=basename($dir);
$zip->addEmptyDir($internalDir.$dirname); $zip->addEmptyDir($internalDir.$dirname);
$internalDir.=$dirname.='/'; $internalDir.=$dirname.='/';
$files=OC_Files::getdirectorycontent($dir); $files=OC_Files::getDirectoryContent($dir);
foreach($files as $file) { foreach($files as $file) {
$filename=$file['name']; $filename=$file['name'];
$file=$dir.'/'.$filename; $file=$dir.'/'.$filename;

View File

@ -524,6 +524,27 @@ class OC_Helper {
return $file; 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 * create a temporary folder with an unique filename
* @return string * @return string
@ -559,6 +580,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 * Adds a suffix to the name in case the file exists
* *