diff --git a/src/_h5ai/client/js/inc/ext/download.js b/src/_h5ai/client/js/inc/ext/download.js index 6b5cf4e9..cc9cd736 100644 --- a/src/_h5ai/client/js/inc/ext/download.js +++ b/src/_h5ai/client/js/inc/ext/download.js @@ -3,8 +3,7 @@ modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'co var settings = _.extend({ enabled: false, - execution: 'php', - format: 'zip', + type: 'php-tar', packageName: 'package' }, allsettings.download), @@ -50,7 +49,7 @@ modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'co server.request({ action: 'createArchive', - execution: settings.execution, + type: settings.type, format: settings.format, hrefs: hrefsStr }, handleResponse); @@ -72,21 +71,16 @@ modulejs.define('ext/download', ['_', '$', 'core/settings', 'core/resource', 'co onClick = function (event) { - var exe = settings.execution.toUpperCase(); + var type = settings.type, + extension = type === 'shell-zip' ? 'zip' : 'tar', + query = '?action=passArchive' + + '&as=' + encodeURIComponent((settings.packageName || location.getItem().label) + '.' + extension) + + '&type=' + type + + '&hrefs=' + encodeURIComponent(selectedHrefsStr), + $iframe = $('<iframe src="' + query + '" style="display: none;" />'); - if (exe === 'PHP') { - - event.preventDefault(); - requestArchive(selectedHrefsStr); - - } else if (exe === 'SHELL') { - - var query = '?action=passArchive'; - query += '&as=' + encodeURIComponent((settings.packageName || location.getItem().label) + '.' + settings.format); - query += '&format=' + settings.format; - query += '&hrefs=' + encodeURIComponent(selectedHrefsStr); - window.location = query; - } + $iframe.appendTo('body'); + setTimeout(function () { $iframe.remove(); }, 1000); }, init = function () { diff --git a/src/_h5ai/conf/options.json b/src/_h5ai/conf/options.json index deb35704..e9ae07c5 100644 --- a/src/_h5ai/conf/options.json +++ b/src/_h5ai/conf/options.json @@ -99,14 +99,12 @@ Options /* Enable packaged download of selected entries. - - execution: "php" or "shell" - - format: "tar" or "zip" + - type: "php-tar", "shell-tar" or "shell-zip" - packageName: basename of the download package, null for current foldername */ "download": { "enabled": true, - "execution": "shell", - "format": "tar", + "type": "php-tar", "packageName": null }, diff --git a/src/_h5ai/server/php/inc/Api.php b/src/_h5ai/server/php/inc/Api.php index cce34364..5e208467 100644 --- a/src/_h5ai/server/php/inc/Api.php +++ b/src/_h5ai/server/php/inc/Api.php @@ -155,7 +155,7 @@ class Api { json_fail(1, "downloads disabled", !$options["download"]["enabled"]); - list($as, $format, $hrefs) = use_request_params(array("as", "format", "hrefs")); + list($as, $type, $hrefs) = use_request_params(array("as", "type", "hrefs")); normalized_require_once("/server/php/inc/Archive.php"); $archive = new Archive($this->app); @@ -165,10 +165,10 @@ class Api { header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"$as\""); header("Connection: close"); - $rc = $archive->shell_passthru($format, $hrefs); + $rc = $archive->output($type, $hrefs); if ($rc !== 0) { - json_fail($target, "package creation failed"); + json_fail("packaging failed"); } exit; } diff --git a/src/_h5ai/server/php/inc/Archive.php b/src/_h5ai/server/php/inc/Archive.php index 5efb6fd6..a00a26f7 100644 --- a/src/_h5ai/server/php/inc/Archive.php +++ b/src/_h5ai/server/php/inc/Archive.php @@ -14,7 +14,7 @@ class Archive { } - public function create($format, $hrefs) { + public function output($type, $hrefs) { $this->dirs = array(); $this->files = array(); @@ -22,62 +22,69 @@ class Archive { $this->add_hrefs($hrefs); if (count($this->dirs) === 0 && count($this->files) === 0) { - return 404; - } - - $target = $this->app->get_cache_abs_path() . "/package-" . sha1(microtime(true) . rand()) . "." . $format; - - try { - $archive = new PharData($target); - foreach ($this->dirs as $archived_dir) { - $archive->addEmptyDir($archived_dir); - } - foreach ($this->files as $real_file => $archived_file) { - $archive->addFile($real_file, $archived_file); // very, very slow :/ - } - } catch (Exeption $err) { return 500; } - return @filesize($target) ? $target : null; + if ($type === "php-tar") { + + return $this->php_tar(); + + } else if ($type === "shell-tar") { + + return $this->shell_cmd(Archive::$TAR_PASSTHRU_CMD); + + } else if ($type === "shell-zip") { + + return $this->shell_cmd(Archive::$ZIP_PASSTHRU_CMD); + } + return 500; } - public function shell_passthru($format, $hrefs) { + // public function create($format, $hrefs) { - $this->dirs = array(); - $this->files = array(); + // $this->dirs = array(); + // $this->files = array(); - $this->add_hrefs($hrefs); + // $this->add_hrefs($hrefs); - if (count($this->dirs) === 0 && count($this->files) === 0) { - return 500; - } + // if (count($this->dirs) === 0 && count($this->files) === 0) { + // return 404; + // } + // $target = $this->app->get_cache_abs_path() . "/package-" . sha1(microtime(true) . rand()) . "." . $format; + + // try { + // $archive = new PharData($target); + // foreach ($this->dirs as $archived_dir) { + // $archive->addEmptyDir($archived_dir); + // } + // foreach ($this->files as $real_file => $archived_file) { + // $archive->addFile($real_file, $archived_file); // very, very slow :/ + // } + // } catch (Exeption $err) { + // return 500; + // } + + // return @filesize($target) ? $target : null; + // } + + + private function shell_cmd($cmd) { + + $cmd = str_replace("[ROOTDIR]", "\"" . $this->app->get_abs_path() . "\"", $cmd); + $cmd = str_replace("[DIRS]", count($this->dirs) ? "\"" . implode("\" \"", array_values($this->dirs)) . "\"" : "", $cmd); + $cmd = str_replace("[FILES]", count($this->files) ? "\"" . implode("\" \"", array_values($this->files)) . "\"" : "", $cmd); try { - - if ($format === "tar") { - $cmd = Archive::$TAR_PASSTHRU_CMD; - } else if ($format === "zip") { - $cmd = Archive::$ZIP_PASSTHRU_CMD; - } else { - return 500; - } - $cmd = str_replace("[ROOTDIR]", "\"" . $this->app->get_abs_path() . "\"", $cmd); - $cmd = str_replace("[DIRS]", count($this->dirs) ? "\"" . implode("\" \"", array_values($this->dirs)) . "\"" : "", $cmd); - $cmd = str_replace("[FILES]", count($this->files) ? "\"" . implode("\" \"", array_values($this->files)) . "\"" : "", $cmd); - passthru($cmd); - } catch (Exeption $err) { return 500; } - return 0; } - private function create_tar() { + private function php_tar() { // POSIX.1-1988 UStar implementation, by @TvdW @@ -113,7 +120,7 @@ class Archive { $size = $filesizes[$file]; - $file_header = + $file_header = str_pad($filename_parts[1], 100, "\0") // first filename part ."0000755\0"."0000000\0"."0000000\0" // File mode and uid/gid .str_pad(decoct($size), 11, "0", STR_PAD_LEFT)."\0" // File size @@ -140,7 +147,6 @@ class Archive { } return 0; - }