add SWIFT (openstack object storage) storage backend
This commit is contained in:
parent
aceda02887
commit
9a707e10bf
|
@ -0,0 +1,3 @@
|
|||
*.swp
|
||||
*~
|
||||
tests/output.log
|
|
@ -0,0 +1,11 @@
|
|||
Current maintainer:
|
||||
Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
|
||||
Previous maintainer:
|
||||
Eric "EJ" Johnson <ej@racklabs.com>
|
||||
Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk>
|
||||
|
||||
Contributors:
|
||||
Paul Kehrer
|
||||
Ben Arwin
|
||||
Jordan Callicoat
|
|
@ -0,0 +1,27 @@
|
|||
Unless otherwise noted, all files are released under the MIT license,
|
||||
exceptions contain licensing information in them.
|
||||
|
||||
Copyright (C) 2008 Rackspace US, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Rackspace US, Inc. shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Rackspace US, Inc.
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
1.7.10 Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Added Streaming URI Functionality
|
||||
|
||||
1.7.9 Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Added Manifest file support for Large Objects
|
||||
|
||||
1.7.8 Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Added CDN SSL URI Stuff
|
||||
|
||||
1.7.7 Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Added CDN Purge Functionality
|
||||
|
||||
1.7.6 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk>
|
||||
* Add Cloud UK Support (conrad.weidenkeller).
|
||||
|
||||
1.7.5 - Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Added the ability to list only currently enabled CDN containers
|
||||
* Added curl timeout to CF_Http
|
||||
* Fixed some logic errors in some if statements.
|
||||
|
||||
1.7.4 - Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Added Manual SSL support for MacOSX users
|
||||
|
||||
1.7.3 - Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Fixed a Small Bug where some users were seeing response bodies for PUTs
|
||||
|
||||
1.7.1 - Conrad Weidenkeller <conrad.weidenkeller@rackspace.com>
|
||||
* Added Support for Auth Token Caching.
|
||||
|
||||
1.7.0 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk>
|
||||
* Adjust api auth to rackspacecloud not mosso (mshuler).
|
||||
|
||||
1.6.2 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk>
|
||||
* Add a close method to close all the current connection.
|
||||
* Fix when container_name is named 0.
|
||||
|
||||
1.6.1 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk>
|
||||
* Fix setting etag on objects.
|
||||
* Fix throwing proper exception when an invalid etag has been set.
|
||||
* Fix throwing proper exception when no content type has been set.
|
||||
|
||||
1.6.0 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk>
|
||||
* Add CDN ACL restriction by referrer feature.
|
||||
* Add CDN ACL restriction by User Agent feature.
|
||||
* Add documentation for log_retention method.
|
||||
* Return True if log_retention as succeeded.
|
||||
* Invalid the PHP stats cache before getting filesize.
|
||||
|
||||
1.5.1 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk> - 20091020
|
||||
* If the environement variable RACKSPACE_SERVICENET is defined then force to
|
||||
connect via rakcspace servicenet.
|
||||
|
||||
1.5.0 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk> - 20091015
|
||||
* Add the option servicenet to connection to use Rackspace service net
|
||||
instead of public network.
|
||||
|
||||
1.4.0 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk> - 20090808
|
||||
|
||||
* Add the ability to store the container log.
|
||||
|
||||
1.3.2 - Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk> - 20090606
|
||||
|
||||
* Change the Unit Tests to phpunit.
|
||||
* Automatically set the updated CA bundle when on the windows OS.
|
||||
* More simplification of the mimetype detection and support for PHP 5.3.
|
||||
* Fix documentation information about the ttl for cached object.
|
||||
* Use the hash library to compute MD5 for streams instead of storing the
|
||||
stream in memory.
|
||||
* Fix CF_Connection::get_containers to display the container name properly.
|
||||
|
||||
1.3.1 - <ej@racklabs.com> - 20090325
|
||||
|
||||
* Simplify use of FileInfo, remove packaged MIME/Magic file
|
||||
* Throw Exception if no Content-Type is set
|
||||
* Fix bug with tracking bytes transferred
|
||||
* Support/tested on Windows XP (PHP v5.2.9)
|
||||
|
||||
1.3.0 - <ej@racklabs.com> - 20090311
|
||||
|
||||
* Support for list operations in JSON/XML
|
||||
* Added support for FileInfo automatic Content-Type/MIME detection
|
||||
* Workaround for cURL's old CA bundle with CF_Connection->ssl_use_cabundle()
|
||||
* Supports limit/marker on Account and Container lists
|
||||
* Support "pathname" traversal on Container lists
|
||||
* Helper function on Container to create directory marker Objects
|
||||
* Support for chunked transfer on PUT requests
|
||||
|
||||
1.2.3 - <ej@racklabs.com> - 20081210
|
||||
|
||||
* Improved in-line comments and generated HTML docs
|
||||
* Callbacks for read/write progress on CF_Connection class
|
||||
* Fixed minor bugs
|
||||
* Started this Changelog
|
|
@ -0,0 +1,73 @@
|
|||
;; PHP Cloud Files API
|
||||
;; ========================================================================
|
||||
;; This package contains the PHP API for the Cloud Files storage system.
|
||||
;;
|
||||
;; Please see http://www.rackspacecloud.com/ for more information regarding the
|
||||
;; Cloud Files storage system.
|
||||
;;
|
||||
;; Install
|
||||
;; ------------------------------------------------------------------------
|
||||
;; Extract this archive and make sure the source code files are in your
|
||||
;; PHP "include path". To use the API in your source code, just make
|
||||
;; sure to include/require the "cloudfiles.php" script.
|
||||
;;
|
||||
;; Requirements
|
||||
;; ------------------------------------------------------------------------
|
||||
;; [mandatory] PHP version 5.x (developed against 5.2.0)
|
||||
;; [mandatory] PHP's cURL module
|
||||
;; [mandatory] PHP enabled with mbstring (multi-byte string) support
|
||||
;; [suggested] PEAR FileInfo module (for Content-Type detection)
|
||||
;;
|
||||
;; Examples
|
||||
;; ------------------------------------------------------------------------
|
||||
;; For sample code, please see the tests and API docs.
|
||||
;;
|
||||
;; Docs
|
||||
;; ------------------------------------------------------------------------
|
||||
;; The included documentation was generated directly from the source
|
||||
;; code files using the PHPDocumentor tool.
|
||||
;;
|
||||
;; This README file is actually the PHPDocumentor INI configuration file.
|
||||
;; The following packages were installed via PEAR to generate the HTML
|
||||
;; API documentation.
|
||||
;;
|
||||
;; * PEAR 1.4.11 (stable)
|
||||
;; * PhpDocumentor 1.4.2 (stable)
|
||||
;; * XML_Beautifier 1.2.0 (stable)
|
||||
;; * XML_Parser 1.3.1 (stable)
|
||||
;; * XML_Util 1.2.0 (stable)
|
||||
;;
|
||||
;; To re-generate the API docs, make sure the above software is
|
||||
;; available and run:
|
||||
;; rm -rf docs && phpdoc -c phpdoc.ini
|
||||
;;
|
||||
;; Tests
|
||||
;; ------------------------------------------------------------------------
|
||||
;; The tests are based on phpunit and are run with PHPUnit 3.3.17
|
||||
;; please follow the instructions on :
|
||||
;;
|
||||
;; http://www.phpunit.de/manual/current/en/installation.html
|
||||
;;
|
||||
;; to install PHPUnit. When installed just run the command phpunit on
|
||||
;; the top of the directory and it will launch the tests.
|
||||
;;
|
||||
;; The tests/Comprehensive.php is not enabled by default since
|
||||
;; generating big files. If you want to run it you need to go in the
|
||||
;; tests directory and run with phpunit Comprehensive.php
|
||||
;;
|
||||
;; ========================================================================
|
||||
;; The lines below here are the configuration settings for re-generating
|
||||
;; the PHP API documentation.
|
||||
;;
|
||||
[Parse Data]
|
||||
title = php-cloudfiles
|
||||
hidden = false
|
||||
parseprivate = off
|
||||
javadocdesc = off
|
||||
defaultpackagename = php-cloudfiles
|
||||
defaultcategoryname = php-cloudfiles
|
||||
target = docs
|
||||
directory = .
|
||||
ignore = share/,examples/,tests/,.git/,.gitignore,*.ini,*.swp
|
||||
output=HTML:Smarty:PHP
|
||||
readmeinstallchangelog = README,COPYING,AUTHORS,Changelog
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* Custom Exceptions for the CloudFiles API
|
||||
*
|
||||
* Requres PHP 5.x (for Exceptions and OO syntax)
|
||||
*
|
||||
* See COPYING for license information.
|
||||
*
|
||||
* @author Eric "EJ" Johnson <ej@racklabs.com>
|
||||
* @copyright Copyright (c) 2008, Rackspace US, Inc.
|
||||
* @package php-cloudfiles-exceptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom Exceptions for the CloudFiles API
|
||||
* @package php-cloudfiles-exceptions
|
||||
*/
|
||||
class SyntaxException extends Exception { }
|
||||
class AuthenticationException extends Exception { }
|
||||
class InvalidResponseException extends Exception { }
|
||||
class NonEmptyContainerException extends Exception { }
|
||||
class NoSuchObjectException extends Exception { }
|
||||
class NoSuchContainerException extends Exception { }
|
||||
class NoSuchAccountException extends Exception { }
|
||||
class MisMatchedChecksumException extends Exception { }
|
||||
class IOException extends Exception { }
|
||||
class CDNNotEnabledException extends Exception { }
|
||||
class BadContentTypeException extends Exception { }
|
||||
class InvalidUTF8Exception extends Exception { }
|
||||
class ConnectionNotOpenException extends Exception { }
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* c-hanging-comment-ender-p: nil
|
||||
* End:
|
||||
*/
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
|
@ -9,3 +9,4 @@
|
|||
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_SWIFT']='apps/files_external/lib/swift.php';
|
||||
|
|
|
@ -0,0 +1,488 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
require_once('php-cloudfiles/cloudfiles.php');
|
||||
|
||||
class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
private $host;
|
||||
private $root;
|
||||
private $user;
|
||||
private $token;
|
||||
private $secure;
|
||||
/**
|
||||
* @var CF_Authentication auth
|
||||
*/
|
||||
private $auth;
|
||||
/**
|
||||
* @var CF_Connection conn
|
||||
*/
|
||||
private $conn;
|
||||
/**
|
||||
* @var CF_Container rootContainer
|
||||
*/
|
||||
private $rootContainer;
|
||||
|
||||
private static $tempFiles=array();
|
||||
|
||||
const SUBCONTAINER_FILE='.subcontainers';
|
||||
|
||||
/**
|
||||
* translate directory path to container name
|
||||
* @param string path
|
||||
* @return string
|
||||
*/
|
||||
private function getContainerName($path){
|
||||
$path=trim($this->root.$path,'/');
|
||||
return md5($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* get container by path
|
||||
* @param string path
|
||||
* @return CF_Container
|
||||
*/
|
||||
private function getContainer($path){
|
||||
if($path=='' or $path=='/'){
|
||||
return $this->rootContainer;
|
||||
}
|
||||
try{
|
||||
$container=$this->conn->get_container($this->getContainerName($path));
|
||||
return $container;
|
||||
}catch(NoSuchContainerException $e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create container
|
||||
* @param string path
|
||||
* @return CF_Container
|
||||
*/
|
||||
private function createContainer($path){
|
||||
if($path=='' or $path=='/'){
|
||||
return $this->conn->create_container($this->getContainerName($path));
|
||||
}
|
||||
$parent=dirname($path);
|
||||
if($parent=='' or $parent=='/'){
|
||||
$parentContainer=$this->rootContainer;
|
||||
}else{
|
||||
if(!$this->containerExists($parent)){
|
||||
$parentContainer=$this->createContainer($parent);
|
||||
}else{
|
||||
$parentContainer=$this->getContainer($parent);
|
||||
}
|
||||
}
|
||||
$this->addSubContainer($parentContainer,basename($path));
|
||||
return $this->conn->create_container($this->getContainerName($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* get object by path
|
||||
* @param string path
|
||||
* @return CF_Object
|
||||
*/
|
||||
private function getObject($path){
|
||||
$container=$this->getContainer(dirname($path));
|
||||
if(is_null($container)){
|
||||
return null;
|
||||
}else{
|
||||
try{
|
||||
$obj=$container->get_object(basename($path));
|
||||
return $obj;
|
||||
}catch(NoSuchObjectException $e){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the names of all objects in a container
|
||||
* @param CF_Container
|
||||
* @return array
|
||||
*/
|
||||
private function getObjects($container){
|
||||
if(is_null($container)){
|
||||
return array();
|
||||
}else{
|
||||
$files=$container->get_objects();
|
||||
foreach($files as &$file){
|
||||
$file=$file->name;
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create object
|
||||
* @param string path
|
||||
* @return CF_Object
|
||||
*/
|
||||
private function createObject($path){
|
||||
$container=$this->getContainer(dirname($path));
|
||||
if(!is_null($container)){
|
||||
$container=$this->createContainer($path);
|
||||
}
|
||||
return $container->create_object(basename($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if an object exists
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
private function objectExists($path){
|
||||
return !is_null($this->getObject($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if container for path exists
|
||||
* @param string path
|
||||
* @return bool
|
||||
*/
|
||||
private function containerExists($path){
|
||||
return !is_null($this->getContainer($path));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the list of emulated sub containers
|
||||
* @param CF_Container container
|
||||
* @return array
|
||||
*/
|
||||
private function getSubContainers($container){
|
||||
$tmpFile=OC_Helper::tmpFile();
|
||||
$obj=$this->getSubContainerFile($container);
|
||||
try{
|
||||
$obj->save_to_filename($tmpFile);
|
||||
}catch(Exception $e){
|
||||
return array();
|
||||
}
|
||||
$obj->save_to_filename($tmpFile);
|
||||
$containers=file($tmpFile);
|
||||
unlink($tmpFile);
|
||||
foreach($containers as &$sub){
|
||||
$sub=trim($sub);
|
||||
}
|
||||
return $containers;
|
||||
}
|
||||
|
||||
/**
|
||||
* add an emulated sub container
|
||||
* @param CF_Container container
|
||||
* @param string name
|
||||
* @return bool
|
||||
*/
|
||||
private function addSubContainer($container,$name){
|
||||
if(!$name){
|
||||
return false;
|
||||
}
|
||||
$tmpFile=OC_Helper::tmpFile();
|
||||
$obj=$this->getSubContainerFile($container);
|
||||
try{
|
||||
$obj->save_to_filename($tmpFile);
|
||||
$containers=file($tmpFile);
|
||||
foreach($containers as &$sub){
|
||||
$sub=trim($sub);
|
||||
}
|
||||
if(array_search($name,$containers)!==false){
|
||||
unlink($tmpFile);
|
||||
return false;
|
||||
}else{
|
||||
$fh=fopen($tmpFile,'a');
|
||||
fwrite($fh,$name."\n");
|
||||
}
|
||||
}catch(Exception $e){
|
||||
$containers=array();
|
||||
file_put_contents($tmpFile,$name."\n");
|
||||
}
|
||||
|
||||
$obj->load_from_filename($tmpFile);
|
||||
unlink($tmpFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove an emulated sub container
|
||||
* @param CF_Container container
|
||||
* @param string name
|
||||
* @return bool
|
||||
*/
|
||||
private function removeSubContainer($container,$name){
|
||||
if(!$name){
|
||||
return false;
|
||||
}
|
||||
$tmpFile=OC_Helper::tmpFile();
|
||||
$obj=$this->getSubContainerFile($container);
|
||||
try{
|
||||
$obj->save_to_filename($tmpFile);
|
||||
$containers=file($tmpFile);
|
||||
}catch(Exception $e){
|
||||
return false;
|
||||
}
|
||||
foreach($containers as &$sub){
|
||||
$sub=trim($sub);
|
||||
}
|
||||
$i=array_search($name,$containers);
|
||||
if($i===false){
|
||||
unlink($tmpFile);
|
||||
return false;
|
||||
}else{
|
||||
unset($containers[$i]);
|
||||
file_put_contents($tmpFile,implode("\n",$containers)."\n");
|
||||
}
|
||||
|
||||
$obj->load_from_filename($tmpFile);
|
||||
unlink($tmpFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ensure a subcontainer file exists and return it's object
|
||||
* @param CF_Container container
|
||||
* @return CF_Object
|
||||
*/
|
||||
private function getSubContainerFile($container){
|
||||
try{
|
||||
return $container->get_object(self::SUBCONTAINER_FILE);
|
||||
}catch(NoSuchObjectException $e){
|
||||
return $container->create_object(self::SUBCONTAINER_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct($params){
|
||||
$this->token=$params['token'];
|
||||
$this->host=$params['host'];
|
||||
$this->user=$params['user'];
|
||||
$this->root=isset($params['root'])?$params['root']:'/';
|
||||
$this->secure=isset($params['secure'])?(bool)$params['secure']:true;
|
||||
if(substr($this->root,0,1)!='/'){
|
||||
$this->root='/'.$this->root;
|
||||
}
|
||||
$this->auth = new CF_Authentication($this->user, $this->token, null, $this->host);
|
||||
$this->auth->authenticate();
|
||||
|
||||
$this->conn = new CF_Connection($this->auth);
|
||||
|
||||
if(!$this->containerExists($this->root)){
|
||||
$this->rootContainer=$this->createContainer('/');
|
||||
}else{
|
||||
$this->rootContainer=$this->getContainer('/');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function mkdir($path){
|
||||
if($this->containerExists($path)){
|
||||
return false;
|
||||
}else{
|
||||
$this->createContainer($path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function rmdir($path){
|
||||
if(!$this->containerExists($path)){
|
||||
return false;
|
||||
}else{
|
||||
$this->emptyContainer($path);
|
||||
if($path!='' and $path!='/'){
|
||||
$parentContainer=$this->getContainer(dirname($path));
|
||||
$this->removeSubContainer($parentContainer,basename($path));
|
||||
}
|
||||
|
||||
$this->conn->delete_container($this->getContainerName($path));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private function emptyContainer($path){
|
||||
$container=$this->getContainer($path);
|
||||
if(is_null($container)){
|
||||
return;
|
||||
}
|
||||
$subContainers=$this->getSubContainers($container);
|
||||
foreach($subContainers as $sub){
|
||||
if($sub){
|
||||
$this->emptyContainer($path.'/'.$sub);
|
||||
$this->conn->delete_container($this->getContainerName($path.'/'.$sub));
|
||||
}
|
||||
}
|
||||
|
||||
$objects=$this->getObjects($container);
|
||||
foreach($objects as $object){
|
||||
$container->delete_object($object);
|
||||
}
|
||||
}
|
||||
|
||||
public function opendir($path){
|
||||
$container=$this->getContainer($path);
|
||||
$files=$this->getObjects($container);
|
||||
$i=array_search(self::SUBCONTAINER_FILE,$files);
|
||||
if($i!==false){
|
||||
unset($files[$i]);
|
||||
}
|
||||
$subContainers=$this->getSubContainers($container);
|
||||
$files=array_merge($files,$subContainers);
|
||||
$id=$this->getContainerName($path);
|
||||
OC_FakeDirStream::$dirs[$id]=$files;
|
||||
return opendir('fakedir://'.$id);
|
||||
}
|
||||
|
||||
public function filetype($path){
|
||||
if($this->containerExists($path)){
|
||||
return 'dir';
|
||||
}else{
|
||||
return 'file';
|
||||
}
|
||||
}
|
||||
|
||||
public function is_readable($path){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function is_writable($path){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function file_exists($path){
|
||||
if($this->is_dir($path)){
|
||||
return true;
|
||||
}else{
|
||||
return $this->objectExists($path);
|
||||
}
|
||||
}
|
||||
|
||||
public function file_get_contents($path){
|
||||
$obj=$this->getObject($path);
|
||||
if(is_null($obj)){
|
||||
return false;
|
||||
}
|
||||
return $obj->read();
|
||||
}
|
||||
|
||||
public function file_put_contents($path,$content){
|
||||
$obj=$this->getObject($path);
|
||||
if(is_null($obj)){
|
||||
$container=$this->getContainer(dirname($path));
|
||||
if(is_null($container)){
|
||||
return false;
|
||||
}
|
||||
$obj=$container->create_object(basename($path));
|
||||
}
|
||||
return $obj->write($content);
|
||||
}
|
||||
|
||||
public function unlink($path){
|
||||
if($this->objectExists($path)){
|
||||
$container=$this->getContainer(dirname($path));
|
||||
$container->delete_object(basename($path));
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function fopen($path,$mode){
|
||||
$obj=$this->getObject($path);
|
||||
if(is_null($obj)){
|
||||
return false;
|
||||
}
|
||||
switch($mode){
|
||||
case 'r':
|
||||
case 'rb':
|
||||
$fp = fopen('php://temp', 'r+');
|
||||
$obj->stream($fp);
|
||||
|
||||
rewind($fp);
|
||||
return $fp;
|
||||
case 'w':
|
||||
case 'wb':
|
||||
case 'a':
|
||||
case 'ab':
|
||||
case 'r+':
|
||||
case 'w+':
|
||||
case 'wb+':
|
||||
case 'a+':
|
||||
case 'x':
|
||||
case 'x+':
|
||||
case 'c':
|
||||
case 'c+':
|
||||
$tmpFile=$this->getTmpFile($path);
|
||||
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
|
||||
self::$tempFiles[$tmpFile]=$path;
|
||||
return fopen('close://'.$tmpFile,$mode);
|
||||
}
|
||||
}
|
||||
|
||||
public function writeBack($tmpFile){
|
||||
if(isset(self::$tempFiles[$tmpFile])){
|
||||
$this->fromTmpFile($tmpFile,self::$tempFiles[$tmpFile]);
|
||||
unlink($tmpFile);
|
||||
}
|
||||
}
|
||||
|
||||
public function free_space($path){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function touch($path,$mtime=null){
|
||||
if(!is_null($mtime)){
|
||||
return false;
|
||||
}
|
||||
$obj=$this->getObject($path);
|
||||
if(is_null($obj)){
|
||||
return false;
|
||||
}
|
||||
$fp = fopen('php://temp', 'r+');
|
||||
$obj->stream($fp);
|
||||
rewind($fp);
|
||||
$obj->write($fp);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
public function rename($path1,$path2){
|
||||
$sourceContainer=$this->getContainer(dirname($path1));
|
||||
$targetContainer=$this->getContainer(dirname($path2));
|
||||
return $sourceContainer->move_object_to(basename($path1),$targetContainer,basename($path2));
|
||||
}
|
||||
|
||||
public function copy($path1,$path2){
|
||||
$sourceContainer=$this->getContainer(dirname($path1));
|
||||
$targetContainer=$this->getContainer(dirname($path2));
|
||||
return $sourceContainer->copy_object_to(basename($path1),$targetContainer,basename($path2));
|
||||
}
|
||||
|
||||
public function stat($path){
|
||||
$obj=$this->getObject($path);
|
||||
if(is_null($obj)){
|
||||
return false;
|
||||
}
|
||||
return array(
|
||||
'mtime'=>strtotime($obj->last_modified),
|
||||
'size'=>$obj->content_length,
|
||||
'ctime'=>-1,
|
||||
);
|
||||
}
|
||||
|
||||
private function getTmpFile($path){
|
||||
$obj=$this->getObject($path);
|
||||
if(!is_null($obj)){
|
||||
$tmpFile=OC_Helper::tmpFile();
|
||||
$obj->save_to_filename($tmpFile);
|
||||
return $tmpFile;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function fromTmpFile($tmpFile,$path){
|
||||
$obj=$this->getObject($path);
|
||||
if(is_null($obj)){
|
||||
$obj=$this->createObject($path);
|
||||
}
|
||||
$obj->load_from_filename($tmpFile);
|
||||
}
|
||||
}
|
|
@ -21,5 +21,12 @@ return array(
|
|||
'token'=>'test',
|
||||
'token_secret'=>'test',
|
||||
'root'=>'/google',
|
||||
)
|
||||
),
|
||||
'swift'=>array(
|
||||
'run'=>true,
|
||||
'user'=>'test:tester',
|
||||
'token'=>'testing',
|
||||
'host'=>'localhost:8080/auth',
|
||||
'root'=>'/',
|
||||
),
|
||||
);
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
$config=include('apps/files_external/tests/config.php');
|
||||
if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']){
|
||||
abstract class Test_Filestorage_SWIFT extends Test_FileStorage{}
|
||||
return;
|
||||
}else{
|
||||
class Test_Filestorage_SWIFT extends Test_FileStorage {
|
||||
private $config;
|
||||
private $id;
|
||||
|
||||
public function setUp(){
|
||||
$id=uniqid();
|
||||
$this->config=include('apps/files_external/tests/config.php');
|
||||
$this->config['swift']['root'].='/'.$id;//make sure we have an new empty folder to work in
|
||||
$this->instance=new OC_Filestorage_SWIFT($this->config['swift']);
|
||||
}
|
||||
|
||||
|
||||
public function tearDown(){
|
||||
$this->instance->rmdir('');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue