public function dir_rewinddir()
 {
     if ($this->dH == -1) {
         self::$currentListingIndex = 0;
     } else {
         return rewinddir($this->dH);
     }
 }
 public function switchAction($action, $httpVars, $fileVars)
 {
     $selection = new UserSelection();
     $dir = $httpVars["dir"] or "";
     $dir = AJXP_Utils::decodeSecureMagic($dir);
     if ($dir == "/") {
         $dir = "";
     }
     $selection->initFromHttpVars($httpVars);
     if (!$selection->isEmpty()) {
         //$this->filterUserSelectionToHidden($selection->getFiles());
     }
     $urlBase = "pydio://" . ConfService::getRepository()->getId();
     $mess = ConfService::getMessages();
     switch ($action) {
         case "monitor_compression":
             $percentFile = fsAccessWrapper::getRealFSReference($urlBase . $dir . "/.zip_operation_" . $httpVars["ope_id"]);
             $percent = 0;
             if (is_file($percentFile)) {
                 $percent = intval(file_get_contents($percentFile));
             }
             if ($percent < 100) {
                 AJXP_XMLWriter::header();
                 AJXP_XMLWriter::triggerBgAction("monitor_compression", $httpVars, $mess["powerfs.1"] . " ({$percent}%)", true, 1);
                 AJXP_XMLWriter::close();
             } else {
                 @unlink($percentFile);
                 AJXP_XMLWriter::header();
                 if ($httpVars["on_end"] == "reload") {
                     AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2);
                 } else {
                     $archiveName = AJXP_Utils::sanitize($httpVars["archive_name"], AJXP_SANITIZE_FILENAME);
                     $archiveName = str_replace("'", "\\'", $archiveName);
                     $jsCode = "\n                            PydioApi.getClient().downloadSelection(null, \$('download_form'), 'postcompress_download', {ope_id:'" . $httpVars["ope_id"] . "',archive_name:'" . $archiveName . "'});\n                        ";
                     AJXP_XMLWriter::triggerBgJsAction($jsCode, $mess["powerfs.3"], true);
                     AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2);
                 }
                 AJXP_XMLWriter::close();
             }
             break;
         case "postcompress_download":
             $archive = AJXP_Utils::getAjxpTmpDir() . DIRECTORY_SEPARATOR . $httpVars["ope_id"] . "_" . AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]), AJXP_SANITIZE_FILENAME);
             $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access");
             if (is_file($archive)) {
                 if (!$fsDriver->getFilteredOption("USE_XSENDFILE", ConfService::getRepository()) && !$fsDriver->getFilteredOption("USE_XACCELREDIRECT", ConfService::getRepository())) {
                     register_shutdown_function("unlink", $archive);
                 }
                 $fsDriver->readFile($archive, "force-download", $httpVars["archive_name"], false, null, true);
             } else {
                 echo "<script>alert('Cannot find archive! Is ZIP correctly installed?');</script>";
             }
             break;
         case "compress":
         case "precompress":
             $archiveName = AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]), AJXP_SANITIZE_FILENAME);
             if (!ConfService::currentContextIsCommandLine() && ConfService::backgroundActionsSupported()) {
                 $opeId = substr(md5(time()), 0, 10);
                 $httpVars["ope_id"] = $opeId;
                 AJXP_Controller::applyActionInBackground(ConfService::getRepository()->getId(), $action, $httpVars);
                 AJXP_XMLWriter::header();
                 $bgParameters = array("dir" => SystemTextEncoding::toUTF8($dir), "archive_name" => SystemTextEncoding::toUTF8($archiveName), "on_end" => isset($httpVars["on_end"]) ? $httpVars["on_end"] : "reload", "ope_id" => $opeId);
                 AJXP_XMLWriter::triggerBgAction("monitor_compression", $bgParameters, $mess["powerfs.1"] . " (0%)", true);
                 AJXP_XMLWriter::close();
                 session_write_close();
                 exit;
             }
             $rootDir = fsAccessWrapper::getRealFSReference($urlBase) . $dir;
             $percentFile = $rootDir . "/.zip_operation_" . $httpVars["ope_id"];
             $compressLocally = $action == "compress" ? true : false;
             // List all files
             $todo = array();
             $args = array();
             $replaceSearch = array($rootDir, "\\");
             $replaceReplace = array("", "/");
             foreach ($selection->getFiles() as $selectionFile) {
                 $baseFile = $selectionFile;
                 $args[] = escapeshellarg(substr($selectionFile, strlen($dir) + ($dir == "/" ? 0 : 1)));
                 $selectionFile = fsAccessWrapper::getRealFSReference($urlBase . $selectionFile);
                 $todo[] = ltrim(str_replace($replaceSearch, $replaceReplace, $selectionFile), "/");
                 if (is_dir($selectionFile)) {
                     $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($selectionFile), RecursiveIteratorIterator::SELF_FIRST);
                     foreach ($objects as $name => $object) {
                         $todo[] = str_replace($replaceSearch, $replaceReplace, $name);
                     }
                 }
                 if (trim($baseFile, "/") == "") {
                     // ROOT IS SELECTED, FIX IT
                     $args = array(escapeshellarg(basename($rootDir)));
                     $rootDir = dirname($rootDir);
                     break;
                 }
             }
             $cmdSeparator = PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows" ? "&" : ";";
             if (!$compressLocally) {
                 $archiveName = AJXP_Utils::getAjxpTmpDir() . DIRECTORY_SEPARATOR . $httpVars["ope_id"] . "_" . $archiveName;
             }
             chdir($rootDir);
             $cmd = $this->getFilteredOption("ZIP_PATH") . " -r " . escapeshellarg($archiveName) . " " . implode(" ", $args);
             $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access");
             $c = $fsDriver->getConfigs();
             if ((!isset($c["SHOW_HIDDEN_FILES"]) || $c["SHOW_HIDDEN_FILES"] == false) && stripos(PHP_OS, "win") === false) {
                 $cmd .= " -x .\\*";
             }
             $cmd .= " " . $cmdSeparator . " echo ZIP_FINISHED";
             $proc = popen($cmd, "r");
             $toks = array();
             $handled = array();
             $finishedEchoed = false;
             while (!feof($proc)) {
                 set_time_limit(20);
                 $results = fgets($proc, 256);
                 if (strlen($results) == 0) {
                 } else {
                     $tok = strtok($results, "\n");
                     while ($tok !== false) {
                         $toks[] = $tok;
                         if ($tok == "ZIP_FINISHED") {
                             $finishedEchoed = true;
                         } else {
                             $test = preg_match('/(\\w+): (.*) \\(([^\\(]+)\\) \\(([^\\(]+)\\)/', $tok, $matches);
                             if ($test !== false) {
                                 $handled[] = $matches[2];
                             }
                         }
                         $tok = strtok("\n");
                     }
                     if ($finishedEchoed) {
                         $percent = 100;
                     } else {
                         $percent = min(round(count($handled) / count($todo) * 100), 100);
                     }
                     file_put_contents($percentFile, $percent);
                 }
                 // avoid a busy wait
                 if ($percent < 100) {
                     usleep(1);
                 }
             }
             pclose($proc);
             file_put_contents($percentFile, 100);
             break;
         default:
             break;
     }
 }
示例#3
0
 public function readFile($filePathOrData, $headerType = "plain", $localName = "", $data = false, $gzip = null, $realfileSystem = false, $byteOffset = -1, $byteLength = -1)
 {
     if ($gzip === null) {
         $gzip = ConfService::getCoreConf("GZIP_COMPRESSION");
     }
     if (!$realfileSystem && $this->wrapperClassName == "fsAccessWrapper") {
         $originalFilePath = $filePathOrData;
         $filePathOrData = fsAccessWrapper::patchPathForBaseDir($filePathOrData);
     }
     session_write_close();
     restore_error_handler();
     restore_exception_handler();
     set_exception_handler('download_exception_handler');
     set_error_handler('download_exception_handler');
     // required for IE, otherwise Content-disposition is ignored
     if (ini_get('zlib.output_compression')) {
         AJXP_Utils::safeIniSet('zlib.output_compression', 'Off');
     }
     $isFile = !$data && !$gzip;
     if ($byteLength == -1) {
         if ($data) {
             $size = strlen($filePathOrData);
         } else {
             if ($realfileSystem) {
                 $size = sprintf("%u", filesize($filePathOrData));
             } else {
                 $size = $this->filesystemFileSize($filePathOrData);
             }
         }
     } else {
         $size = $byteLength;
     }
     if ($gzip && ($size > ConfService::getCoreConf("GZIP_LIMIT") || !function_exists("gzencode") || @strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === FALSE)) {
         $gzip = false;
         // disable gzip
     }
     $localName = $localName == "" ? basename(isset($originalFilePath) ? $originalFilePath : $filePathOrData) : $localName;
     if ($headerType == "plain") {
         header("Content-type:text/plain");
     } else {
         if ($headerType == "image") {
             header("Content-Type: " . AJXP_Utils::getImageMimeType(basename($filePathOrData)) . "; name=\"" . $localName . "\"");
             header("Content-Length: " . $size);
             header('Cache-Control: public');
         } else {
             /*
             if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])) {
                 $localName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($localName)));
             }
             */
             if ($isFile) {
                 header("Accept-Ranges: 0-{$size}");
                 $this->logDebug("Sending accept range 0-{$size}");
             }
             // Check if we have a range header (we are resuming a transfer)
             if (isset($_SERVER['HTTP_RANGE']) && $isFile && $size != 0) {
                 if ($headerType == "stream_content") {
                     if (extension_loaded('fileinfo') && $this->wrapperClassName == "fsAccessWrapper") {
                         $fInfo = new fInfo(FILEINFO_MIME);
                         $realfile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $filePathOrData);
                         $mimeType = $fInfo->file($realfile);
                         $splitChar = explode(";", $mimeType);
                         $mimeType = trim($splitChar[0]);
                         $this->logDebug("Detected mime {$mimeType} for {$realfile}");
                     } else {
                         $mimeType = AJXP_Utils::getStreamingMimeType(basename($filePathOrData));
                     }
                     header('Content-type: ' . $mimeType);
                 }
                 // multiple ranges, which can become pretty complex, so ignore it for now
                 $ranges = explode('=', $_SERVER['HTTP_RANGE']);
                 $offsets = explode('-', $ranges[1]);
                 $offset = floatval($offsets[0]);
                 $length = floatval($offsets[1]) - $offset;
                 if (!$length) {
                     $length = $size - $offset;
                 }
                 if ($length + $offset > $size || $length < 0) {
                     $length = $size - $offset;
                 }
                 $this->logDebug('Content-Range: bytes ' . $offset . '-' . $length . '/' . $size);
                 header('HTTP/1.1 206 Partial Content');
                 header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
                 header("Content-Length: " . $length);
                 $file = fopen($filePathOrData, 'rb');
                 fseek($file, 0);
                 $relOffset = $offset;
                 while ($relOffset > 2000000000.0) {
                     // seek to the requested offset, this is 0 if it's not a partial content request
                     fseek($file, 2000000000, SEEK_CUR);
                     $relOffset -= 2000000000;
                     // This works because we never overcome the PHP 32 bit limit
                 }
                 fseek($file, $relOffset, SEEK_CUR);
                 while (ob_get_level()) {
                     ob_end_flush();
                 }
                 $readSize = 0.0;
                 $bufferSize = 1024 * 8;
                 while (!feof($file) && $readSize < $length && connection_status() == 0) {
                     $this->logDebug("dl reading {$readSize} to {$length}", $_SERVER["HTTP_RANGE"]);
                     echo fread($file, $bufferSize);
                     $readSize += $bufferSize;
                     flush();
                 }
                 fclose($file);
                 return;
             } else {
                 if ($gzip) {
                     $gzippedData = $data ? gzencode($filePathOrData, 9) : gzencode(file_get_contents($filePathOrData), 9);
                     $size = strlen($gzippedData);
                 }
                 HTMLWriter::generateAttachmentsHeader($localName, $size, $isFile, $gzip);
                 if ($gzip) {
                     print $gzippedData;
                     return;
                 }
             }
         }
     }
     if ($data) {
         print $filePathOrData;
     } else {
         if ($this->getFilteredOption("USE_XSENDFILE", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper") {
             if (!$realfileSystem) {
                 $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData);
             }
             $filePathOrData = str_replace("\\", "/", $filePathOrData);
             $server_name = $_SERVER["SERVER_SOFTWARE"];
             $regex = '/^(lighttpd\\/1.4).([0-9]{2}$|[0-9]{3}$|[0-9]{4}$)+/';
             if (preg_match($regex, $server_name)) {
                 $header_sendfile = "X-LIGHTTPD-send-file";
             } else {
                 $header_sendfile = "X-Sendfile";
             }
             header($header_sendfile . ": " . SystemTextEncoding::toUTF8($filePathOrData));
             header("Content-type: application/octet-stream");
             header('Content-Disposition: attachment; filename="' . basename($filePathOrData) . '"');
             return;
         }
         if ($this->getFilteredOption("USE_XACCELREDIRECT", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper" && array_key_exists("X-Accel-Mapping", $_SERVER)) {
             if (!$realfileSystem) {
                 $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData);
             }
             $filePathOrData = str_replace("\\", "/", $filePathOrData);
             $filePathOrData = SystemTextEncoding::toUTF8($filePathOrData);
             $mapping = explode('=', $_SERVER['X-Accel-Mapping']);
             $replacecount = 0;
             $accelfile = str_replace($mapping[0], $mapping[1], $filePathOrData, $replacecount);
             if ($replacecount == 1) {
                 header("X-Accel-Redirect: {$accelfile}");
                 header("Content-type: application/octet-stream");
                 header('Content-Disposition: attachment; filename="' . basename($accelfile) . '"');
                 return;
             } else {
                 $this->logError("X-Accel-Redirect", "Problem with X-Accel-Mapping for file {$filePathOrData}");
             }
         }
         $stream = fopen("php://output", "a");
         if ($realfileSystem) {
             $this->logDebug("realFS!", array("file" => $filePathOrData));
             $fp = fopen($filePathOrData, "rb");
             if ($byteOffset != -1) {
                 fseek($fp, $byteOffset);
             }
             $sentSize = 0;
             $readChunk = 4096;
             while (!feof($fp)) {
                 if ($byteLength != -1 && $sentSize + $readChunk >= $byteLength) {
                     // compute last chunk and break after
                     $readChunk = $byteLength - $sentSize;
                     $break = true;
                 }
                 $data = fread($fp, $readChunk);
                 $dataSize = strlen($data);
                 fwrite($stream, $data, $dataSize);
                 $sentSize += $dataSize;
                 if (isset($break)) {
                     break;
                 }
             }
             fclose($fp);
         } else {
             call_user_func(array($this->wrapperClassName, "copyFileInStream"), $filePathOrData, $stream);
         }
         fflush($stream);
         fclose($stream);
     }
 }
 function switchAction($action, $httpVars, $fileVars)
 {
     if (!isset($this->actions[$action])) {
         return;
     }
     $selection = new UserSelection();
     $dir = $httpVars["dir"] or "";
     $dir = AJXP_Utils::securePath($dir);
     if ($dir == "/") {
         $dir = "";
     }
     $selection->initFromHttpVars($httpVars);
     if (!$selection->isEmpty()) {
         //$this->filterUserSelectionToHidden($selection->getFiles());
     }
     $urlBase = "ajxp.fs://" . ConfService::getRepository()->getId();
     $mess = ConfService::getMessages();
     switch ($action) {
         case "monitor_compression":
             $percentFile = fsAccessWrapper::getRealFSReference($urlBase . $dir . "/.zip_operation_" . $httpVars["ope_id"]);
             $percent = 0;
             if (is_file($percentFile)) {
                 $percent = intval(file_get_contents($percentFile));
             }
             if ($percent < 100) {
                 AJXP_XMLWriter::header();
                 AJXP_XMLWriter::triggerBgAction("monitor_compression", $httpVars, $mess["powerfs.1"] . " ({$percent}%)", true, 1);
                 AJXP_XMLWriter::close();
             } else {
                 @unlink($percentFile);
                 AJXP_XMLWriter::header();
                 if ($httpVars["on_end"] == "reload") {
                     AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2);
                 } else {
                     $archiveName = $httpVars["archive_name"];
                     $jsCode = "\n                            \$('download_form').action = window.ajxpServerAccessPath;\n                            \$('download_form').secure_token.value = window.Connexion.SECURE_TOKEN;\n                            \$('download_form').select('input').each(function(input){\n                                if(input.name!='get_action' && input.name!='secure_token') input.remove();\n                            });\n                            \$('download_form').insert(new Element('input', {type:'hidden', name:'ope_id', value:'" . $httpVars["ope_id"] . "'}));\n                            \$('download_form').insert(new Element('input', {type:'hidden', name:'archive_name', value:'" . $archiveName . "'}));\n                            \$('download_form').insert(new Element('input', {type:'hidden', name:'get_action', value:'postcompress_download'}));\n                            \$('download_form').submit();\n                        ";
                     AJXP_XMLWriter::triggerBgJsAction($jsCode, "powerfs.3", true);
                     AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2);
                 }
                 AJXP_XMLWriter::close();
             }
             break;
         case "postcompress_download":
             $archive = AJXP_Utils::getAjxpTmpDir() . "/" . $httpVars["ope_id"] . "_" . $httpVars["archive_name"];
             //$fsDriver = new fsAccessDriver("fake", "");
             $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access");
             $fsDriver->readFile($archive, "force-download", $httpVars["archive_name"], false, null, true);
             break;
         case "compress":
         case "precompress":
             if (!ConfService::currentContextIsCommandLine() && ConfService::backgroundActionsSupported()) {
                 $opeId = substr(md5(time()), 0, 10);
                 $httpVars["ope_id"] = $opeId;
                 AJXP_Controller::applyActionInBackground(ConfService::getRepository()->getId(), $action, $httpVars);
                 AJXP_XMLWriter::header();
                 $bgParameters = array("dir" => $dir, "archive_name" => $httpVars["archive_name"], "on_end" => isset($httpVars["on_end"]) ? $httpVars["on_end"] : "reload", "ope_id" => $opeId);
                 AJXP_XMLWriter::triggerBgAction("monitor_compression", $bgParameters, $mess["powerfs.1"] . " (0%)", true);
                 AJXP_XMLWriter::close();
                 session_write_close();
                 exit;
             }
             $rootDir = fsAccessWrapper::getRealFSReference($urlBase) . $dir;
             $percentFile = $rootDir . "/.zip_operation_" . $httpVars["ope_id"];
             $compressLocally = $action == "compress" ? true : false;
             // List all files
             $todo = array();
             $args = array();
             $replaceSearch = array($rootDir, "\\");
             $replaceReplace = array("", "/");
             foreach ($selection->getFiles() as $selectionFile) {
                 $args[] = '"' . substr($selectionFile, strlen($dir) + ($dir == "/" ? 0 : 1)) . '"';
                 $selectionFile = fsAccessWrapper::getRealFSReference($urlBase . $selectionFile);
                 $todo[] = ltrim(str_replace($replaceSearch, $replaceReplace, $selectionFile), "/");
                 if (is_dir($selectionFile)) {
                     $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($selectionFile), RecursiveIteratorIterator::SELF_FIRST);
                     foreach ($objects as $name => $object) {
                         $todo[] = str_replace($replaceSearch, $replaceReplace, $name);
                     }
                 }
             }
             $cmdSeparator = PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows" ? "&" : ";";
             $archiveName = $httpVars["archive_name"];
             if (!$compressLocally) {
                 $archiveName = AJXP_Utils::getAjxpTmpDir() . "/" . $httpVars["ope_id"] . "_" . $archiveName;
             }
             chdir($rootDir);
             $cmd = "zip -r \"" . $archiveName . "\" " . implode(" ", $args);
             $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access");
             $c = $fsDriver->getConfigs();
             if (!isset($c["SHOW_HIDDEN_FILES"]) || $c["SHOW_HIDDEN_FILES"] == false) {
                 $cmd .= " -x .\\*";
             }
             $cmd .= " " . $cmdSeparator . " echo ZIP_FINISHED";
             $proc = popen($cmd, "r");
             $toks = array();
             $handled = array();
             $finishedEchoed = false;
             while (!feof($proc)) {
                 set_time_limit(20);
                 $results = fgets($proc, 256);
                 if (strlen($results) == 0) {
                 } else {
                     $tok = strtok($results, "\n");
                     while ($tok !== false) {
                         $toks[] = $tok;
                         if ($tok == "ZIP_FINISHED") {
                             $finishedEchoed = true;
                         } else {
                             $test = preg_match('/(\\w+): (.*) \\(([^\\(]+)\\) \\(([^\\(]+)\\)/', $tok, $matches);
                             if ($test !== false) {
                                 $handled[] = $matches[2];
                             }
                         }
                         $tok = strtok("\n");
                     }
                     if ($finishedEchoed) {
                         $percent = 100;
                     } else {
                         $percent = min(round(count($handled) / count($todo) * 100), 100);
                     }
                     file_put_contents($percentFile, $percent);
                 }
                 // avoid a busy wait
                 if ($percent < 100) {
                     usleep(1);
                 }
             }
             pclose($proc);
             file_put_contents($percentFile, 100);
             break;
         default:
             break;
     }
 }
 public function dir_readdir()
 {
     $x = parent::dir_readdir();
     if (strstr($x, '%') !== false) {
         $x = urldecode($x);
     }
     return $x;
 }
 /**
  * @param string $url
  * @param AJXP_MetaStreamWrapper $crtInstance
  * @return string
  * @throws Exception
  */
 protected static function translateScheme($url, $crtInstance = null)
 {
     $parts = parse_url($url);
     $currentScheme = $parts['scheme'];
     $context = self::actualRepositoryWrapperProtocol($parts['host']);
     $newScheme = self::getNextScheme($url, $context);
     $repository = ConfService::getRepositoryById(parse_url($url, PHP_URL_HOST));
     if ($currentScheme == "pydio" && $repository->hasContentFilter()) {
         $contentFilter = $repository->getContentFilter();
         if ($contentFilter instanceof ContentFilter) {
             $baseDir = $contentFilter->getBaseDir();
             if ($crtInstance != null) {
                 $crtInstance->currentUniquePath = $contentFilter->getUniquePath();
             }
             if (!empty($baseDir) || $baseDir != "/") {
                 $crtPath = parse_url($url, PHP_URL_PATH);
                 $crtBase = basename($crtPath);
                 if (!empty($crtPath) && $crtPath != "/" && fsAccessWrapper::unPatchPathForBaseDir($crtBase) != $contentFilter->getUniquePath() && $crtBase != ".ajxp_meta") {
                     throw new Exception("Cannot find file " . $crtBase);
                 }
                 // Prepend baseDir in path
                 $url = str_replace($currentScheme . "://" . $repository->getId() . $crtPath, $currentScheme . "://" . $repository->getId() . rtrim($baseDir . $crtPath, "/"), $url);
             }
         }
     }
     $newUrl = str_replace($currentScheme . "://", $newScheme . "://", $url);
     self::applyInitPathHook($newUrl, $context);
     return $newUrl;
 }
 public function rename($from, $to)
 {
     $fromUrl = parse_url($from);
     $repoId = $fromUrl["host"];
     $repoObject = ConfService::getRepositoryById($repoId);
     $isViPR = $repoObject->getOption("IS_VIPR");
     $isDir = false;
     if ($isViPR === true) {
         if (is_dir($from . "/")) {
             $from .= '/';
             $to .= '/';
             $isDir = true;
         }
     }
     if ($isDir === true || is_dir($from)) {
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Renaming dir {$from} to {$to}");
         require_once "aws.phar";
         $fromUrl = parse_url($from);
         $repoId = $fromUrl["host"];
         $repoObject = ConfService::getRepositoryById($repoId);
         if (!isset($repoObject)) {
             $e = new Exception("Cannot find repository with id " . $repoId);
             self::$lastException = $e;
             throw $e;
         }
         // Get a client
         $options = array('key' => $repoObject->getOption("API_KEY"), 'secret' => $repoObject->getOption("SECRET_KEY"));
         $baseURL = $repoObject->getOption("STORAGE_URL");
         if (!empty($baseURL)) {
             $options["base_url"] = $baseURL;
         } else {
             $options["region"] = $repoObject->getOption("REGION");
         }
         $proxy = $repoObject->getOption("PROXY");
         if (!empty($proxy)) {
             $options['request.options'] = array('proxy' => $proxy);
         }
         $s3Client = S3Client::factory($options);
         $bucket = $repoObject->getOption("CONTAINER");
         $basePath = $repoObject->getOption("PATH");
         $fromKeyname = trim(str_replace("//", "/", $basePath . parse_url($from, PHP_URL_PATH)), '/');
         $toKeyname = trim(str_replace("//", "/", $basePath . parse_url($to, PHP_URL_PATH)), '/');
         if ($isViPR) {
             $toKeyname .= '/';
             $parts = explode('/', $bucket);
             $bucket = $parts[0];
             if (isset($parts[1])) {
                 $fromKeyname = $parts[1] . "/" . $fromKeyname;
             }
         }
         // Perform a batch of CopyObject operations.
         $batch = array();
         $iterator = $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname . "/"));
         $toDelete = array();
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Got iterator looking for prefix " . $fromKeyname . "/ , and toKeyName=" . $toKeyname);
         foreach ($iterator as $object) {
             $currentFrom = $object['Key'];
             $currentTo = $toKeyname . substr($currentFrom, strlen($fromKeyname));
             if ($isViPR) {
                 if (isset($parts[1])) {
                     $currentTo = $parts[1] . "/" . $currentTo;
                 }
             }
             AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Should move one object " . $currentFrom . " to  new key :" . $currentTo);
             $batch[] = $s3Client->getCommand('CopyObject', array('Bucket' => $bucket, 'Key' => "{$currentTo}", 'CopySource' => "{$bucket}/" . rawurlencode($currentFrom)));
             $toDelete[] = $currentFrom;
         }
         try {
             AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute batch on " . count($batch) . " objects");
             $successful = $s3Client->execute($batch);
             $failed = array();
             $iterator->rewind();
             $clear = new \Aws\S3\Model\ClearBucket($s3Client, $bucket);
             $clear->setIterator($iterator);
             $clear->clear();
         } catch (\Guzzle\Service\Exception\CommandTransferException $e) {
             $successful = $e->getSuccessfulCommands();
             $failed = $e->getFailedCommands();
         }
         if (count($failed)) {
             foreach ($failed as $c) {
                 // $c is a Aws\S3\Command\S3Command
                 AJXP_Logger::error("S3Wrapper", __FUNCTION__, "Error while copying: " . $c->getOperation()->getServiceDescription());
             }
             self::$lastException = new Exception("Failed moving folder: " . count($failed));
             return false;
         }
         return true;
     } else {
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute standard rename on " . $from . " to " . $to);
         return parent::rename($from, $to);
     }
 }
 function readFile($filePathOrData, $headerType = "plain", $localName = "", $data = false, $gzip = null, $realfileSystem = false, $byteOffset = -1, $byteLength = -1)
 {
     if ($gzip === null) {
         $gzip = ConfService::getCoreConf("GZIP_COMPRESSION");
     }
     if (!$realfileSystem && $this->wrapperClassName == "fsAccessWrapper") {
         $originalFilePath = $filePathOrData;
         $filePathOrData = fsAccessWrapper::patchPathForBaseDir($filePathOrData);
     }
     session_write_close();
     restore_error_handler();
     restore_exception_handler();
     set_exception_handler('download_exception_handler');
     set_error_handler('download_exception_handler');
     // required for IE, otherwise Content-disposition is ignored
     if (ini_get('zlib.output_compression')) {
         AJXP_Utils::safeIniSet('zlib.output_compression', 'Off');
     }
     $isFile = !$data && !$gzip;
     if ($byteLength == -1) {
         if ($data) {
             $size = strlen($filePathOrData);
         } else {
             if ($realfileSystem) {
                 $size = sprintf("%u", filesize($filePathOrData));
             } else {
                 $size = $this->filesystemFileSize($filePathOrData);
             }
         }
     } else {
         $size = $byteLength;
     }
     if ($gzip && ($size > ConfService::getCoreConf("GZIP_LIMIT") || !function_exists("gzencode") || @strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === FALSE)) {
         $gzip = false;
         // disable gzip
     }
     $localName = $localName == "" ? basename(isset($originalFilePath) ? $originalFilePath : $filePathOrData) : $localName;
     if ($headerType == "plain") {
         header("Content-type:text/plain");
     } else {
         if ($headerType == "image") {
             header("Content-Type: " . AJXP_Utils::getImageMimeType(basename($filePathOrData)) . "; name=\"" . $localName . "\"");
             header("Content-Length: " . $size);
             header('Cache-Control: public');
         } else {
             /*
             			if(preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])){
             				$localName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($localName)));
             			}
             */
             if ($isFile) {
                 header("Accept-Ranges: 0-{$size}");
                 AJXP_Logger::debug("Sending accept range 0-{$size}");
             }
             // Check if we have a range header (we are resuming a transfer)
             if (isset($_SERVER['HTTP_RANGE']) && $isFile && $size != 0) {
                 if ($headerType == "stream_content") {
                     if (extension_loaded('fileinfo') && $this->wrapperClassName == "fsAccessWrapper") {
                         $fInfo = new fInfo(FILEINFO_MIME);
                         $realfile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $filePathOrData);
                         $mimeType = $fInfo->file($realfile);
                         $splitChar = explode(";", $mimeType);
                         $mimeType = trim($splitChar[0]);
                         AJXP_Logger::debug("Detected mime {$mimeType} for {$realfile}");
                     } else {
                         $mimeType = AJXP_Utils::getStreamingMimeType(basename($filePathOrData));
                     }
                     header('Content-type: ' . $mimeType);
                 }
                 // multiple ranges, which can become pretty complex, so ignore it for now
                 $ranges = explode('=', $_SERVER['HTTP_RANGE']);
                 $offsets = explode('-', $ranges[1]);
                 $offset = floatval($offsets[0]);
                 $length = floatval($offsets[1]) - $offset;
                 if (!$length) {
                     $length = $size - $offset;
                 }
                 if ($length + $offset > $size || $length < 0) {
                     $length = $size - $offset;
                 }
                 AJXP_Logger::debug('Content-Range: bytes ' . $offset . '-' . $length . '/' . $size);
                 header('HTTP/1.1 206 Partial Content');
                 header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size);
                 header("Content-Length: " . $length);
                 $file = fopen($filePathOrData, 'rb');
                 fseek($file, 0);
                 $relOffset = $offset;
                 while ($relOffset > 2000000000.0) {
                     // seek to the requested offset, this is 0 if it's not a partial content request
                     fseek($file, 2000000000, SEEK_CUR);
                     $relOffset -= 2000000000;
                     // This works because we never overcome the PHP 32 bit limit
                 }
                 fseek($file, $relOffset, SEEK_CUR);
                 while (ob_get_level()) {
                     ob_end_flush();
                 }
                 $readSize = 0.0;
                 $bufferSize = 1024 * 8;
                 while (!feof($file) && $readSize < $length && connection_status() == 0) {
                     AJXP_Logger::debug("dl reading {$readSize} to {$length}", $_SERVER["HTTP_RANGE"]);
                     echo fread($file, $bufferSize);
                     $readSize += $bufferSize;
                     flush();
                 }
                 fclose($file);
                 return;
             } else {
                 if ($gzip) {
                     $gzippedData = $data ? gzencode($filePathOrData, 9) : gzencode(file_get_contents($filePathOrData), 9);
                     $size = strlen($gzippedData);
                 }
                 HTMLWriter::generateAttachmentsHeader($localName, $size, $isFile, $gzip);
                 /*
                 				header("Content-Type: application/force-download; name=\"".$localName."\"");
                 				header("Content-Transfer-Encoding: binary");
                 				if($gzip){
                 					header("Content-Encoding: gzip");
                 					// If gzip, recompute data size!
                 					$gzippedData = ($data?gzencode($filePathOrData,9):gzencode(file_get_contents($filePathOrData), 9));
                 					$size = strlen($gzippedData);
                 				}
                 				header("Content-Length: ".$size);
                 				if ($isFile && ($size != 0)) header("Content-Range: bytes 0-" . ($size - 1) . "/" . $size . ";");
                 				header("Content-Disposition: attachment; filename=\"".$localName."\"");
                 				header("Expires: 0");
                 				header("Cache-Control: no-cache, must-revalidate");
                 				header("Pragma: no-cache");
                 				if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])){
                 					header("Cache-Control: max_age=0");
                 					header("Pragma: public");
                 				}
                 
                 // IE8 is dumb
                 				if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']))
                 {
                     header("Pragma: public");
                     header("Expires: 0");
                     header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                     header("Cache-Control: private",false);
                 //                    header("Content-Type: application/octet-stream");
                 }
                 
                 				// For SSL websites there is a bug with IE see article KB 323308
                 				// therefore we must reset the Cache-Control and Pragma Header
                 				if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']))
                 				{
                 					header("Cache-Control:");
                 					header("Pragma:");
                 				}
                 */
                 if ($gzip) {
                     print $gzippedData;
                     return;
                 }
             }
         }
     }
     if ($data) {
         print $filePathOrData;
     } else {
         if ($this->pluginConf["USE_XSENDFILE"] && $this->wrapperClassName == "fsAccessWrapper") {
             if (!$realfileSystem) {
                 $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData);
             }
             $filePathOrData = str_replace("\\", "/", $filePathOrData);
             header("X-Sendfile: " . SystemTextEncoding::toUTF8($filePathOrData));
             header("Content-type: application/octet-stream");
             header('Content-Disposition: attachment; filename="' . basename($filePathOrData) . '"');
             return;
         }
         $stream = fopen("php://output", "a");
         if ($realfileSystem) {
             AJXP_Logger::debug("realFS!", array("file" => $filePathOrData));
             $fp = fopen($filePathOrData, "rb");
             if ($byteOffset != -1) {
                 fseek($fp, $byteOffset);
             }
             $sentSize = 0;
             $readChunk = 4096;
             while (!feof($fp)) {
                 if ($byteLength != -1 && $sentSize + $readChunk >= $byteLength) {
                     // compute last chunk and break after
                     $readChunk = $byteLength - $sentSize;
                     $break = true;
                 }
                 $data = fread($fp, $readChunk);
                 $dataSize = strlen($data);
                 fwrite($stream, $data, $dataSize);
                 $sentSize += $dataSize;
                 if (isset($break)) {
                     break;
                 }
             }
             fclose($fp);
         } else {
             call_user_func(array($this->wrapperClassName, "copyFileInStream"), $filePathOrData, $stream);
         }
         fflush($stream);
         fclose($stream);
     }
 }
 /**
  * @inheritdoc
  */
 public function rename($from, $to)
 {
     $fromUrl = parse_url($from);
     $repoId = $fromUrl["host"];
     $repoObject = ConfService::getRepositoryById($repoId);
     $isViPR = $repoObject->getOption("IS_VIPR");
     $isDir = false;
     if ($isViPR === true) {
         if (is_dir($from . "/")) {
             $from .= '/';
             $to .= '/';
             $isDir = true;
         }
     }
     if ($isDir === true || is_dir($from)) {
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Renaming dir {$from} to {$to}");
         require_once "aws-v2.phar";
         $fromUrl = parse_url($from);
         $repoId = $fromUrl["host"];
         $repoObject = ConfService::getRepositoryById($repoId);
         if (!isset($repoObject)) {
             $e = new Exception("Cannot find repository with id " . $repoId);
             self::$lastException = $e;
             throw $e;
         }
         $s3Client = self::getClientForRepository($repoObject, false);
         $bucket = $repoObject->getOption("CONTAINER");
         $basePath = $repoObject->getOption("PATH");
         $fromKeyname = trim(str_replace("//", "/", $basePath . parse_url($from, PHP_URL_PATH)), '/');
         $toKeyname = trim(str_replace("//", "/", $basePath . parse_url($to, PHP_URL_PATH)), '/');
         if ($isViPR) {
             $toKeyname .= '/';
             $parts = explode('/', $bucket);
             $bucket = $parts[0];
             if (isset($parts[1])) {
                 $fromKeyname = $parts[1] . "/" . $fromKeyname;
             }
         }
         // Perform a batch of CopyObject operations.
         $batch = array();
         $failed = array();
         $iterator = $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname . "/"));
         $toDelete = array();
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Got iterator looking for prefix " . $fromKeyname . "/ , and toKeyName=" . $toKeyname);
         foreach ($iterator as $object) {
             $currentFrom = $object['Key'];
             $currentTo = $toKeyname . substr($currentFrom, strlen($fromKeyname));
             if ($isViPR) {
                 if (isset($parts[1])) {
                     $currentTo = $parts[1] . "/" . $currentTo;
                 }
             }
             AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Should move one object " . $currentFrom . " to  new key :" . $currentTo);
             $batch[] = $s3Client->getCommand('CopyObject', array('Bucket' => $bucket, 'Key' => "{$currentTo}", 'CopySource' => "{$bucket}/" . rawurlencode($currentFrom)));
             $toDelete[] = $currentFrom;
         }
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute batch on " . count($batch) . " objects");
         ConfService::getConfStorageImpl()->_loadPluginConfig("access.s3", $globalOptions);
         $sdkVersion = $globalOptions["SDK_VERSION"];
         if ($sdkVersion === "v3") {
             foreach ($batch as $command) {
                 $successful = $s3Client->execute($command);
             }
             //We must delete the "/" in $fromKeyname because we want to delete the folder
             $clear = \Aws\S3\BatchDelete::fromIterator($s3Client, $bucket, $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname)));
             $clear->delete();
         } else {
             try {
                 $successful = $s3Client->execute($batch);
                 $clear = new \Aws\S3\Model\ClearBucket($s3Client, $bucket);
                 $iterator->rewind();
                 $clear->setIterator($iterator);
                 $clear->clear();
                 $failed = array();
             } catch (\Guzzle\Service\Exception\CommandTransferException $e) {
                 $successful = $e->getSuccessfulCommands();
                 $failed = $e->getFailedCommands();
             }
         }
         if (count($failed)) {
             foreach ($failed as $c) {
                 // $c is a Aws\S3\Command\S3Command
                 AJXP_Logger::error("S3Wrapper", __FUNCTION__, "Error while copying: " . $c->getOperation()->getServiceDescription());
             }
             self::$lastException = new Exception("Failed moving folder: " . count($failed));
             return false;
         }
         return true;
     } else {
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute standard rename on " . $from . " to " . $to);
         return parent::rename($from, $to);
     }
 }