Introduce streamer
This commit is contained in:
parent
fe32beb85d
commit
e3b95e8473
2 changed files with 120 additions and 63 deletions
|
@ -57,20 +57,15 @@ class OC_Files {
|
|||
/**
|
||||
* @param string $filename
|
||||
* @param string $name
|
||||
* @param bool $zip
|
||||
*/
|
||||
private static function sendHeaders($filename, $name, $zip = false) {
|
||||
private static function sendHeaders($filename, $name) {
|
||||
OC_Response::setContentDispositionHeader($name, 'attachment');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
OC_Response::disableCaching();
|
||||
if ($zip) {
|
||||
header('Content-Type: application/zip');
|
||||
} else {
|
||||
$filesize = \OC\Files\Filesystem::filesize($filename);
|
||||
header('Content-Type: '.\OC_Helper::getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename)));
|
||||
if ($filesize > -1) {
|
||||
OC_Response::setContentLengthHeader($filesize);
|
||||
}
|
||||
$filesize = \OC\Files\Filesystem::filesize($filename);
|
||||
header('Content-Type: '.\OC_Helper::getSecureMimeType(\OC\Files\Filesystem::getMimeType($filename)));
|
||||
if ($filesize > -1) {
|
||||
OC_Response::setContentLengthHeader($filesize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,9 +74,9 @@ class OC_Files {
|
|||
*
|
||||
* @param string $dir
|
||||
* @param string $files ; separated list of files to download
|
||||
* @param boolean $only_header ; boolean to only send header of the request
|
||||
* @param boolean $onlyHeader ; boolean to only send header of the request
|
||||
*/
|
||||
public static function get($dir, $files, $only_header = false) {
|
||||
public static function get($dir, $files, $onlyHeader = false) {
|
||||
$view = \OC\Files\Filesystem::getView();
|
||||
|
||||
if (is_array($files) && count($files) === 1) {
|
||||
|
@ -89,45 +84,48 @@ class OC_Files {
|
|||
}
|
||||
|
||||
if (is_array($files)) {
|
||||
$get_type = self::ZIP_FILES;
|
||||
$getType = self::ZIP_FILES;
|
||||
$basename = basename($dir);
|
||||
if ($basename) {
|
||||
$name = $basename . '.zip';
|
||||
$name = $basename;
|
||||
} else {
|
||||
$name = 'download.zip';
|
||||
$name = 'download';
|
||||
}
|
||||
|
||||
$filename = $dir . '/' . $name;
|
||||
} else {
|
||||
$filename = $dir . '/' . $files;
|
||||
if (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) {
|
||||
$get_type = self::ZIP_DIR;
|
||||
$getType = self::ZIP_DIR;
|
||||
// downloading root ?
|
||||
if ($files === '') {
|
||||
$name = 'download.zip';
|
||||
$name = 'download';
|
||||
} else {
|
||||
$name = $files . '.zip';
|
||||
$name = $files;
|
||||
}
|
||||
|
||||
} else {
|
||||
$get_type = self::FILE;
|
||||
$getType = self::FILE;
|
||||
$name = $files;
|
||||
}
|
||||
}
|
||||
|
||||
if ($get_type === self::FILE) {
|
||||
$zip = false;
|
||||
if ($getType === self::FILE) {
|
||||
$streamer = false;
|
||||
} else {
|
||||
$zip = new ZipStreamer\ZipStreamer();
|
||||
$streamer = new OC_Streamer();
|
||||
}
|
||||
OC_Util::obEnd();
|
||||
|
||||
try {
|
||||
if ($get_type === self::FILE) {
|
||||
if ($getType === self::FILE) {
|
||||
$view->lockFile($filename, ILockingProvider::LOCK_SHARED);
|
||||
}
|
||||
if ($zip or \OC\Files\Filesystem::isReadable($filename)) {
|
||||
self::sendHeaders($filename, $name, $zip);
|
||||
|
||||
if ($streamer) {
|
||||
$streamer->sendHeaders($name);
|
||||
} elseif (\OC\Files\Filesystem::isReadable($filename)) {
|
||||
self::sendHeaders($filename, $name);
|
||||
} elseif (!\OC\Files\Filesystem::file_exists($filename)) {
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
$tmpl = new OC_Template('', '404', 'guest');
|
||||
|
@ -137,33 +135,34 @@ class OC_Files {
|
|||
header("HTTP/1.0 403 Forbidden");
|
||||
die('403 Forbidden');
|
||||
}
|
||||
if ($only_header) {
|
||||
if ($onlyHeader) {
|
||||
return;
|
||||
}
|
||||
if ($zip) {
|
||||
if ($streamer) {
|
||||
$executionTime = intval(ini_get('max_execution_time'));
|
||||
set_time_limit(0);
|
||||
if ($get_type === self::ZIP_FILES) {
|
||||
if ($getType === self::ZIP_FILES) {
|
||||
foreach ($files as $file) {
|
||||
$file = $dir . '/' . $file;
|
||||
if (\OC\Files\Filesystem::is_file($file)) {
|
||||
$fileSize = \OC\Files\Filesystem::filesize($file);
|
||||
$fh = \OC\Files\Filesystem::fopen($file, 'r');
|
||||
$zip->addFileFromStream($fh, basename($file));
|
||||
$streamer->addFileFromStream($fh, basename($file), $fileSize);
|
||||
fclose($fh);
|
||||
} elseif (\OC\Files\Filesystem::is_dir($file)) {
|
||||
self::zipAddDir($file, $zip);
|
||||
$streamer->addDirRecoursive($file);
|
||||
}
|
||||
}
|
||||
} elseif ($get_type === self::ZIP_DIR) {
|
||||
} elseif ($getType === self::ZIP_DIR) {
|
||||
$file = $dir . '/' . $files;
|
||||
self::zipAddDir($file, $zip);
|
||||
$streamer->addDirRecoursive($file);
|
||||
}
|
||||
$zip->finalize();
|
||||
$streamer->finalize();
|
||||
set_time_limit($executionTime);
|
||||
} else {
|
||||
\OC\Files\Filesystem::readfile($filename);
|
||||
}
|
||||
if ($get_type === self::FILE) {
|
||||
if ($getType === self::FILE) {
|
||||
$view->unlockFile($filename, ILockingProvider::LOCK_SHARED);
|
||||
}
|
||||
} catch (\OCP\Lock\LockedException $ex) {
|
||||
|
@ -177,35 +176,6 @@ class OC_Files {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
* @param ZipStreamer $zip
|
||||
* @param string $internalDir
|
||||
*/
|
||||
public static function zipAddDir($dir, ZipStreamer $zip, $internalDir='') {
|
||||
$dirname=basename($dir);
|
||||
$rootDir = $internalDir.$dirname;
|
||||
if (!empty($rootDir)) {
|
||||
$zip->addEmptyDir($rootDir);
|
||||
}
|
||||
$internalDir.=$dirname.='/';
|
||||
// prevent absolute dirs
|
||||
$internalDir = ltrim($internalDir, '/');
|
||||
|
||||
$files=\OC\Files\Filesystem::getDirectoryContent($dir);
|
||||
foreach($files as $file) {
|
||||
$filename=$file['name'];
|
||||
$file=$dir.'/'.$filename;
|
||||
if(\OC\Files\Filesystem::is_file($file)) {
|
||||
$fh = \OC\Files\Filesystem::fopen($file, 'r');
|
||||
$zip->addFileFromStream($fh, $internalDir.$filename);
|
||||
fclose($fh);
|
||||
}elseif(\OC\Files\Filesystem::is_dir($file)) {
|
||||
self::zipAddDir($file, $zip, $internalDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the maximum upload size limit for apache hosts using .htaccess
|
||||
*
|
||||
|
|
87
lib/private/streamer.php
Normal file
87
lib/private/streamer.php
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Victor Dubiniuk <dubiniuk@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
use \ZipStreamer\ZipStreamer;
|
||||
use DeepDiver1975\TarStreamer\TarStreamer;
|
||||
|
||||
class OC_Streamer {
|
||||
|
||||
private $streamerInstance;
|
||||
private $extension;
|
||||
|
||||
public function __construct(){
|
||||
if (0) {
|
||||
$this->streamerInstance = new ZipStreamer();
|
||||
} else {
|
||||
$this->streamerInstance = new TarStreamer();
|
||||
}
|
||||
}
|
||||
|
||||
public function sendHeaders($name){
|
||||
$extension = $this->streamerInstance instanceof ZipStreamer ? '.zip' : '.tar';
|
||||
return $this->streamerInstance->sendHeaders($name . $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
* @param string $internalDir
|
||||
*/
|
||||
public function addDirRecoursive($dir, $internalDir='') {
|
||||
$dirname = basename($dir);
|
||||
$rootDir = $internalDir . $dirname;
|
||||
if (!empty($rootDir)) {
|
||||
$this->streamerInstance->addEmptyDir($rootDir);
|
||||
}
|
||||
$internalDir.= $dirname .= '/';
|
||||
// prevent absolute dirs
|
||||
$internalDir = ltrim($internalDir, '/');
|
||||
|
||||
$files= \OC\Files\Filesystem::getDirectoryContent($dir);
|
||||
foreach($files as $file) {
|
||||
$filename = $file['name'];
|
||||
$file = $dir . '/' . $filename;
|
||||
if(\OC\Files\Filesystem::is_file($file)) {
|
||||
$filesize = \OC\Files\Filesystem::filesize($file);
|
||||
$fh = \OC\Files\Filesystem::fopen($file, 'r');
|
||||
$this->streamerInstance->addFileFromStream($fh, $internalDir . $filename, $filesize);
|
||||
fclose($fh);
|
||||
}elseif(\OC\Files\Filesystem::is_dir($file)) {
|
||||
$this->addDirRecoursive($file, $internalDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addFileFromStream($fd, $internalName, $size){
|
||||
if ($this->streamerInstance instanceof ZipStreamer) {
|
||||
return $this->streamerInstance->addFileFromStream($fd, $internalName);
|
||||
} else {
|
||||
return $this->streamerInstance->addFileFromStream($fd, $internalName, $size);
|
||||
}
|
||||
}
|
||||
|
||||
public function addEmptyDir($dirName){
|
||||
return $this->streamerInstance->addEmptyDir($dirName);
|
||||
}
|
||||
|
||||
public function finalize(){
|
||||
return $this->streamerInstance->finalize();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue