63 require_once(
"cloudfiles_exceptions.php");
64 require(
"cloudfiles_http-kt.php");
65 define(
"DEFAULT_CF_API_VERSION", 1);
66 define(
"MAX_CONTAINER_NAME_LEN", 256);
67 define(
"MAX_OBJECT_NAME_LEN", 1024);
68 define(
"MAX_OBJECT_SIZE", 5*1024*1024*1024+1);
69 define(
"AUTHURL",
"https://api.ucloudbiz.olleh.com/storage/v1/auth");
70 define(
"JPAUTHURL",
"https://api.ucloudbiz.olleh.com/storage/v1/authjp");
130 $this->storage_url = NULL;
131 $this->auth_token = NULL;
159 $this->cfs_http->ssl_use_cabundle($path);
187 list($status,$reason,$surl,$atoken) =
188 $this->cfs_http->authenticate($this->username, $this->api_key, $this->auth_host);
190 if ($status == 401) {
191 throw new AuthenticationException(
"Invalid username or access key.");
193 if ($status < 200 || $status > 299) {
194 throw new InvalidResponseException(
195 "Unexpected response (".$status.
"): ".$reason);
198 if (!($surl || $curl) || !$atoken) {
199 throw new InvalidResponseException(
200 "Expected headers missing from auth service.");
202 $this->storage_url = $surl;
203 $this->auth_token = $atoken;
227 throw new SyntaxException(
"Missing Required Interface URL's!");
232 throw new SyntaxException(
"Missing Auth Token!");
273 if (!($this->storage_url || !$this->auth_token)) {
285 $this->cfs_http->setDebug($bool);
352 if (!$this->cfs_auth->authenticated()) {
353 $e =
"Need to pass in a previously authenticated ";
354 $e .=
"CF_Authentication instance.";
355 throw new AuthenticationException($e);
357 $this->cfs_http->setCFAuth($this->cfs_auth);
368 $this->dbug = (boolean) $bool;
369 $this->cfs_http->setDebug($this->dbug);
387 $this->cfs_http->close();
412 list($status, $reason, $container_count, $total_bytes) =
413 $this->cfs_http->head_account();
414 if ($status == 401 && $this->_re_auth()) {
417 if ($status < 200 || $status > 299) {
418 throw new InvalidResponseException(
419 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
421 return array($container_count, $total_bytes);
446 if ($container_name !=
"0" and !isset($container_name))
447 throw new SyntaxException(
"Container name not set.");
449 if (!isset($container_name) or $container_name ==
"")
450 throw new SyntaxException(
"Container name not set.");
452 if (strpos($container_name,
"/") !== False) {
453 $r =
"Container name '".$container_name;
454 $r .=
"' cannot contain a '/' character.";
455 throw new SyntaxException($r);
458 throw new SyntaxException(sprintf(
459 "Container name exeeds %d bytes.",
463 $return_code = $this->cfs_http->create_container($container_name);
465 throw new InvalidResponseException(
"Invalid response ("
466 . $return_code.
"): " . $this->cfs_http->get_error());
468 if ($return_code == 401 && $this->_re_auth()) {
471 if ($return_code != 201 && $return_code != 202) {
472 throw new InvalidResponseException(
473 "Invalid response (".$return_code.
"): "
474 . $this->cfs_http->get_error());
476 return new CF_Container($this->cfs_auth, $this->cfs_http, $container_name);
503 $container_name = NULL;
505 if (is_object($container)) {
506 if (get_class($container) ==
"CF_Container") {
507 $container_name = $container->name;
510 if (is_string($container)) {
511 $container_name = $container;
514 if ($container_name !=
"0" and !isset($container_name))
515 throw new SyntaxException(
"Must specify container object or name.");
517 $return_code = $this->cfs_http->delete_container($container_name);
520 throw new InvalidResponseException(
"Failed to obtain http response");
522 if ($return_code == 401 && $this->_re_auth()) {
525 if ($return_code == 409) {
526 throw new NonEmptyContainerException(
527 "Container must be empty prior to removing it.");
529 if ($return_code == 404) {
530 throw new NoSuchContainerException(
531 "Specified container did not exist to delete.");
533 if ($return_code != 204) {
534 throw new InvalidResponseException(
535 "Invalid response (".$return_code.
"): "
536 . $this->cfs_http->get_error());
565 list($status, $reason, $count, $bytes) =
566 $this->cfs_http->head_container($container_name);
567 if ($status == 401 && $this->_re_auth()) {
570 if ($status == 404) {
571 throw new NoSuchContainerException(
"Container not found.");
573 if ($status < 200 || $status > 299) {
574 throw new InvalidResponseException(
575 "Invalid response: ".$this->cfs_http->get_error());
577 return new CF_Container($this->cfs_auth, $this->cfs_http,
578 $container_name, $count, $bytes);
607 list($status, $reason, $container_info) =
608 $this->cfs_http->list_containers_info($limit, $marker);
609 if ($status == 401 && $this->_re_auth()) {
612 if ($status < 200 || $status > 299) {
613 throw new InvalidResponseException(
614 "Invalid response: ".$this->cfs_http->get_error());
616 $containers = array();
617 foreach ($container_info as $name => $info) {
618 $containers[] =
new CF_Container($this->cfs_auth, $this->cfs_http,
619 $info[
'name'], $info[
"count"], $info[
"bytes"], False);
651 list($status, $reason, $containers) =
652 $this->cfs_http->list_containers($limit, $marker);
653 if ($status == 401 && $this->_re_auth()) {
656 if ($status < 200 || $status > 299) {
657 throw new InvalidResponseException(
658 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
699 list($status, $reason, $container_info) =
700 $this->cfs_http->list_containers_info($limit, $marker);
701 if ($status == 401 && $this->_re_auth()) {
704 if ($status < 200 || $status > 299) {
705 throw new InvalidResponseException(
706 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
708 return $container_info;
749 $this->cfs_http->setReadProgressFunc($func_name);
785 $this->cfs_http->setWriteProgressFunc($func_name);
811 $this->cfs_http->ssl_use_cabundle($path);
814 private function _re_auth()
816 $this->cfs_auth->authenticate();
817 $this->cfs_http->setCFAuth($this->cfs_auth);
860 throw new SyntaxException(
"Container name exceeds "
861 .
"maximum allowed length.");
863 if (strpos(
$name,
"/") !== False) {
864 throw new SyntaxException(
865 "Container names cannot contain a '/' character.");
870 $this->object_count = $count;
871 $this->bytes_used = $bytes;
872 $this->metadata = array();
884 $me = sprintf(
"name: %s, count: %.0f, bytes: %.0f",
885 $this->name, $this->object_count, $this->bytes_used);
943 return new CF_Object($this, $obj_name, True);
990 function list_objects($limit=0, $marker=NULL, $prefix=NULL, $path=NULL)
992 list($status, $reason, $obj_list) =
993 $this->cfs_http->list_objects($this->name, $limit,
994 $marker, $prefix, $path);
995 if ($status < 200 || $status > 299) {
996 throw new InvalidResponseException(
997 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
1046 function get_objects($limit=0, $marker=NULL, $prefix=NULL, $path=NULL, $delimiter=NULL)
1048 list($status, $reason, $obj_array) =
1049 $this->cfs_http->get_objects($this->name, $limit,
1050 $marker, $prefix, $path, $delimiter);
1051 if ($status < 200 || $status > 299) {
1052 throw new InvalidResponseException(
1053 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
1056 foreach ($obj_array as $obj) {
1057 if(!isset($obj[
'subdir'])) {
1058 $tmp =
new CF_Object($this, $obj[
"name"], False, False);
1059 $tmp->content_type = $obj[
"content_type"];
1060 $tmp->content_length = (float) $obj[
"bytes"];
1061 $tmp->set_etag($obj[
"hash"]);
1062 $tmp->last_modified = $obj[
"last_modified"];
1101 if (is_object($obj)) {
1102 if (get_class($obj) ==
"CF_Object") {
1103 $obj_name = $obj->name;
1106 if (is_string($obj)) {
1110 throw new SyntaxException(
"Object name not set.");
1113 if ($dest_obj_name === NULL) {
1114 $dest_obj_name = $obj_name;
1117 $container_name_target = NULL;
1118 if (is_object($container_target)) {
1119 if (get_class($container_target) ==
"CF_Container") {
1120 $container_name_target = $container_target->name;
1123 if (is_string($container_target)) {
1124 $container_name_target = $container_target;
1126 if (!$container_name_target) {
1127 throw new SyntaxException(
"Container name target not set.");
1130 $status = $this->cfs_http->copy_object($obj_name,$dest_obj_name,$this->name,$container_name_target,
$metadata,$headers);
1131 if ($status == 404) {
1132 $m =
"Specified object '".$this->name.
"/".$obj_name;
1133 $m.=
"' did not exist as source to copy from or '".$container_name_target.
"' did not exist as target to copy to.";
1134 throw new NoSuchObjectException($m);
1136 if ($status < 200 || $status > 299) {
1137 throw new InvalidResponseException(
1138 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
1175 if (is_object($obj)) {
1176 if (get_class($obj) ==
"CF_Object") {
1177 $obj_name = $obj->name;
1180 if (is_string($obj)) {
1184 throw new SyntaxException(
"Object name not set.");
1187 if ($dest_obj_name === NULL) {
1188 $dest_obj_name = $obj_name;
1191 $container_name_source = NULL;
1192 if (is_object($container_source)) {
1193 if (get_class($container_source) ==
"CF_Container") {
1194 $container_name_source = $container_source->name;
1197 if (is_string($container_source)) {
1198 $container_name_source = $container_source;
1200 if (!$container_name_source) {
1201 throw new SyntaxException(
"Container name source not set.");
1204 $status = $this->cfs_http->copy_object($obj_name,$dest_obj_name,$container_name_source,$this->name,
$metadata,$headers);
1205 if ($status == 404) {
1206 $m =
"Specified object '".$container_name_source.
"/".$obj_name;
1207 $m.=
"' did not exist as source to copy from or '".$this->name.
"/".$obj_name.
"' did not exist as target to copy to.";
1208 throw new NoSuchObjectException($m);
1210 if ($status < 200 || $status > 299) {
1211 throw new InvalidResponseException(
1212 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
1251 if(self::copy_object_to($obj,$container_target,$dest_obj_name,
$metadata,$headers)) {
1252 $retVal = self::delete_object($obj,$this->name);
1291 if(self::copy_object_from($obj,$container_source,$dest_obj_name,
$metadata,$headers)) {
1292 $retVal = self::delete_object($obj,$container_source);
1327 if (is_object($obj)) {
1328 if (get_class($obj) ==
"CF_Object") {
1329 $obj_name = $obj->name;
1332 if (is_string($obj)) {
1336 throw new SyntaxException(
"Object name not set.");
1339 $container_name = NULL;
1341 if($container === NULL) {
1345 if (is_object($container)) {
1346 if (get_class($container) ==
"CF_Container") {
1347 $container_name = $container->name;
1350 if (is_string($container)) {
1351 $container_name = $container;
1353 if (!$container_name) {
1354 throw new SyntaxException(
"Container name source not set.");
1358 $status = $this->cfs_http->delete_object($container_name, $obj_name);
1359 if ($status == 404) {
1360 $m =
"Specified object '".$container_name.
"/".$obj_name;
1361 $m.=
"' did not exist to delete.";
1362 throw new NoSuchObjectException($m);
1364 if ($status != 204) {
1365 throw new InvalidResponseException(
1366 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
1396 $usermetadata = array();
1397 if($index != NULL) {
1398 $usermetadata[] = CONTAINER_METADATA_HEADER_PREFIX .
"Web-Index:" . $index;
1400 if($error != NULL) {
1401 $usermetadata[] = CONTAINER_METADATA_HEADER_PREFIX .
"Web-Error:" . $error;
1403 if($listings != NULL) {
1404 $usermetadata[] = CONTAINER_METADATA_HEADER_PREFIX .
"Web-Listings:" . $listings;
1406 if($error != NULL) {
1407 $usermetadata[] = CONTAINER_METADATA_HEADER_PREFIX .
"Web-Listings-Css:" . $css;
1409 $usermetadata[] =
"X-Container-Read: " .
".r:*";
1410 return $this->addUpdate_container_metadata($usermetadata);
1432 $usermetadata = array();
1433 $usermetadata[] = CONTAINER_REMOVE_METADATA_HEADER_PREFIX .
"Web-Index:tempValue";
1434 $usermetadata[] = CONTAINER_REMOVE_METADATA_HEADER_PREFIX .
"Web-Error:tempValue";
1435 $usermetadata[] = CONTAINER_REMOVE_METADATA_HEADER_PREFIX .
"Web-Listings:tempValue";
1436 $usermetadata[] = CONTAINER_REMOVE_METADATA_HEADER_PREFIX .
"Web-Listings-Css:tempValue";
1437 $usermetadata[] =
"X-Remove-Container-Read: " .
".r:*";
1438 return $this->addUpdate_container_metadata($usermetadata);
1462 $usermetadata = array();
1463 $usermetadata[] = CONTAINER_METADATA_HEADER_PREFIX .
"Access-Log-Delivery:true";
1464 return $this->addUpdate_container_metadata($usermetadata);
1486 $usermetadata = array();
1487 $usermetadata[] = CONTAINER_REMOVE_METADATA_HEADER_PREFIX .
"Access-Log-Delivery:true";
1488 return $this->addUpdate_container_metadata($usermetadata);
1511 $usermetadata = array();
1512 $usermetadata[] =
"X-Container-Read: .r:*";
1513 return $this->addUpdate_container_metadata($usermetadata);
1535 $usermetadata = array();
1536 $usermetadata[] =
"X-Remove-Container-Read: .r:*";
1537 return $this->addUpdate_container_metadata($usermetadata);
1564 $usermetadata = array();
1567 if (is_string($key)) {
1568 $user_header = CONTAINER_METADATA_HEADER_PREFIX . $key;
1570 if (is_string($value)) {
1571 $usermetadata[] = $user_header .
": " . $value;
1573 return $this->addUpdate_container_metadata($usermetadata);
1597 $usermetadata = array();
1600 if (is_string($key)) {
1601 $user_header = CONTAINER_REMOVE_METADATA_HEADER_PREFIX . $key;
1603 $usermetadata[] = $user_header .
": tempValue";
1604 return $this->addUpdate_container_metadata($usermetadata);
1619 if ($path_name[0] ==
'/') {
1620 $path_name = mb_substr($path_name, 0, 1);
1622 $elements = explode(
'/', $path_name, -1);
1624 foreach ($elements as $idx => $val) {
1628 $build_path .=
"/" . $val;
1630 $obj =
new CF_Object($this, $build_path);
1631 $obj->content_type =
"application/directory";
1632 $obj->write(
".", 1);
1636 private function addUpdate_container_metadata($usermetadata) {
1637 if (!is_array($usermetadata)) {
1638 throw new SyntaxException(
"Metadata array is empty");
1641 $this->metadata = $usermetadata;
1642 $status = $this->cfs_http->post_container($this);
1644 if ($status == 404) {
1645 $m =
"Specified object '".$container_name.
"/".$obj_name;
1646 $m.=
"' did not exist to delete.";
1647 throw new NoSuchObjectException($m);
1649 if ($status != 204) {
1650 throw new InvalidResponseException(
1651 "Invalid response (".$status.
"): ".$this->cfs_http->get_error());
1688 if (
$name[0] ==
"/") {
1689 $r =
"Object name '".$name;
1690 $r .=
"' cannot contain begin with a '/' character.";
1691 throw new SyntaxException($r);
1694 throw new SyntaxException(
"Object name exceeds "
1695 .
"maximum allowed length.");
1698 $this->name =
$name;
1700 $this->_etag_override = False;
1701 $this->last_modified = NULL;
1702 $this->content_type = NULL;
1703 $this->content_length = 0;
1704 $this->metadata = array();
1705 $this->headers = array();
1706 $this->manifest = NULL;
1708 if (!$this->_initialize() && $force_exists) {
1709 throw new NoSuchObjectException(
"No such object '".
$name.
"'");
1723 return $this->container->name .
"/" .
$this->name;
1749 if ($this->content_type)
1752 if (function_exists(
"finfo_open")) {
1753 $local_magic = dirname(__FILE__) .
"/share/magic";
1754 $finfo = @finfo_open(FILEINFO_MIME, $local_magic);
1757 $finfo = @finfo_open(FILEINFO_MIME);
1761 if (is_file((
string)$handle))
1762 $ct = @finfo_file($finfo, $handle);
1764 $ct = @finfo_buffer($finfo, $handle);
1770 $extra_content_type_info = strpos($ct,
"; ");
1771 if ($extra_content_type_info)
1772 $ct = substr($ct, 0, $extra_content_type_info);
1775 if ($ct && $ct !=
'application/octet-stream')
1776 $this->content_type = $ct;
1778 @finfo_close($finfo);
1782 if (!$this->content_type && (
string)is_file($handle) && function_exists(
"mime_content_type")) {
1783 $this->content_type = @mime_content_type($handle);
1786 if (!$this->content_type) {
1787 throw new BadContentTypeException(
"Required Content-Type not set");
1823 list($status, $reason, $data) =
1824 $this->container->cfs_http->get_object_to_string($this, $hdrs);
1825 #if ($status == 401 && $this->_re_auth()) {
1826 # return $this->read($hdrs);
1828 if (($status < 200) || ($status > 299
1829 && $status != 412 && $status != 304)) {
1830 throw new InvalidResponseException(
"Invalid response (".$status.
"): "
1831 . $this->container->cfs_http->get_error());
1880 list($status, $reason) =
1881 $this->container->cfs_http->get_object_to_stream($this,$fp,$hdrs);
1882 #if ($status == 401 && $this->_re_auth()) {
1883 # return $this->stream($fp, $hdrs);
1885 if (($status < 200) || ($status > 299
1886 && $status != 412 && $status != 304)) {
1887 throw new InvalidResponseException(
"Invalid response (".$status.
"): "
1931 if (!empty($this->metadata) || !empty($this->headers) || $this->manifest) {
1932 $status = $this->container->cfs_http->update_object($this);
1933 #if ($status == 401 && $this->_re_auth()) {
1934 # return $this->sync_metadata();
1936 if ($status != 202) {
1937 throw new InvalidResponseException(
"Invalid response ("
1938 .$status.
"): ".$this->container->cfs_http->get_error());
2007 function write($data=NULL, $bytes=0, $verify=True)
2009 if (!$data && !is_string($data)) {
2010 throw new SyntaxException(
"Missing data source.");
2013 throw new SyntaxException(
"Bytes exceeds maximum object size.");
2016 if (!$this->_etag_override) {
2024 if (!is_resource($data)) {
2025 # A hack to treat string data as a file handle. php://memory feels
2026 # like a better option, but it seems to break on Windows so use
2027 # a temporary file instead.
2029 $fp = fopen(
"php://temp",
"wb+");
2030 #$fp = fopen("php://memory", "wb+");
2031 fwrite($fp, $data, strlen($data));
2034 $this->content_length = (float) strlen($data);
2036 throw new SyntaxException(
"Data exceeds maximum object size");
2038 $ct_data = substr($data, 0, 64);
2040 $this->content_length = $bytes;
2042 $ct_data = fread($data, 64);
2048 list($status, $reason, $etag) =
2049 $this->container->cfs_http->put_object($this, $fp);
2050 #if ($status == 401 && $this->_re_auth()) {
2051 # return $this->write($data, $bytes, $verify);
2053 if ($status == 412) {
2054 if ($close_fh) { fclose($fp); }
2055 throw new SyntaxException(
"Missing Content-Type header");
2057 if ($status == 422) {
2058 if ($close_fh) { fclose($fp); }
2059 throw new MisMatchedChecksumException(
2060 "Supplied and computed checksums do not match.");
2062 if ($status != 201) {
2063 if ($close_fh) { fclose($fp); }
2064 throw new InvalidResponseException(
"Invalid response (".$status.
"): "
2065 . $this->container->cfs_http->get_error());
2068 $this->etag = $etag;
2070 if ($close_fh) { fclose($fp); }
2105 $fp = @fopen($filename,
"r");
2107 throw new IOException(
"Could not open file for reading: ".$filename);
2112 $size = (float) sprintf(
"%u", filesize($filename));
2114 throw new SyntaxException(
"File size exceeds maximum object size.");
2118 $this->
write($fp, $size, $verify);
2149 $fp = @fopen($filename,
"wb");
2151 throw new IOException(
"Could not open file for writing: ".$filename);
2153 $result = $this->
stream($fp);
2169 $this->etag = $etag;
2170 $this->_etag_override = True;
2202 if (function_exists(
"hash_init") && is_resource($data)) {
2203 $ctx = hash_init(
'md5');
2204 while (!feof($data)) {
2205 $buffer = fgets($data, 65536);
2206 hash_update($ctx, $buffer);
2208 $md5 = hash_final($ctx,
false);
2210 } elseif ((
string)is_file($data)) {
2211 $md5 = md5_file($data);
2221 private function _initialize()
2225 $this->container->cfs_http->head_object($this);
2226 if ($status == 404) {
2229 if ($status < 200 || $status > 299) {
2230 throw new InvalidResponseException(
"Invalid response (".$status.
"): "
2231 . $this->container->cfs_http->get_error());
2233 $this->etag = $etag;
enableStaticWebsiteConfig($index=NULL, $error=NULL, $listings=NULL, $css=NULL)
delete_container($container=NULL)
list_containers_info($limit=0, $marker=NULL)
load_from_filename($filename, $verify=True)
_guess_content_type($handle)
const MAX_OBJECT_NAME_LEN
delete_container_user_metadata($key)
const MAX_CONTAINER_NAME_LEN
list_containers($limit=0, $marker=NULL)
get_objects($limit=0, $marker=NULL, $prefix=NULL, $path=NULL, $delimiter=NULL)
stream(&$fp, $hdrs=array())
set_read_progress_function($func_name)
move_object_from($obj, $container_source, $dest_obj_name=NULL, $metadata=NULL, $headers=NULL)
addUpdate_container_user_metadata($key, $value)
ssl_use_cabundle($path=NULL)
copy_object_to($obj, $container_target, $dest_obj_name=NULL, $metadata=NULL, $headers=NULL)
create_object($obj_name=NULL)
ssl_use_cabundle($path=NULL)
set_write_progress_function($func_name)
__construct(&$container, $name, $force_exists=False, $dohead=True)
create_container($container_name=NULL)
__construct(&$cfs_auth, &$cfs_http, $name, $count=0, $bytes=0)
write($data=NULL, $bytes=0, $verify=True)
delete_object($obj, $container=NULL)
get_object($obj_name=NULL)
save_to_filename($filename)
disableStaticWebsiteConfig()
__construct($username=NULL, $api_key=NULL, $auth_host=AUTHURL)
list_objects($limit=0, $marker=NULL, $prefix=NULL, $path=NULL)
move_object_to($obj, $container_target, $dest_obj_name=NULL, $metadata=NULL, $headers=NULL)
load_cached_credentials($auth_token, $storage_url)
copy_object_from($obj, $container_source, $dest_obj_name=NULL, $metadata=NULL, $headers=NULL)
disableContainerLogging()
authenticate($version=DEFAULT_CF_API_VERSION)
get_containers($limit=0, $marker=NULL)
get_container($container_name=NULL)
const DEFAULT_CF_API_VERSION