parent
b60b05c100
commit
3a094e2bcb
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."core".DIRECTORY_SEPARATOR."Headers.php";
|
||||
|
||||
class Consts {
|
||||
// static $Ks3EndPoint = "kss.ksyun.com";
|
||||
static $SubResource = array("acl", "lifecycle", "location", "logging", "notification", "policy", "requestPayment", "torrent", "uploadId", "uploads", "versionId","versioning", "versions", "website", "delete", "thumbnail","cors","pfop","querypfop","adp","queryadp");
|
||||
static $QueryParam = array("partNumber","response-content-type","response-content-language","response-expires", "response-cache-control","response-content-disposition", "response-content-encoding", );
|
||||
static $Acl = array("private","public-read","public-read-write");
|
||||
static $KS3HeaderPrefix = "x-kss-";
|
||||
static $CORSElements = array("AllowedMethod","AllowedOrigin","AllowedHeader","MaxAgeSeconds","ExposeHeader");
|
||||
static $BucketLoggingElements = array("TargetBucket","TargetPrefix");
|
||||
static $ObjectMeta = array("Cache-Control","Content-Disposition","Content-Encoding","Content-Length","Content-MD5","Content-Type","Expires");
|
||||
static $MultipartObjectMeta = array("Cache-Control","Content-Disposition","Content-Encoding","Content-Type","Expires");
|
||||
static $UserMetaPrefix = "x-kss-meta";
|
||||
static $ResponseObjectMeta = array(
|
||||
"cache-control"=>"Cache-Control",
|
||||
"content-disposition"=>"Content-Disposition",
|
||||
"content-encoding"=>"Content-Encoding",
|
||||
"etag"=>"ETag",
|
||||
"content-type"=>"Content-Type",
|
||||
"expires"=>"Expires",
|
||||
"last-modified"=>"Last-Modified",
|
||||
"content-range"=>"Content-Range",
|
||||
"content-length"=>"Content-Length",
|
||||
"x-kss-server-side-encryption"=>"SSEAlgm",
|
||||
"x-kss-server-side-encryption-kss-kms-key-id"=>"SSEKMSId",
|
||||
"x-kss-server-side-encryption-customer-algorithm"=>"SSECAlgm",
|
||||
"x-kss-server-side-encryption-customer-key-md5"=>"SSECKeyMD5"
|
||||
);
|
||||
static $PartsElement = array("PartNumber","ETag");
|
||||
static $UploadHandler = array(
|
||||
"etag"=>"ETag",
|
||||
"taskid"=>"TaskID",
|
||||
"x-kss-server-side-encryption"=>"SSEAlgm",
|
||||
"x-kss-server-side-encryption-kss-kms-key-id"=>"SSEKMSId",
|
||||
"x-kss-server-side-encryption-customer-algorithm"=>"SSECAlgm",
|
||||
"x-kss-server-side-encryption-customer-key-md5"=>"SSECKeyMD5"
|
||||
);
|
||||
static $SSEHandler = array(
|
||||
"x-kss-server-side-encryption"=>"SSEAlgm",
|
||||
"x-kss-server-side-encryption-kss-kms-key-id"=>"SSEKMSId",
|
||||
"x-kss-server-side-encryption-customer-algorithm"=>"SSECAlgm",
|
||||
"x-kss-server-side-encryption-customer-key-md5"=>"SSECKeyMD5"
|
||||
);
|
||||
static $Permission_Read = "READ";
|
||||
static $Permission_Write = "WRITE";
|
||||
static $Grantee_Group_All = "http://acs.ksyun.com/groups/global/AllUsers";
|
||||
static $ResponseOverrides = array("response-expires","response-content-encoding","response-content-disposition",
|
||||
"response-content-language","response-content-type","response-cache-control");
|
||||
static $CallBackMagics = array("bucket","key","etag","objectSize","mimeType","createTime");
|
||||
static $UserAgent = "ks3-kss-php-sdk";
|
||||
static $SSEDefaultAlgm = "AES256";
|
||||
}
|
||||
?>
|
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."exceptions".DIRECTORY_SEPARATOR."Exceptions.php";
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."config".DIRECTORY_SEPARATOR."Consts.php";
|
||||
|
||||
class LocationBuilder{
|
||||
function build($args){
|
||||
if(isset($args["Location"])){
|
||||
$location = $args["Location"];
|
||||
$xml = new SimpleXmlElement('<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"></CreateBucketConfiguration>');
|
||||
$xml->addChild("LocationConstraint",$args["Location"]);
|
||||
return $xml->asXml();
|
||||
}
|
||||
}
|
||||
}
|
||||
class CORSBuilder{
|
||||
function build($args){
|
||||
if(isset($args["CORS"])){
|
||||
$cors = $args["CORS"];
|
||||
$xml = new SimpleXmlElement('<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"></CORSConfiguration>');
|
||||
if(is_array($cors)){
|
||||
foreach ($cors as $key => $rule) {
|
||||
$ruleXml = $xml->addChild("CORSRule");
|
||||
if(is_array($rule)){
|
||||
foreach ($rule as $key => $value) {
|
||||
if(in_array($key,Consts::$CORSElements)){
|
||||
if(is_array($value)){
|
||||
foreach ($value as $ele) {
|
||||
$ruleXml->addChild($key,$ele);
|
||||
}
|
||||
}else{
|
||||
$ruleXml->addChild($key,$value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $xml->asXml();
|
||||
}
|
||||
}
|
||||
}
|
||||
class BucketLoggingBuilder{
|
||||
function build($args){
|
||||
if(isset($args["BucketLogging"])){
|
||||
$logging = $args["BucketLogging"];
|
||||
$xml = new SimpleXmlElement('<BucketLoggingStatus xmlns="http://s3.amazonaws.com/doc/2006-03-01/" />');
|
||||
if(is_array($logging)){
|
||||
|
||||
if(!isset($logging["Enable"]))
|
||||
throw new Ks3ClientException("bucket logging must provide Enable argument");
|
||||
|
||||
if($logging["Enable"]){
|
||||
if(!isset($logging["TargetBucket"]))
|
||||
throw new Ks3ClientException("bucket logging must provide TargetBucket argument");
|
||||
$loggingConfig = $xml->addChild("LoggingEnabled");
|
||||
foreach ($logging as $key => $value) {
|
||||
if(in_array($key,Consts::$BucketLoggingElements)){
|
||||
$loggingConfig->addChild($key,$value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $xml->asXml();
|
||||
}
|
||||
}
|
||||
}
|
||||
class DeleteObjectsBuilder{
|
||||
function build($args){
|
||||
if(isset($args["DeleteKeys"])){
|
||||
$keys = $args["DeleteKeys"];
|
||||
$xml = new SimpleXmlElement('<Delete></Delete>');
|
||||
if(is_array($keys)){
|
||||
foreach ($keys as $key => $value) {
|
||||
$object = $xml->addChild("Object");
|
||||
$object->addChild("Key",$value);
|
||||
}
|
||||
}
|
||||
return $xml->asXml();
|
||||
}
|
||||
}
|
||||
}
|
||||
class CompleteMultipartUploadBuilder{
|
||||
function build($args){
|
||||
if(isset($args["Parts"])){
|
||||
$parts = $args["Parts"];
|
||||
$xml = new SimpleXmlElement('<CompleteMultipartUpload></CompleteMultipartUpload>');
|
||||
if(is_array($parts)){
|
||||
foreach ($parts as $part) {
|
||||
$partXml = $xml->addChild("Part");
|
||||
foreach ($part as $key => $value) {
|
||||
if(in_array($key,Consts::$PartsElement)){
|
||||
$partXml->addChild($key,$value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $xml->asXml();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,343 @@
|
||||
<?php
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."exceptions".DIRECTORY_SEPARATOR."Exceptions.php";
|
||||
|
||||
interface Handler{
|
||||
public function handle(ResponseCore $response);
|
||||
}
|
||||
class ErrorResponseHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$code = $response->status;
|
||||
if($code >= 400){
|
||||
$exception = new Ks3ServiceException();
|
||||
$exception->statusCode=$code;
|
||||
if(!empty($response->body)){
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
$exception ->requestId = $xml->RequestId->__toString();
|
||||
$exception->errorCode = $xml->Code->__toString();
|
||||
$exception->errorMessage=$xml->Message->__toString();
|
||||
$exception->resource=$xml->Resource->__toString();
|
||||
}
|
||||
throw $exception;
|
||||
}else{
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
class ListBucketsHandler implements Handler{
|
||||
|
||||
public function handle(ResponseCore $response){
|
||||
$result = array();
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
foreach ($xml->Buckets->Bucket as $bucketXml) {
|
||||
$bucket = array();
|
||||
foreach ($bucketXml->children() as $key => $value) {
|
||||
$bucket[$key]=$value->__toString();
|
||||
}
|
||||
array_push($result, $bucket);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
class ListObjectsHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$result = array();
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
$result["Name"]=$xml->Name->__toString();
|
||||
$result["Prefix"]=$xml->Prefix->__toString();
|
||||
$result["Marker"]=$xml->Marker->__toString();
|
||||
$result["Delimiter"]=$xml->Delimiter->__toString();
|
||||
$result["MaxKeys"]=$xml->MaxKeys->__toString();
|
||||
$result["IsTruncated"]=$xml->IsTruncated->__toString();
|
||||
$result["NextMarker"]=$xml->NextMarker->__toString();
|
||||
$contents = array();
|
||||
foreach ($xml->Contents as $contentXml) {
|
||||
$content = array();
|
||||
foreach ($contentXml->children() as $key => $value) {
|
||||
$owner = array();
|
||||
if($key === "Owner"){
|
||||
foreach ($value->children() as $ownerkey => $ownervalue) {
|
||||
$owner[$ownerkey]=$ownervalue->__toString();
|
||||
}
|
||||
$content["Owner"] = $owner;
|
||||
}else{
|
||||
$content[$key]=$value->__toString();
|
||||
}
|
||||
}
|
||||
array_push($contents, $content);
|
||||
}
|
||||
$result["Contents"] = $contents;
|
||||
|
||||
$commonprefix = array();
|
||||
foreach ($xml->CommonPrefixes as $commonprefixXml) {
|
||||
foreach ($commonprefixXml->children() as $key => $value) {
|
||||
array_push($commonprefix, $value->__toString());
|
||||
}
|
||||
}
|
||||
$result["CommonPrefixes"] = $commonprefix;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
class GetBucketCORSHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
$cors = array();
|
||||
foreach ($xml->CORSRule as $rule) {
|
||||
$acors = array();
|
||||
foreach ($rule as $key => $value) {
|
||||
if($key === "MaxAgeSeconds")
|
||||
{
|
||||
$acors[$key] = $value->__toString();
|
||||
}else{
|
||||
if(!isset($acors[$key])){
|
||||
$acors[$key] = array();
|
||||
}
|
||||
array_push($acors[$key],$value->__toString());
|
||||
}
|
||||
}
|
||||
array_push($cors,$acors);
|
||||
}
|
||||
return $cors;
|
||||
}
|
||||
}
|
||||
class GetBucketLocationHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
$location = $xml->__toString();
|
||||
|
||||
return $location;
|
||||
}
|
||||
}
|
||||
class GetBucketLoggingHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$logging = array();
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
$loggingXml = $xml->LoggingEnabled;
|
||||
if($loggingXml&&$loggingXml!==NULL)
|
||||
{
|
||||
foreach ($loggingXml->children() as $key => $value) {
|
||||
$logging["Enable"] = TRUE;
|
||||
$logging[$key] = $value->__toString();
|
||||
}
|
||||
}else{
|
||||
$logging["Enable"] = FALSE;
|
||||
}
|
||||
return $logging;
|
||||
}
|
||||
}
|
||||
class ObjectMetaHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$ObjectMeta = array();
|
||||
$UserMeta = array();
|
||||
foreach ($response->header as $key => $value) {
|
||||
if (substr(strtolower($key), 0, 10) === Consts::$UserMetaPrefix){
|
||||
$UserMeta[$key]=$value;
|
||||
}else if(isset(Consts::$ResponseObjectMeta[strtolower($key)])){
|
||||
$ObjectMeta[Consts::$ResponseObjectMeta[strtolower($key)]]=$value;
|
||||
}
|
||||
}
|
||||
$Meta = array(
|
||||
"ObjectMeta"=>$ObjectMeta,
|
||||
"UserMeta"=>$UserMeta
|
||||
);
|
||||
return $Meta;
|
||||
}
|
||||
}
|
||||
class getObjectHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$ObjectMeta = array();
|
||||
$UserMeta = array();
|
||||
foreach ($response->header as $key => $value) {
|
||||
if (substr(strtolower($key), 0, 10) === Consts::$UserMetaPrefix){
|
||||
$UserMeta[$key]=$value;
|
||||
}else if(isset(Consts::$ResponseObjectMeta[strtolower($key)])){
|
||||
$ObjectMeta[Consts::$ResponseObjectMeta[strtolower($key)]]=$value;
|
||||
}
|
||||
}
|
||||
$Meta = array(
|
||||
"ObjectMeta"=>$ObjectMeta,
|
||||
"UserMeta"=>$UserMeta
|
||||
);
|
||||
$ks3Object = array(
|
||||
"Content"=>$response->body,
|
||||
"Meta"=>$Meta
|
||||
);
|
||||
return $ks3Object;
|
||||
}
|
||||
}
|
||||
class CopyHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$headers = array();
|
||||
|
||||
foreach ($response->header as $key => $value) {
|
||||
if(isset(Consts::$SSEHandler[strtolower($key)])&&!empty($value)){
|
||||
$headers[Consts::$SSEHandler[strtolower($key)]]=$value;
|
||||
}
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
class InitMultipartUploadHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$upload = array();
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
foreach ($xml->children() as $key => $value) {
|
||||
$upload[$key] = $value->__toString();
|
||||
}
|
||||
|
||||
foreach ($response->header as $key => $value) {
|
||||
if(isset(Consts::$SSEHandler[strtolower($key)])&&!empty($value)){
|
||||
$upload[Consts::$SSEHandler[strtolower($key)]]=$value;
|
||||
}
|
||||
}
|
||||
|
||||
return $upload;
|
||||
}
|
||||
}
|
||||
class ListPartsHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$listParts = array();
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
|
||||
$listParts["Bucket"]=$xml->Bucket->__toString();
|
||||
$listParts["Key"]=$xml->Key->__toString();
|
||||
$listParts["UploadId"]=$xml->UploadId->__toString();
|
||||
$listParts["StorageClass"]=$xml->StorageClass->__toString();
|
||||
$listParts["PartNumberMarker"]=$xml->PartNumberMarker->__toString();
|
||||
$listParts["NextPartNumberMarker"]=$xml->NextPartNumberMarker->__toString();
|
||||
$listParts["MaxParts"]=$xml->MaxParts->__toString();
|
||||
$listParts["IsTruncated"]=$xml->IsTruncated->__toString();
|
||||
|
||||
$initer = array();
|
||||
$owner = array();
|
||||
|
||||
foreach ($xml->Initiator->children() as $key => $value) {
|
||||
$initer[$key] = $value->__toString();
|
||||
}
|
||||
foreach ($xml->Owner->children() as $key => $value) {
|
||||
$owner[$key] = $value->__toString();
|
||||
}
|
||||
$listParts["Owner"] = $owner;
|
||||
$listParts["Initiator"]=$initer;
|
||||
|
||||
$parts = array();
|
||||
foreach ($xml->Part as $partxml) {
|
||||
$part = array();
|
||||
foreach ($partxml->children() as $key => $value) {
|
||||
$part[$key] = $value->__toString();
|
||||
}
|
||||
array_push($parts,$part);
|
||||
}
|
||||
$listParts["Parts"] = $parts;
|
||||
return $listParts;
|
||||
}
|
||||
}
|
||||
class UploadHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$Headers = array();
|
||||
foreach ($response->header as $key => $value) {
|
||||
if(isset(Consts::$UploadHandler[strtolower($key)])&&!empty($value)){
|
||||
$Headers[Consts::$UploadHandler[strtolower($key)]]=$value;
|
||||
}
|
||||
}
|
||||
return $Headers;
|
||||
}
|
||||
}
|
||||
class GetAclHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$hasread = FALSE;
|
||||
$haswrite = FALSE;
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
$acl = $xml->AccessControlList;
|
||||
foreach ($acl->children() as $grant) {
|
||||
$permission = $grant->Permission->__toString();
|
||||
$hasURI = FALSE;
|
||||
$grantee = $grant->Grantee;
|
||||
foreach ($grantee->children() as $key => $value) {
|
||||
if($key === "URI"&&$value->__toString() === Consts::$Grantee_Group_All){
|
||||
$hasURI = TRUE;
|
||||
}
|
||||
}
|
||||
if($hasURI){
|
||||
if($permission===Consts::$Permission_Read){
|
||||
$hasread = TRUE;
|
||||
}elseif($permission===Consts::$Permission_Write){
|
||||
$haswrite = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($hasread&&$haswrite){
|
||||
return "public-read-write";
|
||||
}else{
|
||||
if($hasread)
|
||||
return "public-read";
|
||||
else
|
||||
return "private";
|
||||
}
|
||||
}
|
||||
}
|
||||
class ListMutipartUploadsHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$mutiUploads = array();
|
||||
$xml = new SimpleXMLElement($response->body);
|
||||
|
||||
$mutiUploads["Bucket"]=$xml->Bucket->__toString();
|
||||
$mutiUploads["KeyMarker"]=$xml->KeyMarker->__toString();
|
||||
$mutiUploads["UploadIdMarker"]=$xml->UploadIdMarker->__toString();
|
||||
$mutiUploads["NextKeyMarker"]=$xml->NextKeyMarker->__toString();
|
||||
$mutiUploads["NextUploadIdMarker"]=$xml->NextUploadIdMarker->__toString();
|
||||
$mutiUploads["MaxUploads"]=$xml->MaxUploads->__toString();
|
||||
$mutiUploads["IsTruncated"]=$xml->IsTruncated->__toString();
|
||||
|
||||
|
||||
$uploads = array();
|
||||
foreach ($xml->Upload as $uploadxml) {
|
||||
$upload = array();
|
||||
foreach ($uploadxml->children() as $key => $value) {
|
||||
if($key === "Initiator"){
|
||||
$initer = array();
|
||||
foreach ($value->children() as $key1 => $value1) {
|
||||
$initer[$key1] = $value1->__toString();
|
||||
}
|
||||
$upload["Initiator"] = $initer;
|
||||
}elseif($key === "Owner"){
|
||||
$owner = array();
|
||||
foreach ($value->children() as $key1 => $value1) {
|
||||
$owner[$key1] = $value1->__toString();
|
||||
}
|
||||
$upload["Owner"] = $owner;
|
||||
}else{
|
||||
$upload[$key] = $value->__toString();
|
||||
}
|
||||
}
|
||||
array_push($uploads,$upload);
|
||||
}
|
||||
$mutiUploads["Uploads"] = $uploads;
|
||||
return $mutiUploads;
|
||||
}
|
||||
}
|
||||
class AdpHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
return $response->body;
|
||||
}
|
||||
}
|
||||
class BooleanHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
if($response->isOk()){
|
||||
return TRUE;
|
||||
}else{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
class ExistsHandler implements Handler{
|
||||
public function handle(ResponseCore $response){
|
||||
$status = $response->status;
|
||||
if($status === 404){
|
||||
return FALSE;
|
||||
}else{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
class Headers{
|
||||
static $Date = "Date";
|
||||
static $Authorization = "Authorization";
|
||||
static $ContentMd5 = "Content-MD5";
|
||||
static $ContentType = "Content-Type";
|
||||
static $ContentLength="Content-Length";
|
||||
static $Acl = "x-kss-acl";
|
||||
static $CopySource = "x-kss-copy-source";
|
||||
static $ETag = "ETag";
|
||||
static $TaskID = "TaskID";
|
||||
static $Range = "Range";
|
||||
static $AsynchronousProcessingList = "kss-async-process";
|
||||
static $NotifyURL = "kss-notifyurl";
|
||||
static $XKssCallbackUrl = "x-kss-callbackurl";
|
||||
static $XKssCallbackBody = "x-kss-callbackbody";
|
||||
static $UserAgent = "User-Agent";
|
||||
static $SSEAlgm = "x-kss-server-side-encryption";
|
||||
static $SSEKMSId = "x-kss-server-side-encryption-kss-kms-key-id";
|
||||
static $SSECAlgm = "x-kss-server-side-encryption-customer-algorithm";
|
||||
static $SSECKey = "x-kss-server-side-encryption-customer-key";
|
||||
static $SSECMD5 = "x-kss-server-side-encryption-customer-key-MD5";
|
||||
|
||||
static $SSECSourceAlgm = "x-kss-copy-source-server-side-encryption-customer-algorithm";
|
||||
static $SSECSourceKey = "x-kss-copy-source-server-side-encryption-customer-key";
|
||||
static $SSECSourceMD5 = "x-kss-copy-source-server-side-encryption-customer-key-MD5";
|
||||
|
||||
}
|
||||
?>
|
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."core".DIRECTORY_SEPARATOR."Utils.class.php";
|
||||
|
||||
class Ks3Request{
|
||||
private $bucket;
|
||||
private $key;
|
||||
private $queryParams=array();
|
||||
private $headers=array();
|
||||
private $subResource;
|
||||
private $method;
|
||||
private $endpoint;
|
||||
private $scheme;
|
||||
private $body;
|
||||
private $read_stream;
|
||||
private $seek_position;
|
||||
private $write_stream;
|
||||
|
||||
public function __set($property_name, $value){
|
||||
$this->$property_name=$value;
|
||||
}
|
||||
public function __get($property_name){
|
||||
if(isset($this->$property_name))
|
||||
{
|
||||
return($this->$property_name);
|
||||
}else
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
public function getHeader($key){
|
||||
if(isset($this->headers[$key])){
|
||||
return $this->headers[$key];
|
||||
}else{
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
public function addHeader($key,$value){
|
||||
$this->headers[$key] = $value;
|
||||
}
|
||||
|
||||
public function getQueryParams($key){
|
||||
if(isset($this->queryParams[$key])){
|
||||
return $this->queryParams[$key];
|
||||
}else{
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
public function addQueryParams($key,$value){
|
||||
$this->queryParams[$key] = $value;
|
||||
}
|
||||
public function toUrl($endpoint){
|
||||
$url = "";
|
||||
$bucket = $this->bucket;
|
||||
$key = $this->key;
|
||||
$subResource = $this->subResource;
|
||||
if(!empty($bucket)){
|
||||
if(KS3_API_VHOST){
|
||||
$url.=$bucket.".".$endpoint;
|
||||
}else{
|
||||
$url.=$endpoint."/".$bucket;
|
||||
}
|
||||
}else{
|
||||
$url.=$endpoint;
|
||||
}
|
||||
if(!empty($key)){
|
||||
$url.="/".Utils::encodeUrl($key);
|
||||
}
|
||||
$url = str_replace("//","/%2F", $url);
|
||||
$queryString = "";
|
||||
if(!empty($subResource)){
|
||||
$queryString.="&".$subResource;
|
||||
}
|
||||
foreach ($this->queryParams as $key => $value) {
|
||||
$queryString.="&".$key."=".rawurlencode($value);
|
||||
}
|
||||
$queryString = substr($queryString, 1);
|
||||
if(!empty($queryString)){
|
||||
$url.="?".$queryString;
|
||||
}
|
||||
$url = $this->scheme.$url;
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."exceptions".DIRECTORY_SEPARATOR."Exceptions.php";
|
||||
class Logger{
|
||||
function info($msg){
|
||||
$this->log("INFO",$msg);
|
||||
}
|
||||
function error($msg){
|
||||
$this->log("ERROR",$msg);
|
||||
}
|
||||
function warn($msg){
|
||||
$this->log("WARN",$msg);
|
||||
}
|
||||
function debug($msg){
|
||||
$this->log("DEBUG",$msg);
|
||||
}
|
||||
private function log($level,$msg){
|
||||
$date = gmdate('D, d M Y H:i:s \G\M\T');
|
||||
$log = $date." ".$level."\r\n".$msg."\r\n";
|
||||
if(defined('KS3_API_LOG_PATH') ){
|
||||
$log_path = KS3_API_LOG_PATH;
|
||||
if(empty($log_path)){
|
||||
$log_path = KS3_API_PATH.DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR;
|
||||
}
|
||||
}else{
|
||||
$log_path = KS3_API_PATH.DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
//检测日志目录是否存在
|
||||
if(!file_exists($log_path)){
|
||||
mkdir($log_path);
|
||||
}
|
||||
|
||||
$log_name = $log_path.'ks3_php_sdk_'.date('Y-m-d').'.log';
|
||||
|
||||
if(KS3_API_DISPLAY_LOG){
|
||||
echo $log;
|
||||
}
|
||||
|
||||
if(KS3_API_LOG){
|
||||
if(!error_log($log,3,$log_name)){
|
||||
throw new Ks3ClientException("write to log file error");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
class MessageHolder{
|
||||
public $msg;
|
||||
}
|
||||
?>
|
@ -0,0 +1,358 @@
|
||||
<?php
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR."EncryptionUtil.php";
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR."EncryptionCallBack.php";
|
||||
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."exceptions".DIRECTORY_SEPARATOR."Exceptions.php";
|
||||
interface EncryptionHandler{
|
||||
public function putObjectByContentSecurely($args=array());
|
||||
public function putObjectByFileSecurely($args=array());
|
||||
public function getObjectSecurely($args=array());
|
||||
public function initMultipartUploadSecurely($args=array());
|
||||
public function uploadPartSecurely($args=array());
|
||||
public function abortMultipartUploadSecurely($args=array());
|
||||
public function completeMultipartUploadSecurely($args=array());
|
||||
}
|
||||
class EncryptionEO implements EncryptionHandler{
|
||||
private $encryptionMaterials = NULL;
|
||||
private $ks3client = NULL;
|
||||
public function __construct($ks3client,$encryptionMaterials){
|
||||
$this->encryptionMaterials = $encryptionMaterials;
|
||||
$this->ks3client = $ks3client;
|
||||
}
|
||||
public function putObjectByContentSecurely($args=array()){
|
||||
$sek = EncryptionUtil::genereateOnceUsedKey();
|
||||
$encryptedSek = EncryptionUtil::encodeCek($this->encryptionMaterials,$sek);
|
||||
$content = $args["Content"];
|
||||
if(empty($content))
|
||||
throw new Ks3ClientException("please specifie Content in request args");
|
||||
$metaContentLength = EncryptionUtil::metaTextLength($args);
|
||||
$plainTextLength = strlen($content);
|
||||
if($metaContentLength > 0 && $metaContentLength < $plainTextLength){
|
||||
$plainTextLength = $metaContentLength;
|
||||
}
|
||||
if($plainTextLength > 0)
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-unencrypted-content-length"] = $plainTextLength;
|
||||
else
|
||||
throw new Ks3ClientException("unexpected content length ".$plainTextLength);
|
||||
|
||||
$content = substr($content, 0,$plainTextLength);
|
||||
|
||||
|
||||
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');
|
||||
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND);
|
||||
mcrypt_generic_init($td,$sek,$iv);
|
||||
//对content进行pkcs5填充
|
||||
$content = EncryptionUtil::PKCS5Padding($content,mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC));
|
||||
$encrypted = mcrypt_generic($td,$content);
|
||||
mcrypt_generic_deinit($td);
|
||||
|
||||
$args["ObjectMeta"]["Content-Length"] = strlen($encrypted);
|
||||
$args["Content"] = $encrypted;
|
||||
|
||||
$args = EncryptionUtil::updateContentMD5Header($args);
|
||||
|
||||
//TODO
|
||||
$matdesc = "{}";
|
||||
if(ENCRYPTPTION_STORAGE_MODE == "ObjectMetadata"){
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-key"] = base64_encode($encryptedSek);
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-iv"] = base64_encode($iv);
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-matdesc"] = $matdesc;
|
||||
}
|
||||
|
||||
$result = $this->ks3client->putObjectByContent($args);
|
||||
|
||||
if(ENCRYPTPTION_STORAGE_MODE == "InstructionFile"){
|
||||
$req = EncryptionUtil::createInstructionFile($args["Bucket"],$args["Key"],
|
||||
base64_encode($encryptedSek),base64_encode($iv),$matdesc);
|
||||
$this->ks3client->putObjectByContent($req);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
public function putObjectByFileSecurely($args=array()){
|
||||
$sek = EncryptionUtil::genereateOnceUsedKey();
|
||||
$encryptedSek = EncryptionUtil::encodeCek($this->encryptionMaterials,$sek);
|
||||
if(!isset($args["Content"])||!is_array($args["Content"])
|
||||
||!isset($args["Content"]["content"])
|
||||
||empty($args["Content"]["content"]))
|
||||
throw new Ks3ClientException("please specifie file content in request args");
|
||||
$content = $args["Content"];
|
||||
$plainTextLength = EncryptionUtil::plainTextLength($args);
|
||||
if($plainTextLength <= 0){
|
||||
throw new Ks3ClientException("get content length failed ,unexpected content length ".$plainTextLength);
|
||||
}
|
||||
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');
|
||||
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND);
|
||||
|
||||
$args = EncryptionUtil::updateContentMD5Header($args);
|
||||
$encryptedLength = EncryptionUtil::getPKCS5EncrypedLength($plainTextLength,mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC));
|
||||
|
||||
$args["ObjectMeta"]["Content-Length"] = $encryptedLength;
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-unencrypted-content-length"] = $plainTextLength;
|
||||
|
||||
$readCallBack = new AESCBCStreamReadCallBack();
|
||||
$readCallBack->iv = $iv;
|
||||
$readCallBack->cek = $sek;
|
||||
$readCallBack->contentLength = $plainTextLength;
|
||||
$args["readCallBack"] = $readCallBack;
|
||||
|
||||
//TODO
|
||||
$matdesc = "{}";
|
||||
if(ENCRYPTPTION_STORAGE_MODE == "ObjectMetadata"){
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-key"] = base64_encode($encryptedSek);
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-iv"] = base64_encode($iv);
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-matdesc"] = $matdesc;
|
||||
}
|
||||
|
||||
$result = $this->ks3client->putObjectByFile($args);
|
||||
|
||||
if(ENCRYPTPTION_STORAGE_MODE == "InstructionFile"){
|
||||
$req = EncryptionUtil::createInstructionFile($args["Bucket"],$args["Key"],
|
||||
base64_encode($encryptedSek),base64_encode($iv),$matdesc);
|
||||
$this->ks3client->putObjectByContent($req);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
public function getObjectSecurely($args=array()){
|
||||
$meta = $this->ks3client->getObjectMeta($args);
|
||||
if(isset($meta["UserMeta"]["x-kss-meta-x-kss-key"])&&isset($meta["UserMeta"]["x-kss-meta-x-kss-iv"])){
|
||||
$encryptedInMeta = TRUE;
|
||||
}else{
|
||||
$encryptedInMeta = FALSE;
|
||||
}
|
||||
$encrypted = TRUE;
|
||||
$encryptionInfo = array();
|
||||
if($encryptedInMeta){
|
||||
$encryptionInfo["iv"] = base64_decode($meta["UserMeta"]["x-kss-meta-x-kss-iv"]);
|
||||
$matdesc =$meta["UserMeta"]["x-kss-meta-x-kss-matdesc"];
|
||||
$encryptionInfo["matdesc"] = $matdesc;
|
||||
$cekEncrypted = base64_decode($meta["UserMeta"]["x-kss-meta-x-kss-key"]);
|
||||
$encryptionInfo["cek"] = $cek = EncryptionUtil::decodeCek($this->encryptionMaterials,$cekEncrypted);
|
||||
}else{
|
||||
if($this->ks3client->objectExists(array(
|
||||
"Bucket"=>$args["Bucket"],
|
||||
"Key"=>$args["Key"].EncryptionUtil::$INSTRUCTION_SUFFIX)
|
||||
)
|
||||
){
|
||||
$insKey = $args["Key"].EncryptionUtil::$INSTRUCTION_SUFFIX;
|
||||
$getIns = array(
|
||||
"Bucket"=>$args["Bucket"],
|
||||
"Key"=>$insKey,
|
||||
);
|
||||
$s3Object = $this->ks3client->getObject($getIns);
|
||||
if(!EncryptionUtil::isInstructionFile($s3Object))
|
||||
throw new Ks3ClientException($insKey." is not an InstructionFile");
|
||||
|
||||
$content = $s3Object["Content"];
|
||||
$content = json_decode($content,TRUE);
|
||||
$encryptionInfo["iv"] = base64_decode($content["x-kss-iv"]);
|
||||
$matdesc =$content["x-kss-matdesc"];
|
||||
$encryptionInfo["matdesc"] = $matdesc;
|
||||
$cekEncrypted = base64_decode($content["x-kss-key"]);
|
||||
$encryptionInfo["cek"] = $cek = EncryptionUtil::decodeCek($this->encryptionMaterials,$cekEncrypted);
|
||||
}else{
|
||||
$encrypted =FALSE;
|
||||
}
|
||||
}
|
||||
//是否为下载到文件中
|
||||
$isWriteToFile=FALSE;
|
||||
if($encrypted)
|
||||
{
|
||||
$iv = $encryptionInfo["iv"];
|
||||
$cek = $encryptionInfo["cek"];
|
||||
|
||||
if(empty($iv))
|
||||
throw new Ks3ClientException("can not find iv in UserMeta or InstructionFile");
|
||||
if(empty($cek))
|
||||
throw new Ks3ClientException("can not find cek in UserMeta or InstructionFile");
|
||||
|
||||
if(isset($args["Range"])){
|
||||
$range = $args["Range"];
|
||||
if(!is_array($range)){
|
||||
if(preg_match('/^bytes=[0-9]*-[0-9]*$/', $range)){
|
||||
$ranges = explode("-",substr($range,strlen("bytes=")));
|
||||
$a = $ranges[0];
|
||||
$b = $ranges[1];
|
||||
if($a > $b){
|
||||
throw new Ks3ClientException("Invalid range ".$range);
|
||||
}
|
||||
$range = array("start"=>$a,"end"=>$b);
|
||||
}else{
|
||||
throw new Ks3ClientException("Invalid range ".$range);
|
||||
}
|
||||
}else{
|
||||
if(!isset($range["start"])||!isset($range["end"])){
|
||||
throw new Ks3ClientException("Invalid range ".serialize($range));
|
||||
}
|
||||
if($range["start"] > $range["end"]){
|
||||
throw new Ks3ClientException("Invalid range ".serialize($range));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$isWriteToFile = isset($args["WriteTo"]);
|
||||
$contentLength = $meta["ObjectMeta"]["Content-Length"];
|
||||
if($isWriteToFile){
|
||||
$writeCallBack = new AESCBCStreamWriteCallBack();
|
||||
$writeCallBack->iv=$iv;
|
||||
$writeCallBack->cek=$cek;
|
||||
$writeCallBack->contentLength = $contentLength;
|
||||
if(isset($range)){
|
||||
$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC);
|
||||
$adjustedRange = EncryptionUtil::getAdjustedRange($range,$blocksize);
|
||||
$writeCallBack->expectedRange = $range;
|
||||
$writeCallBack->adjustedRange = $adjustedRange;
|
||||
$args["Range"]=$adjustedRange;
|
||||
}
|
||||
$args["writeCallBack"] = $writeCallBack;
|
||||
return $this->ks3client->getObject($args);
|
||||
}else{
|
||||
$offset = 0;
|
||||
$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC);
|
||||
if(isset($range)){
|
||||
$adjustedRange = EncryptionUtil::getAdjustedRange($range,$blocksize);
|
||||
$args["Range"]=$adjustedRange;
|
||||
}
|
||||
$s3Object = $this->ks3client->getObject($args);
|
||||
$content = $s3Object["Content"];
|
||||
|
||||
if(isset($range)){
|
||||
if($adjustedRange["start"] > 0){
|
||||
$iv = substr($content,0,$blocksize);
|
||||
$content = substr($content,$blocksize);
|
||||
$offset = $blocksize+$adjustedRange["start"];
|
||||
}
|
||||
}
|
||||
if(!empty($content)){
|
||||
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');
|
||||
mcrypt_generic_init($td,$cek,$iv);
|
||||
$decoded = mdecrypt_generic($td,$content);
|
||||
mcrypt_generic_deinit($td);
|
||||
mcrypt_module_close($td);
|
||||
}else{
|
||||
$decoded = "";
|
||||
}
|
||||
|
||||
//判断是否需要删除最后填充的字符,以及获取填充的字符
|
||||
$needRemovePad = FALSE;
|
||||
$pad = NULL;
|
||||
if($offset+strlen($decoded) >=$contentLength){
|
||||
$needRemovePad = TRUE;
|
||||
$pad = ord(substr($decoded,strlen($decoded)-1,1));
|
||||
if($pad<=0||$pad>$blocksize)
|
||||
{
|
||||
//invalid pad
|
||||
$needRemovePad = FALSE;
|
||||
}
|
||||
}
|
||||
$endOffset = 0;
|
||||
if(isset($range)){
|
||||
if($offset+strlen($decoded)>$range["end"]){
|
||||
$preLength = strlen($decoded);
|
||||
$decoded = substr($decoded, 0,$range["end"]-$offset+1);
|
||||
$endOffset = $preLength-strlen($decoded);
|
||||
}
|
||||
if($offset<$range["start"]){
|
||||
$decoded = substr($decoded,$range["start"] - $offset);
|
||||
}
|
||||
}
|
||||
//再次根据截取的长度判断是否需要删除最后填充的字符
|
||||
if($needRemovePad&&$endOffset > $pad){
|
||||
$needRemovePad = FALSE;
|
||||
}
|
||||
if($needRemovePad){
|
||||
$padOffset = $pad-$endOffset;
|
||||
$actualWriteCount = strlen($decoded)-$padOffset;
|
||||
if($actualWriteCount <= 0)//负数的情况就是用户期望的range里全是填充的
|
||||
$decoded = "";
|
||||
else
|
||||
$decoded = substr($decoded,0,strlen($decoded)-$padOffset);
|
||||
}
|
||||
$s3Object["Content"] = $decoded;
|
||||
return $s3Object;
|
||||
}
|
||||
}else{
|
||||
return $this->ks3client->getObject($args);
|
||||
}
|
||||
}
|
||||
public function initMultipartUploadSecurely($args=array()){
|
||||
$sek = EncryptionUtil::genereateOnceUsedKey();
|
||||
$encryptedSek = EncryptionUtil::encodeCek($this->encryptionMaterials,$sek);
|
||||
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'',MCRYPT_MODE_CBC,'');
|
||||
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND);
|
||||
|
||||
$matdesc = "{}";
|
||||
if(ENCRYPTPTION_STORAGE_MODE == "ObjectMetadata"){
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-key"] = base64_encode($encryptedSek);
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-iv"] = base64_encode($iv);
|
||||
$args["UserMeta"]["x-kss-meta-x-kss-matdesc"] = $matdesc;
|
||||
}
|
||||
|
||||
$initResult = $this->ks3client->initMultipartUpload($args);
|
||||
|
||||
EncryptionUtil::initMultipartUploadContext($initResult,$iv,$sek,$encryptedSek,$matdesc);
|
||||
|
||||
return $initResult;
|
||||
}
|
||||
public function uploadPartSecurely($args=array()){
|
||||
$uploadId = $args["Options"]["uploadId"];
|
||||
$isLastPart = FALSE;
|
||||
$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_CBC);
|
||||
if(isset($args["LastPart"]))
|
||||
$isLastPart = $args["LastPart"];
|
||||
$exists = EncryptionUtil::multipartUploadContextExists($uploadId);
|
||||
if(!$exists){
|
||||
throw new Ks3ClientException("no such upload in cache/encryption/");
|
||||
}
|
||||
$context = EncryptionUtil::getMultipartUploadContext($uploadId);
|
||||
if($context["lastPart"]){
|
||||
throw new Ks3ClientException("this upload with uploadId ".$uploadId," has been upload last part");
|
||||
}
|
||||
$plainTextLength = EncryptionUtil::plainTextLength($args);
|
||||
if($plainTextLength <= 0){
|
||||
throw new Ks3ClientException("get content length failed ,unexpected content length ".$plainTextLength);
|
||||
}
|
||||
if(!$isLastPart){
|
||||
if($plainTextLength % $blocksize != 0)
|
||||
throw new Ks3ClientException("Invalid part size,part size (".$plainTextLength.") must be multiples of the block size ".$blocksize);
|
||||
}else{
|
||||
$args["ObjectMeta"]["Content-Length"] = $plainTextLength + ($blocksize - $plainTextLength%$blocksize);
|
||||
}
|
||||
$readCallBack = new AESCBCStreamReadCallBack();
|
||||
$readCallBack->iv = base64_decode($context["nextIv"]);
|
||||
$readCallBack->cek = base64_decode($context["cek"]);
|
||||
$readCallBack->contentLength = $plainTextLength;
|
||||
$readCallBack->mutipartUpload = TRUE;
|
||||
$readCallBack->isLastPart = $isLastPart;
|
||||
$args["readCallBack"] = $readCallBack;
|
||||
|
||||
$upResult = $this->ks3client->uploadPart($args);
|
||||
EncryptionUtil::updateMultipartUploadContext($uploadId,$readCallBack->iv,$isLastPart);
|
||||
return $upResult;
|
||||
}
|
||||
public function abortMultipartUploadSecurely($args=array()){
|
||||
$uploadId = $args["Options"]["uploadId"];
|
||||
EncryptionUtil::deleteMultipartUploadContext($uploadId);
|
||||
return $this->ks3client->abortMultipartUpload($args);
|
||||
}
|
||||
public function completeMultipartUploadSecurely($args=array()){
|
||||
$uploadId = $args["Options"]["uploadId"];
|
||||
$exists = EncryptionUtil::multipartUploadContextExists($uploadId);
|
||||
if(!$exists){
|
||||
throw new Ks3ClientException("no such upload in cache/encryption/");
|
||||
}
|
||||
$context = EncryptionUtil::getMultipartUploadContext($uploadId);
|
||||
if(!$context["lastPart"]){
|
||||
throw new Ks3ClientException("Unable to complete an encrypted multipart upload without being told which part was the last. when upload part you can add item in args like args[\"LastPart\"]=TRUE");
|
||||
}
|
||||
$result = $this->ks3client->completeMultipartUpload($args);
|
||||
if(ENCRYPTPTION_STORAGE_MODE=="InstructionFile"){
|
||||
$req = EncryptionUtil::createInstructionFile($args["Bucket"],$args["Key"],
|
||||
$context["encryptedCek"],$context["firstIv"],$context["matdesc"]);
|
||||
$this->ks3client->putObjectByContent($req);
|
||||
}
|
||||
EncryptionUtil::deleteMultipartUploadContext($uploadId);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
class Ks3ClientException extends RuntimeException{
|
||||
|
||||
}
|
||||
class Ks3ServiceException extends Ks3ClientException{
|
||||
private $requestId;
|
||||
private $errorCode;
|
||||
private $errorMessage;
|
||||
private $resource;
|
||||
private $statusCode;
|
||||
public function __set($property_name, $value){
|
||||
$this->$property_name=$value;
|
||||
}
|
||||
public function __get($property_name){
|
||||
if(isset($this->$property_name))
|
||||
{
|
||||
return($this->$property_name);
|
||||
}else
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
public function __toString()
|
||||
{
|
||||
$message = get_class($this) . ': '
|
||||
."(errorCode:".$this->errorCode.";"
|
||||
."errorMessage:".$this->errorMessage.";"
|
||||
."resource:".$this->resource.";"
|
||||
."requestId:".$this->requestId.";"
|
||||
."statusCode:".$this->statusCode.")";
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
//更加详细的表单上传请参考js sdk
|
||||
require_once "../Ks3Client.class.php";
|
||||
|
||||
$client = new Ks3Client("","");
|
||||
$bucket_name = "phpsdktestlijunwei";
|
||||
if(!$client->bucketExists(array("Bucket"=>$bucket_name))){
|
||||
$client->createBucket(array("Bucket"=>$bucket_name));
|
||||
}
|
||||
|
||||
|
||||
$key = 'formuploadtest/@中文.txt';
|
||||
$host = "kss.ksyun.com";
|
||||
$host_uri = "http://".$host."/".$bucket_name;
|
||||
$redirect = $host_uri;
|
||||
|
||||
//将所有能确定值的表单项都放在该数组中
|
||||
$postData = array(
|
||||
"key"=>$key,
|
||||
"success_action_redirect"=>$redirect,
|
||||
"Content-Type"=>"text/html",
|
||||
);
|
||||
//将不能确定值的表单项都放在该数组中
|
||||
$unknowData = array(
|
||||
"random"
|
||||
);
|
||||
$result = $client->postObject($bucket_name,$postData,$unknowData);
|
||||
print_r($result);
|
||||
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<form action="<?php echo $host_uri;?>" method="post" enctype="multipart/form-data">
|
||||
Key to upload: <input type="input" name="key" value="<?php echo $key;?>" /><br />
|
||||
<input type="hidden" name="success_action_redirect" value="<?php echo $redirect;?>" />
|
||||
<input type="hidden" name="Content-Type" value="text/html" />
|
||||
<input type="hidden" name="random" value="vfegf34egf3" />
|
||||
<input type="hidden" name="KSSAccessKeyId" value="<?php echo $result["KSSAccessKeyId"];?>" />
|
||||
<input type="hidden" name="Policy" value="<?php echo $result["Policy"];?>" />
|
||||
<input type="hidden" name="Signature" value="<?php echo $result["Signature"];?>" />
|
||||
File: <input type="file" name="file" /> <br />
|
||||
<!-- The elements after this will be ignored -->
|
||||
<input type="submit" name="submit" value="Upload to KSS S3" />
|
||||
</form>
|
||||
</html>
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
require_once "../core/Logger.php";
|
||||
class PUnit{
|
||||
function assertEquals($value,$expected,$info = NULL){
|
||||
if($value != $expected){
|
||||
throw new Exception($info." expected ".$expected." but ".$value);
|
||||
}
|
||||
}
|
||||
function run($torun = NULL){
|
||||
$r = new ReflectionClass($this);
|
||||
foreach($r->getMethods() as $key=>$methodObj){
|
||||
if($methodObj->isPrivate())
|
||||
$methods[$key]['type'] = 'private';
|
||||
elseif($methodObj->isProtected())
|
||||
$methods[$key]['type'] = 'protected';
|
||||
else
|
||||
$methods[$key]['type'] = 'public';
|
||||
$methods[$key]['name'] = $methodObj->name;
|
||||
$methods[$key]['class'] = $methodObj->class;
|
||||
}
|
||||
$before = NULL;
|
||||
$after = NULL;
|
||||
foreach ($methods as $method) {
|
||||
if($method["class"] != "PUnit"&&$method["name"] == "before"){
|
||||
$before = $method;
|
||||
}
|
||||
if($method["class"] != "PUnit"&&$method["name"] == "after"){
|
||||
$after = $method;
|
||||
}
|
||||
}
|
||||
$error = array();
|
||||
$success = array();
|
||||
foreach ($methods as $method) {
|
||||
if($method["class"] != "PUnit"&&substr($method["name"],0,4) == "test"){
|
||||
if($torun !== NULL){
|
||||
if(!in_array($method["name"],$torun))
|
||||
continue;
|
||||
}
|
||||
try{
|
||||
if($method["type"] == "public"){
|
||||
$log = new Logger();
|
||||
$log->info("Run unit --->".$method["name"]);
|
||||
if($before!=NULL)
|
||||
$this->$before["name"]();
|
||||
$this->$method["name"]();
|
||||
array_push($success,$method["name"]);
|
||||
}
|
||||
}catch(Exception $e){
|
||||
$error[$method["name"]]="".$e;
|
||||
}
|
||||
}
|
||||
}
|
||||
echo "\r\nPHP Unit-----------error"."\r\n";
|
||||
print_r($error);
|
||||
echo "PHP Unit-----------result"."\r\n";
|
||||
echo "total:".(count($success)+count($error)).",success:".count($success).",error:".count($error)."\r\n";
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
function rangeGetAndCheckMd5($client,$bucket,$key,$file,$expectedMd5){
|
||||
$args = array("Bucket"=>$bucket,"Key"=>$key);
|
||||
$meta = $client->getObjectMeta($args);
|
||||
$contentlength = $meta["ObjectMeta"]["Content-Length"];
|
||||
|
||||
$filelist = array();
|
||||
|
||||
for($begin = 0;$begin <$contentlength;){
|
||||
$index = rand((int)($contentlength/20),(int)($contentlength/4));
|
||||
$range = array("start"=>$begin,"end"=>$begin+$index);
|
||||
$destFile = $file.$begin."-".($begin+$index);
|
||||
array_push($filelist,$destFile);
|
||||
$begin += ($index+1);
|
||||
$args = array(
|
||||
"Bucket"=>$bucket,
|
||||
"Key"=>$key,
|
||||
"Range"=>$range,
|
||||
"WriteTo"=>$destFile
|
||||
);
|
||||
$client->getObject($args);
|
||||
}
|
||||
|
||||
foreach ($filelist as $key => $value) {
|
||||
$handle = fopen($value,"r");
|
||||
$size = filesize($value);
|
||||
if($size > 0){
|
||||
$content = fread($handle,$size);
|
||||
file_put_contents($file,$content,FILE_APPEND);
|
||||
}
|
||||
fclose($handle);
|
||||
//@unlink($value);
|
||||
}
|
||||
$md5 = md5_file($file);
|
||||
//@unlink($file);
|
||||
if($md5 != $expectedMd5)
|
||||
throw new Exception("file md5 check error expected ".$expectedMd5." ,actual ".$md5, 1);
|
||||
foreach ($filelist as $key => $value) {
|
||||
@unlink($value);
|
||||
}
|
||||
@unlink($file);
|
||||
}
|
||||
function generateFile($sizeInBytes,$destFile){
|
||||
for($i = 0;$i < $sizeInBytes/10;$i++){
|
||||
$randpwd = "";
|
||||
for ($j = 0; $j < 10; $j++)
|
||||
{
|
||||
$randpwd .= chr(mt_rand(33, 126));
|
||||
}
|
||||
file_put_contents($destFile,$randpwd,FILE_APPEND);
|
||||
}
|
||||
}
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,18 @@
|
||||
===========================
|
||||
===Version 1.0.0===
|
||||
* 支持普通上传
|
||||
* 支持表单上传
|
||||
* 支持分片上传
|
||||
* 支持删除文件
|
||||
* 支持秒传文件
|
||||
|
||||
===Version 1.0.1===
|
||||
* 强化 MimeType 检测功能
|
||||
* bugfix
|
||||
|
||||
===Version 1.0.5===
|
||||
2015.10.19
|
||||
* fix digest bug
|
||||
=== Version 1.0.6 ===
|
||||
* 新增append 接口
|
||||
* 上传key 去掉转义,保留原有格式
|
@ -0,0 +1,16 @@
|
||||
ucloud/conf.php 为配置文件,按需填写:
|
||||
|
||||
- $UCLOUD_PROXY_SUFFIX = '.cn-bj.ufileos.com';
|
||||
- $UCLOUD_PUBLIC_KEY = 'paste your public key here';
|
||||
- $UCLOUD_PRIVATE_KEY = 'paste your private key here';
|
||||
|
||||
|
||||
Demo 目录中,包含各个接口的使用例子:
|
||||
- append.php
|
||||
- delete.php
|
||||
- get.php
|
||||
- multipart.php
|
||||
- mupload.php
|
||||
- put.php
|
||||
- listobjects.php
|
||||
- uploadhit.php
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
require_once("../ucloud/proxy.php");
|
||||
|
||||
//存储空间名
|
||||
$bucket = "your bucket";
|
||||
//上传至存储空间后的文件名称(请不要和API公私钥混淆)
|
||||
$key = "your key";
|
||||
//待上传文件的本地路径
|
||||
$file = "local file path";
|
||||
//当前append 的文件已有的大小, 新建填0
|
||||
$position = 0;
|
||||
|
||||
//该接口适用于0-10MB小文件,更大的文件建议使用分片上传接口
|
||||
list($data, $err) = UCloud_AppendFile($bucket, $key, $file, $position);
|
||||
if ($err) {
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
echo "ETag: " . $data['ETag'] . "\n";
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
require_once("../ucloud/proxy.php");
|
||||
|
||||
//存储空间名
|
||||
$bucket = "your bucket";
|
||||
//上传至存储空间后的文件名称(请不要和API公私钥混淆)
|
||||
$key = "your key";
|
||||
|
||||
list($data, $err) = UCloud_Delete($bucket, $key);
|
||||
if ($err) {
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
echo "delete $bucket/$key success\n";
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
require_once("../ucloud/proxy.php");
|
||||
|
||||
//存储空间名
|
||||
$bucket = "your bucket";
|
||||
//上传至存储空间后的文件名称(请不要和API公私钥混淆)
|
||||
$key = "your key";
|
||||
|
||||
function curl_file_get_contents($durl){
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $durl);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
|
||||
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
|
||||
$r = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $r;
|
||||
}
|
||||
|
||||
/*
|
||||
* 访问公有Bucket的例子
|
||||
*/
|
||||
$url = UCloud_MakePublicUrl($bucket, $key);
|
||||
echo "download url(public): ", $url . "\n";
|
||||
|
||||
/*
|
||||
* 访问私有Bucket的例子
|
||||
*/
|
||||
$url = UCloud_MakePrivateUrl($bucket, $key);
|
||||
echo "download url(private): ", $url . "\n";
|
||||
|
||||
/*
|
||||
* 访问包含过期时间的私有Bucket例子
|
||||
*/
|
||||
$curtime = time();
|
||||
$curtime += 60; // 有效期60秒
|
||||
$url = UCloud_MakePrivateUrl($bucket, $key, $curtime);
|
||||
$content = curl_file_get_contents($url);
|
||||
echo "download file with expires: ", $url . "\n";
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
require_once("../ucloud/conf.php");
|
||||
require_once("../ucloud/http.php");
|
||||
require_once("../ucloud/proxy.php");
|
||||
|
||||
//存储空间名
|
||||
$bucket = "your bucket";
|
||||
//上传至存储空间后的文件名称(请不要和API公私钥混淆)
|
||||
$key = "your key";
|
||||
//待上传文件的本地路径
|
||||
$file = "local file path";
|
||||
|
||||
//该接口适用于web的POST表单上传,本SDK为了完整性故带上该接口demo.
|
||||
//服务端上传建议使用分片上传接口,而非POST表单
|
||||
list($data, $err) = UCloud_MultipartForm($bucket, $key, $file);
|
||||
if ($err) {
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
echo "ETag: " . $data['ETag'] . "\n";
|
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
require_once('../ucloud/proxy.php');
|
||||
|
||||
//存储空间名
|
||||
$bucket = 'your bucket';
|
||||
//上传至存储空间后的文件名称(请不要和API公私钥混淆)
|
||||
$key = 'your key';
|
||||
//待上传文件的本地路径
|
||||
$file = 'local file path';
|
||||
|
||||
//初始化分片上传,获取本地上传的uploadId和分片大小
|
||||
list($data, $err) = UCloud_MInit($bucket, $key);
|
||||
if ($err)
|
||||
{
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$uploadId = $data['UploadId'];
|
||||
$blkSize = $data['BlkSize'];
|
||||
echo "UploadId: " . $uploadId . "\n";
|
||||
echo "BlkSize: " . $blkSize . "\n";
|
||||
|
||||
//数据上传
|
||||
list($etagList, $err) = UCloud_MUpload($bucket, $key, $file, $uploadId, $blkSize);
|
||||
if ($err) {
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
//完成上传
|
||||
list($data, $err) = UCloud_MFinish($bucket, $key, $uploadId, $etagList);
|
||||
if ($err) {
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
echo "Etag: " . $data['ETag'] . "\n";
|
||||
echo "FileSize: " . $data['FileSize'] . "\n";
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
require_once("../ucloud/proxy.php");
|
||||
|
||||
//存储空间名
|
||||
$bucket = "your bucket";
|
||||
//上传至存储空间后的文件名称(请不要和API公私钥混淆)
|
||||
$key = "your key";
|
||||
//待上传文件的本地路径
|
||||
$file = "local file path";
|
||||
|
||||
//该接口适用于0-10MB小文件,更大的文件建议使用分片上传接口
|
||||
list($data, $err) = UCloud_PutFile($bucket, $key, $file);
|
||||
if ($err) {
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
echo "ETag: " . $data['ETag'] . "\n";
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
require_once('../ucloud/proxy.php');
|
||||
|
||||
//存储空间
|
||||
$bucket = 'your bucket';
|
||||
//上传至存储空间后的文件名称(请不要和API公私钥混淆)
|
||||
$key = 'your key';
|
||||
//待秒传的本地文件路径
|
||||
$file = 'local file path';
|
||||
|
||||
//该接口不是上传接口.如果秒传返回非200错误码,意味着该文件在服务器不存在
|
||||
//需要继续调用其他上传接口完成上传操作
|
||||
list($data, $err) = UCloud_UploadHit($bucket, $key, $file);
|
||||
if ($err) {
|
||||
echo "error: " . $err->ErrMsg . "\n";
|
||||
echo "code: " . $err->Code . "\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
echo "upload hit success\n";
|
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
require_once("utils.php");
|
||||
require_once("conf.php");
|
||||
|
||||
define("NO_AUTH_CHECK", 0);
|
||||
define("HEAD_FIELD_CHECK", 1);
|
||||
define("QUERY_STRING_CHECK", 2);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
function CanonicalizedResource($bucket, $key)
|
||||
{
|
||||
return "/" . $bucket . "/" . $key;
|
||||
}
|
||||
|
||||
function CanonicalizedUCloudHeaders($headers)
|
||||
{
|
||||
|
||||
$keys = array();
|
||||
foreach($headers as $header) {
|
||||
$header = trim($header);
|
||||
$arr = explode(':', $header);
|
||||
if (count($arr) < 2) continue;
|
||||
list($k, $v) = $arr;
|
||||
$k = strtolower($k);
|
||||
if (strncasecmp($k, "x-ucloud") === 0) {
|
||||
$keys[] = $k;
|
||||
}
|
||||
}
|
||||
|
||||
$c = '';
|
||||
sort($keys, SORT_STRING);
|
||||
foreach($keys as $k) {
|
||||
$c .= $k . ":" . trim($headers[$v], " ") . "\n";
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
class UCloud_Auth {
|
||||
|
||||
public $PublicKey;
|
||||
public $PrivateKey;
|
||||
|
||||
public function __construct($publicKey, $privateKey)
|
||||
{
|
||||
$this->PublicKey = $publicKey;
|
||||
$this->PrivateKey = $privateKey;
|
||||
}
|
||||
|
||||
public function Sign($data)
|
||||
{
|
||||
$sign = base64_encode(hash_hmac('sha1', $data, $this->PrivateKey, true));
|
||||
return "UCloud " . $this->PublicKey . ":" . $sign;
|
||||
}
|
||||
|
||||
//@results: $token
|
||||
public function SignRequest($req, $mimetype = null, $type = HEAD_FIELD_CHECK)
|
||||
{
|
||||
$url = $req->URL;
|
||||
$url = parse_url($url['path']);
|
||||
$data = '';
|
||||
$data .= strtoupper($req->METHOD) . "\n";
|
||||
$data .= UCloud_Header_Get($req->Header, 'Content-MD5') . "\n";
|
||||
if ($mimetype)
|
||||
$data .= $mimetype . "\n";
|
||||
else
|
||||
$data .= UCloud_Header_Get($req->Header, 'Content-Type') . "\n";
|
||||
if ($type === HEAD_FIELD_CHECK)
|
||||
$data .= UCloud_Header_Get($req->Header, 'Date') . "\n";
|
||||
else
|
||||
$data .= UCloud_Header_Get($req->Header, 'Expires') . "\n";
|
||||
$data .= CanonicalizedUCloudHeaders($req->Header);
|
||||
$data .= CanonicalizedResource($req->Bucket, $req->Key);
|
||||
return $this->Sign($data);
|
||||
}
|
||||
}
|
||||
|
||||
function UCloud_MakeAuth($auth)
|
||||
{
|
||||
if (isset($auth)) {
|
||||
return $auth;
|
||||
}
|
||||
|
||||
global $UCLOUD_PUBLIC_KEY;
|
||||
global $UCLOUD_PRIVATE_KEY;
|
||||
|
||||
return new UCloud_Auth($UCLOUD_PUBLIC_KEY, $UCLOUD_PRIVATE_KEY);
|
||||
}
|
||||
|
||||
//@results: token
|
||||
function UCloud_SignRequest($auth, $req, $type = HEAD_FIELD_CHECK)
|
||||
{
|
||||
return UCloud_MakeAuth($auth)->SignRequest($req, $type);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
|
@ -0,0 +1,373 @@
|
||||
<?php
|
||||
|
||||
require_once("conf.php");
|
||||
require_once("utils.php");
|
||||
require_once("digest.php");
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
class HTTP_Request
|
||||
{
|
||||
public $URL;
|
||||
public $RawQuerys;
|
||||
public $Header;
|
||||
public $Body;
|
||||
public $UA;
|
||||
public $METHOD;
|
||||
public $Params; //map
|
||||
public $Bucket;
|
||||
public $Key;
|
||||
public $Timeout;
|
||||
|
||||
public function __construct($method, $url, $body, $bucket, $key, $action_type = ActionType::NONE)
|
||||
{
|
||||
$this->URL = $url;
|
||||
if (isset($url["query"])) {
|
||||
$this->RawQuerys = $url["query"];
|
||||
}
|
||||
$this->Header = array();
|
||||
$this->Body = $body;
|
||||
$this->UA = UCloud_UserAgent();
|
||||
$this->METHOD = $method;
|
||||
$this->Bucket = $bucket;
|
||||
$this->Key = $key;
|
||||
|
||||
global $CURL_TIMEOUT;
|
||||
global $UFILE_ACTION_TYPE;
|
||||
if ($CURL_TIMEOUT == null && $action_type !== ActionType::PUTFILE
|
||||
&& $action_type !== ActionType::POSTFILE) {
|
||||
$CURL_TIMEOUT = 10;
|
||||
}
|
||||
$this->Timeout = $CURL_TIMEOUT;
|
||||
}
|
||||
|
||||
public function EncodedQuery() {
|
||||
if ($this->RawQuerys != null) {
|
||||
$q = "";
|
||||
foreach ($this->RawQuerys as $k => $v) {
|
||||
$q = $q . "&" . rawurlencode($k) . "=" . rawurlencode($v);
|
||||
}
|
||||
return $q;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class HTTP_Response
|
||||
{
|
||||
public $StatusCode;
|
||||
public $Header;
|
||||
public $ContentLength;
|
||||
public $Body;
|
||||
public $Timeout;
|
||||
|
||||
public function __construct($code, $body)
|
||||
{
|
||||
$this->StatusCode = $code;
|
||||
$this->Header = array();
|
||||
$this->Body = $body;
|
||||
$this->ContentLength = strlen($body);
|
||||
|
||||
global $CURL_TIMEOUT;
|
||||
if ($CURL_TIMEOUT == null) {
|
||||
$CURL_TIMEOUT = 10;
|
||||
}
|
||||
$this->Timeout = $CURL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
//@results: $val
|
||||
function UCloud_Header_Get($header, $key)
|
||||
{
|
||||
$val = @$header[$key];
|
||||
if (isset($val)) {
|
||||
if (is_array($val)) {
|
||||
return $val[0];
|
||||
}
|
||||
return $val;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
//@results: $error
|
||||
function UCloud_ResponseError($resp)
|
||||
{
|
||||
$header = $resp->Header;
|
||||
$err = new UCloud_Error($resp->StatusCode, null);
|
||||
|
||||
if ($err->Code > 299) {
|
||||
if ($resp->ContentLength !== 0) {
|
||||
if (UCloud_Header_Get($header, 'Content-Type') === 'application/json') {
|
||||
$ret = json_decode($resp->Body, true);
|
||||
$err->ErrRet = $ret['ErrRet'];
|
||||
$err->ErrMsg = $ret['ErrMsg'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$err->Reqid = UCloud_Header_Get($header, 'X-SessionId');
|
||||
return $err;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
//@results: ($resp, $error)
|
||||
function UCloud_Client_Do($req)
|
||||
{
|
||||
$ch = curl_init();
|
||||
$url = $req->URL;
|
||||
|
||||
$options = array(
|
||||
CURLOPT_USERAGENT => $req->UA,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_NOBODY => false,
|
||||
CURLOPT_CUSTOMREQUEST => $req->METHOD,
|
||||
//CURLOPT_URL => $url['host'] . "/" . rawurlencode($url['path']) . "?" . $req->EncodedQuery(),
|
||||
CURLOPT_TIMEOUT => $req->Timeout,
|
||||
CURLOPT_CONNECTTIMEOUT => $req->Timeout
|
||||
);
|
||||
|
||||
if($req->EncodedQuery() !== ""){
|
||||
$options[CURLOPT_URL] = $url['host'] . "/" . $url['path'] . "?" . $req->EncodedQuery();
|
||||
}else{
|
||||
$options[CURLOPT_URL] = $url['host'] . "/" . $url['path'];
|
||||
}
|
||||
|
||||
$httpHeader = $req->Header;
|
||||
if (!empty($httpHeader))
|
||||
{
|
||||
$header = array();
|
||||
foreach($httpHeader as $key => $parsedUrlValue) {
|
||||
$header[] = "$key: $parsedUrlValue";
|
||||
}
|
||||
$options[CURLOPT_HTTPHEADER] = $header;
|
||||
}
|
||||
$body = $req->Body;
|
||||
if (!empty($body)) {
|
||||
$options[CURLOPT_POSTFIELDS] = $body;
|
||||
} else {
|
||||
$options[CURLOPT_POSTFIELDS] = "";
|
||||
}
|
||||
curl_setopt_array($ch, $options);
|
||||
$result = curl_exec($ch);
|
||||
$ret = curl_errno($ch);
|
||||
if ($ret !== 0) {
|
||||
$err = new UCloud_Error(0, $ret, curl_error($ch));
|
||||
curl_close($ch);
|
||||
return array(null, $err);
|
||||
}
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||
curl_close($ch);
|
||||
|
||||
$responseArray = explode("\r\n\r\n", $result);
|
||||
$responseArraySize = sizeof($responseArray);
|
||||
$headerString = $responseArray[$responseArraySize-2];
|
||||
$respBody = $responseArray[$responseArraySize-1];
|
||||
|
||||
$headers = parseHeaders($headerString);
|
||||
$resp = new HTTP_Response($code, $respBody);
|
||||
$resp->Header = $headers;
|
||||
$err = null;
|
||||
if (floor($resp->StatusCode/100) != 2) {
|
||||
list($r, $m) = parseError($respBody);
|
||||
$err = new UCloud_Error($resp->StatusCode, $r, $m);
|
||||
}
|
||||
return array($resp, $err);
|
||||
}
|
||||
|
||||
function parseError($bodyString) {
|
||||
|
||||
$r = 0;
|
||||
$m = '';
|
||||
$mp = json_decode($bodyString);
|
||||
if (isset($mp->{'ErrRet'})) $r = $mp->{'ErrRet'};
|
||||
if (isset($mp->{'ErrMsg'})) $m = $mp->{'ErrMsg'};
|
||||
return array($r, $m);
|
||||
}
|
||||
|
||||
function parseHeaders($headerString) {
|
||||
|
||||
$headers = explode("\r\n", $headerString);
|
||||
foreach($headers as $header) {
|
||||
if (strstr($header, ":")) {
|
||||
$header = trim($header);
|
||||
list($k, $v) = explode(":", $header);
|
||||
$headers[$k] = trim($v);
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
class UCloud_HttpClient
|
||||
{
|
||||
//@results: ($resp, $error)
|
||||
public function RoundTrip($req)
|
||||
{
|
||||
return UCloud_Client_Do($req);
|
||||
}
|
||||
}
|
||||
|
||||
class UCloud_AuthHttpClient
|
||||
{
|
||||
public $Auth;
|
||||
public $Type;
|
||||
public $MimeType;
|
||||
|
||||
public function __construct($auth, $mimetype = null, $type = HEAD_FIELD_CHECK)
|
||||
{
|
||||
$this->Type = $type;
|
||||
$this->MimeType = $mimetype;
|
||||
$this->Auth = UCloud_MakeAuth($auth, $type);
|
||||
}
|
||||
|
||||
//@results: ($resp, $error)
|
||||
public function RoundTrip($req)
|
||||
{
|
||||
if ($this->Type === HEAD_FIELD_CHECK) {
|
||||
$token = $this->Auth->SignRequest($req, $this->MimeType, $this->Type);
|
||||
$req->Header['Authorization'] = $token;
|
||||
}
|
||||
return UCloud_Client_Do($req);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
//@results: ($data, $error)
|
||||
function UCloud_Client_Ret($resp)
|
||||
{
|
||||
$code = $resp->StatusCode;
|
||||
$data = null;
|
||||
if ($code >= 200 && $code <= 299) {
|
||||
if ($resp->ContentLength !== 0 && UCloud_Header_Get($resp->Header, 'Content-Type') == 'application/json') {
|
||||
$data = json_decode($resp->Body, true);
|
||||
if ($data === null) {
|
||||
$err = new UCloud_Error($code, 0, "");
|
||||
return array(null, $err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$etag = UCloud_Header_Get($resp->Header, 'ETag');
|
||||
if ($etag != ''){
|
||||
$data['ETag'] = $etag;
|
||||
}else{
|
||||
$data['ETag'] = UCloud_Header_Get($resp->Header, 'Etag');
|
||||
}
|
||||
if (floor($code/100) == 2) {
|
||||
return array($data, null);
|
||||
}
|
||||
return array($data, UCloud_ResponseError($resp));
|
||||
}
|
||||
|
||||
//@results: ($data, $error)
|
||||
function UCloud_Client_Call($self, $req, $type = HEAD_FIELD_CHECK)
|
||||
{
|
||||
list($resp, $err) = $self->RoundTrip($req, $type);
|
||||
if ($err !== null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
return UCloud_Client_Ret($resp);
|
||||
}
|
||||
|
||||
//@results: $error
|
||||
function UCloud_Client_CallNoRet($self, $req, $type = HEAD_FIELD_CHECK)
|
||||
{
|
||||
list($resp, $err) = $self->RoundTrip($req, $type);
|
||||
if ($err !== null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
if (floor($resp->StatusCode/100) == 2) {
|
||||
return null;
|
||||
}
|
||||
return UCloud_ResponseError($resp);
|
||||
}
|
||||
|
||||
//@results: ($data, $error)
|
||||
function UCloud_Client_CallWithForm(
|
||||
$self, $req, $body, $contentType = 'application/x-www-form-urlencoded')
|
||||
{
|
||||
if ($contentType === 'application/x-www-form-urlencoded') {
|
||||
if (is_array($req->Params)) {
|
||||
$body = http_build_query($req->Params);
|
||||
}
|
||||
}
|
||||
if ($contentType !== 'multipart/form-data') {
|
||||
$req->Header['Content-Type'] = $contentType;
|
||||
}
|
||||
$req->Body = $body;
|
||||
list($resp, $err) = $self->RoundTrip($req, HEAD_FIELD_CHECK);
|
||||
if ($err !== null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
return UCloud_Client_Ret($resp);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
function UCloud_Client_CallWithMultipartForm($self, $req, $fields, $files)
|
||||
{
|
||||
list($contentType, $body) = UCloud_Build_MultipartForm($fields, $files);
|
||||
return UCloud_Client_CallWithForm($self, $req, $body, $contentType);
|
||||
}
|
||||
|
||||
//@results: ($contentType, $body)
|
||||
function UCloud_Build_MultipartForm($fields, $files)
|
||||
{
|
||||
$data = array();
|
||||
$boundary = md5(microtime());
|
||||
|
||||
foreach ($fields as $name => $val) {
|
||||
array_push($data, '--' . $boundary);
|
||||
array_push($data, "Content-Disposition: form-data; name=\"$name\"");
|
||||
array_push($data, '');
|
||||
array_push($data, $val);
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
array_push($data, '--' . $boundary);
|
||||
list($name, $fileName, $fileBody, $mimeType) = $file;
|
||||
$mimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType;
|
||||
$fileName = UCloud_EscapeQuotes($fileName);
|
||||
array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$fileName\"");
|
||||
array_push($data, "Content-Type: $mimeType");
|
||||
array_push($data, '');
|
||||
array_push($data, $fileBody);
|
||||
}
|
||||
|
||||
array_push($data, '--' . $boundary . '--');
|
||||
array_push($data, '');
|
||||
|
||||
$body = implode("\r\n", $data);
|
||||
$contentType = 'multipart/form-data; boundary=' . $boundary;
|
||||
return array($contentType, $body);
|
||||
}
|
||||
|
||||
function UCloud_UserAgent() {
|
||||
global $SDK_VER;
|
||||
$sdkInfo = "UCloudPHP/$SDK_VER";
|
||||
|
||||
$systemInfo = php_uname("s");
|
||||
$machineInfo = php_uname("m");
|
||||
|
||||
$envInfo = "($systemInfo/$machineInfo)";
|
||||
|
||||
$phpVer = phpversion();
|
||||
|
||||
$ua = "$sdkInfo $envInfo PHP/$phpVer";
|
||||
return $ua;
|
||||
}
|
||||
|
||||
function UCloud_EscapeQuotes($str)
|
||||
{
|
||||
$find = array("\\", "\"");
|
||||
$replace = array("\\\\", "\\\"");
|
||||
return str_replace($find, $replace, $str);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
@ -0,0 +1,449 @@
|
||||
<?php
|
||||
|
||||
global $mimetype_complete_map;
|
||||
$mimetype_complete_map = array(
|
||||
".3dm" => "x-world/x-3dmf",
|
||||
".3dmf" => "x-world/x-3dmf",
|
||||
".a" => "application/octet-stream",
|
||||
".aab" => "application/x-authorware-bin",
|
||||
".aam" => "application/x-authorware-map",
|
||||
".aas" => "application/x-authorware-seg",
|
||||
".abc" => "text/vnd.abc",
|
||||
".acgi" => "text/html",
|
||||
".afl" => "video/animaflex",
|
||||
".ai" => "application/postscript",
|
||||
".aif" => "audio/aiff",
|
||||
".aifc" => "audio/aiff",
|
||||
".aiff" => "audio/aiff",
|
||||
".aim" => "application/x-aim",
|
||||
".aip" => "text/x-audiosoft-intra",
|
||||
".ani" => "application/x-navi-animation",
|
||||
".aos" => "application/x-nokia-9000-communicator-add-on-software",
|
||||
".aps" => "application/mime",
|
||||
".arc" => "application/octet-stream",
|
||||
".arj" => "application/arj",
|
||||
".art" => "image/x-jg",
|
||||
".asf" => "video/x-ms-asf",
|
||||
".asm" => "text/x-asm",
|
||||
".asp" => "text/asp",
|
||||
".asx" => "application/x-mplayer2",
|
||||
".au" => "audio/basic",
|
||||
".avi" => "video/avi",
|
||||
".avs" => "video/avs-video",
|
||||
".bcpio" => "application/x-bcpio",
|
||||
".bin" => "application/octet-stream",
|
||||
".bm" => "image/bmp",
|
||||
".bmp" => "image/bmp",
|
||||
".boo" => "application/book",
|
||||
".book" => "application/book",
|
||||
".boz" => "application/x-bzip2",
|
||||
".bsh" => "application/x-bsh",
|
||||
".bz" => "application/x-bzip",
|
||||
".bz2" => "application/x-bzip2",
|
||||
".c" => "text/x-c",
|
||||
".c++" => "text/plain",
|
||||
".cat" => "application/vnd.ms-pki.seccat",
|
||||
".cc" => "text/x-c",
|
||||
".ccad" => "application/clariscad",
|
||||
".cco" => "application/x-cocoa",
|
||||
".cdf" => "application/cdf",
|
||||
".cer" => "application/pkix-cert",
|
||||
".cha" => "application/x-chat",
|
||||
".chat" => "application/x-chat",
|
||||
".conf" => "text/plain",
|
||||
".cpio" => "application/x-cpio",
|
||||
".cpp" => "text/x-c",
|
||||
".cpt" => "application/x-cpt",
|
||||
".crl" => "application/pkcs-crl",
|
||||
".crt" => "application/pkix-cert",
|
||||
".csh" => "application/x-csh",
|
||||
".css" => "text/css",
|
||||
".cxx" => "text/plain",
|
||||
".dcr" => "application/x-director",
|
||||
".deepv" => "application/x-deepv",
|
||||
".def" => "text/plain",
|
||||
".der" => "application/x-x509-ca-cert",
|
||||
".dif" => "video/x-dv",
|
||||
".dir" => "application/x-director",
|
||||
".dl" => "video/dl",
|
||||
".doc" => "application/msword",
|
||||
".dot" => "application/msword",
|
||||
".dp" => "application/commonground",
|
||||
".drw" => "application/drafting",
|
||||
".dump" => "application/octet-stream",
|
||||
".dv" => "video/x-dv",
|
||||
".dvi" => "application/x-dvi",
|
||||
".dwf" => "drawing/x-dwf",
|
||||
".dwg" => "application/acad",
|
||||
".dxf" => "application/dxf",
|
||||
".dxr" => "application/x-director",
|
||||
".el" => "text/x-script.elisp",
|
||||
".elc" => "application/x-elc",
|
||||
".env" => "application/x-envoy",
|
||||
".eps" => "application/postscript",
|
||||
".es" => "application/x-esrehber",
|
||||
".etx" => "text/x-setext",
|
||||
".evy" => "application/envoy",
|
||||
".exe" => "application/octet-stream",
|
||||
".f" => "text/plain",
|
||||
".f77" => "text/x-fortran",
|
||||
".f90" => "text/x-fortran",
|
||||
".fdf" => "application/vnd.fdf",
|
||||
".fif" => "image/fif",
|
||||
".fli" => "video/fli",
|
||||
".flo" => "image/florian",
|
||||
".flx" => "text/vnd.fmi.flexstor",
|
||||
".fmf" => "video/x-atomic3d-feature",
|
||||
".for" => "text/x-fortran",
|
||||
".fpx" => "image/vnd.fpx",
|
||||
".frl" => "application/freeloader",
|
||||
".funk" => "audio/make",
|
||||
".g" => "text/plain",
|
||||
".g3" => "image/g3fax",
|
||||
".gif" => "image/gif",
|
||||
".gl" => "video/gl",
|
||||
".gsd" => "audio/x-gsm",
|
||||
".gsm" => "audio/x-gsm",
|
||||
".gsp" => "application/x-gsp",
|
||||
".gss" => "application/x-gss",
|
||||
".gtar" => "application/x-gtar",
|
||||
".gz" => "application/x-gzip",
|
||||
".gzip" => "application/x-gzip",
|
||||
".h" => "text/plain",
|
||||
".hdf" => "application/x-hdf",
|
||||
".help" => "application/x-helpfile",
|
||||
".hgl" => "application/vnd.hp-hpgl",
|
||||
".hh" => "text/plain",
|
||||
".hlb" => "text/x-script",
|
||||
".hlp" => "application/hlp",
|
||||
".hpg" => "application/vnd.hp-hpgl",
|
||||
".hpgl" => "application/vnd.hp-hpgl",
|
||||
".hta" => "application/hta",
|
||||
".htc" => "text/x-component",
|
||||
".htm" => "text/html",
|
||||
".html" => "text/html",
|
||||
".htmls" => "text/html",
|
||||
".htt" => "text/webviewhtml",
|
||||
".htx" => "text/html",
|
||||
".ice" => "x-conference/x-cooltalk",
|
||||
".ico" => "image/x-icon",
|
||||
".idc" => "text/plain",
|
||||
".ief" => "image/ief",
|
||||
".iefs" => "image/ief",
|
||||
".iges" => "application/iges",
|
||||
".igs" => "application/iges",
|
||||
".ima" => "application/x-ima",
|
||||
".imap" => "application/x-httpd-imap",
|
||||
".inf" => "application/inf",
|
||||
".ins" => "application/x-internett-signup",
|
||||
".ip" => "application/x-ip2",
|
||||
".isu" => "video/x-isvideo",
|
||||
".it" => "audio/it",
|
||||
".iv" => "application/x-inventor",
|
||||
".ivr" => "i-world/i-vrml",
|
||||
".ivy" => "application/x-livescreen",
|
||||
".jam" => "audio/x-jam",
|
||||
".java" => "text/plain",
|
||||
".jcm" => "application/x-java-commerce",
|
||||
".jfif" => "image/jpeg",
|
||||
".jfif-tbnl" => "image/jpeg",
|
||||
".jpe" => "image/jpeg",
|
||||
".jpeg" => "image/jpeg",
|
||||
".jpg" => "image/jpeg",
|
||||
".jps" => "image/x-jps",
|
||||
".js" => "application/javascript",
|
||||
".jut" => "image/jutvision",
|
||||
".kar" => "audio/midi",
|
||||
".ksh" => "application/x-ksh",
|
||||
".la" => "audio/nspaudio",
|
||||
".lam" => "audio/x-liveaudio",
|
||||
".latex" => "application/x-latex",
|
||||
".lha" => "application/lha",
|
||||
".lhx" => "application/octet-stream",
|
||||
".list" => "text/plain",
|
||||
".lma" => "audio/nspaudio",
|
||||
".log" => "text/plain",
|
||||
".lsp" => "application/x-lisp",
|
||||
".lst" => "text/plain",
|
||||
".ltx" => "application/x-latex",
|
||||
".lzh" => "application/x-lzh",
|
||||
".lzx" => "application/lzx",
|
||||
".m" => "text/x-m",
|
||||
".m1v" => "video/mpeg",
|
||||
".m2a" => "audio/mpeg",
|
||||
".m2v" => "video/mpeg",
|
||||
".m3u" => "audio/x-mpequrl",
|
||||
".man" => "application/x-troff-man",
|
||||
".map" => "application/x-navimap",
|
||||
".mar" => "text/plain",
|
||||
".mbd" => "application/mbedlet",
|
||||
".mc$" => "application/x-magic-cap-package-1.0",
|
||||
".mcd" => "application/mcad",
|
||||
".mcf" => "image/vasa",
|
||||
".mcp" => "application/netmc",
|
||||
".me" => "application/x-troff-me",
|
||||
".mht" => "message/rfc822",
|
||||
".mhtml" => "message/rfc822",
|
||||
".mid" => "audio/midi",
|
||||
".midi" => "audio/midi",
|
||||
".mif" => "application/x-mif",
|
||||
".mime" => "www/mime",
|
||||
".mjf" => "audio/x-vnd.audioexplosion.mjuicemediafile",
|
||||
".mjpg" => "video/x-motion-jpeg",
|
||||
".mm" => "application/base64",
|
||||
".mod" => "audio/mod",
|
||||
".moov" => "video/quicktime",
|
||||
".mov" => "video/quicktime",
|
||||
".movie" => "video/x-sgi-movie",
|
||||
".mp2" => "audio/mpeg",
|
||||
".mp3" => "audio/mpeg3",
|
||||
".mpa" => "video/mpeg",
|
||||
".mpc" => "application/x-project",
|
||||
".mpe" => "video/mpeg",
|
||||
".mpeg" => "video/mpeg",
|
||||
".mpg" => "video/mpeg",
|
||||
".mpga" => "audio/mpeg",
|
||||
".mpp" => "application/vnd.ms-project",
|
||||
".mpt" => "application/x-project",
|
||||
".mpv" => "application/x-project",
|
||||
".mpx" => "application/x-project",
|
||||
".mrc" => "application/marc",
|
||||
".ms" => "application/x-troff-ms",
|
||||
".mv" => "video/x-sgi-movie",
|
||||
".my" => "audio/make",
|
||||
".mzz" => "application/x-vnd.audioexplosion.mzz",
|
||||
".nap" => "image/naplps",
|
||||
".naplps" => "image/naplps",
|
||||
".nc" => "application/x-netcdf",
|
||||
".ncm" => "application/vnd.nokia.configuration-message",
|
||||
".nif" => "image/x-niff",
|
||||
".niff" => "image/x-niff",
|
||||
".nix" => "application/x-mix-transfer",
|
||||
".nsc" => "application/x-conference",
|
||||
".nvd" => "application/x-navidoc",
|
||||
".o" => "application/octet-stream",
|
||||
".oda" => "application/oda",
|
||||
".omc" => "application/x-omc",
|
||||
".omcd" => "application/x-omcdatamaker",
|
||||
".omcr" => "application/x-omcregerator",
|
||||
".p" => "text/x-pascal",
|
||||
".p10" => "application/pkcs10",
|
||||
".p12" => "application/pkcs-12",
|
||||
".p7a" => "application/x-pkcs7-signature",
|
||||
".p7c" => "application/pkcs7-mime",
|
||||
".p7m" => "application/pkcs7-mime",
|
||||
".p7r" => "application/x-pkcs7-certreqresp",
|
||||
".p7s" => "application/pkcs7-signature",
|
||||
".part" => "application/pro_eng",
|
||||
".pas" => "text/pascal",
|
||||
".pbm" => "image/x-portable-bitmap",
|
||||
".pcl" => "application/x-pcl",
|
||||
".pct" => "image/x-pict",
|
||||
".pcx" => "image/x-pcx",
|
||||
".pdb" => "chemical/x-pdb",
|
||||
".pdf" => "application/pdf",
|
||||
".pfunk" => "audio/make",
|
||||
".pgm" => "image/x-portable-graymap",
|
||||
".pic" => "image/pict",
|
||||
".pict" => "image/pict",
|
||||
".pko" => "application/vnd.ms-pki.pko",
|
||||
".pl" => "text/plain",
|
||||
".plx" => "application/x-pixclscript",
|
||||
".pm" => "image/x-xpixmap",
|
||||
".pm4" => "application/x-pagemaker",
|
||||
".pm5" => "application/x-pagemaker",
|
||||
".png" => "image/png",
|
||||
".pnm" => "application/x-portable-anymap",
|
||||
".pot" => "application/mspowerpoint",
|
||||
".pov" => "model/x-pov",
|
||||
".ppa" => "application/vnd.ms-powerpoint",
|
||||
".ppm" => "image/x-portable-pixmap",
|
||||
".pps" => "application/mspowerpoint",
|
||||
".ppt" => "application/mspowerpoint",
|
||||
".ppz" => "application/mspowerpoint",
|
||||
".pre" => "application/x-freelance",
|
||||
".prt" => "application/pro_eng",
|
||||
".ps" => "application/postscript",
|
||||
".psd" => "application/octet-stream",
|
||||
".pvu" => "paleovu/x-pv",
|
||||
".pwz" => "application/vnd.ms-powerpoint",
|
||||
".py" => "text/x-script.phyton",
|
||||
".pyc" => "application/x-bytecode.python",
|
||||
".qcp" => "audio/vnd.qcelp",
|
||||
".qd3" => "x-world/x-3dmf",
|
||||
".qd3d" => "x-world/x-3dmf",
|
||||
".qif" => "image/x-quicktime",
|
||||
".qt" => "video/quicktime",
|
||||
".qtc" => "video/x-qtc",
|
||||
".qti" => "image/x-quicktime",
|
||||
".qtif" => "image/x-quicktime",
|
||||
".ra" => "audio/x-pn-realaudio",
|
||||
".ram" => "audio/x-pn-realaudio",
|
||||
".ras" => "application/x-cmu-raster",
|
||||
".rast" => "image/cmu-raster",
|
||||
".rexx" => "text/x-script.rexx",
|
||||
".rf" => "image/vnd.rn-realflash",
|
||||
".rgb" => "image/x-rgb",
|
||||
".rm" => "audio/x-pn-realaudio",
|
||||
".rmi" => "audio/mid",
|
||||
".rmm" => "audio/x-pn-realaudio",
|
||||
".rmp" => "audio/x-pn-realaudio",
|
||||
".rng" => "application/ringing-tones",
|
||||
".rnx" => "application/vnd.rn-realplayer",
|
||||
".roff" => "application/x-troff",
|
||||
".rp" => "image/vnd.rn-realpix",
|
||||
".rpm" => "audio/x-pn-realaudio-plugin",
|
||||
".rt" => "text/richtext",
|
||||
".rtf" => "application/rtf",
|
||||
".rtx" => "application/rtf",
|
||||
".rv" => "video/vnd.rn-realvideo",
|
||||
".s" => "text/x-asm",
|
||||
".s3m" => "audio/s3m",
|
||||
".saveme" => "application/octet-stream",
|
||||
".sbk" => "application/x-tbook",
|
||||
".sdml" => "text/plain",
|
||||
".sdp" => "application/sdp",
|
||||
".sdr" => "application/sounder",
|
||||
".sea" => "application/sea",
|
||||
".set" => "application/set",
|
||||
".sgm" => "text/sgml",
|
||||
".sgml" => "text/sgml",
|
||||
".sh" => "application/x-sh",
|
||||
".shar" => "application/x-shar",
|
||||
".shtml" => "text/html",
|
||||
".sid" => "audio/x-psid",
|
||||
".sit" => "application/x-sit",
|
||||
".skd" => "application/x-koan",
|
||||
".skm" => "application/x-koan",
|
||||
".skp" => "application/x-koan",
|
||||
".skt" => "application/x-koan",
|
||||
".sl" => "application/x-seelogo",
|
||||
".smi" => "application/smil",
|
||||
".smil" => "application/smil",
|
||||
".snd" => "audio/basic",
|
||||
".sol" => "application/solids",
|
||||
".spl" => "application/futuresplash",
|
||||
".spr" => "application/x-sprite",
|
||||
".sprite" => "application/x-sprite",
|
||||
".src" => "application/x-wais-source",
|
||||
".ssi" => "text/x-server-parsed-html",
|
||||
".ssm" => "application/streamingmedia",
|
||||
".sst" => "application/vnd.ms-pki.certstore",
|
||||
".step" => "application/step",
|
||||
".stl" => "application/sla",
|
||||
".stp" => "application/step",
|
||||
".sv4cpio" => "application/x-sv4cpio",
|
||||
".sv4crc" => "application/x-sv4crc",
|
||||
".svf" => "image/vnd.dwg",
|
||||
".svr" => "application/x-world",
|
||||
".swf" => "application/x-shockwave-flash",
|
||||
".svg" => "image/svg+xml",
|
||||
".t" => "application/x-troff",
|
||||
".talk" => "text/x-speech",
|
||||
".tar" => "application/x-tar",
|
||||
".tbk" => "application/toolbook",
|
||||
".tcl" => "application/x-tcl",
|
||||
".tcsh" => "text/x-script.tcsh",
|
||||
".tex" => "application/x-tex",
|
||||
".texi" => "application/x-texinfo",
|
||||
".texinfo" => "application/x-texinfo",
|
||||
".text" => "text/plain",
|
||||
".tgz" => "application/x-compressed",
|
||||
".tif" => "image/tiff",
|
||||
".tiff" => "image/tiff",
|
||||
".tr" => "application/x-troff",
|
||||
".tsi" => "audio/tsp-audio",
|
||||
".tsp" => "application/dsptype",
|
||||
".tsv" => "text/tab-separated-values",
|
||||
".turbot" => "image/florian",
|
||||
".txt" => "text/plain",
|
||||
".uil" => "text/x-uil",
|
||||
".uni" => "text/uri-list",
|
||||
".unis" => "text/uri-list",
|
||||
".unv" => "application/i-deas",
|
||||
".uri" => "text/uri-list",
|
||||
".uris" => "text/uri-list",
|
||||
".ustar" => "application/x-ustar",
|
||||
".uu" => "application/octet-stream",
|
||||
".uue" => "text/x-uuencode",
|
||||
".vcd" => "application/x-cdlink",
|
||||
".vcs" => "text/x-vcalendar",
|
||||
".vda" => "application/vda",
|
||||
".vdo" => "video/vdo",
|
||||
".vew" => "application/groupwise",
|
||||
".viv" => "video/vivo",
|
||||
".vivo" => "video/vivo",
|
||||
".vmd" => "application/vocaltec-media-desc",
|
||||
".vmf" => "application/vocaltec-media-file",
|
||||
".voc" => "audio/voc",
|
||||
".vos" => "video/vosaic",
|
||||
".vox" => "audio/voxware",
|
||||
".vqe" => "audio/x-twinvq-plugin",
|
||||
".vqf" => "audio/x-twinvq",
|
||||
".vql" => "audio/x-twinvq-plugin",
|
||||
".vrml" => "application/x-vrml",
|
||||
".vrt" => "x-world/x-vrt",
|
||||
".vsd" => "application/x-visio",
|
||||
".vst" => "application/x-visio",
|
||||
".vsw" => "application/x-visio",
|
||||
".w60" => "application/wordperfect6.0",
|
||||
".w61" => "application/wordperfect6.1",
|
||||
".w6w" => "application/msword",
|
||||
".wav" => "audio/wav",
|
||||
".wb1" => "application/x-qpro",
|
||||
".wbmp" => "image/vnd.wap.wbmp",
|
||||
".web" => "application/vnd.xara",
|
||||
".wiz" => "application/msword",
|
||||
".wk1" => "application/x-123",
|
||||
".wmf" => "windows/metafile",
|
||||
".wmlc" => "application/vnd.wap.wmlc",
|
||||
".wmls" => "text/vnd.wap.wmlscript",
|
||||
".wmlsc" => "application/vnd.wap.wmlscriptc",
|
||||
".word" => "application/msword",
|
||||
".wp" => "application/wordperfect",
|
||||
".wp5" => "application/wordperfect",
|
||||
".wp6" => "application/wordperfect",
|
||||
".wpd" => "application/wordperfect",
|
||||
".wq1" => "application/x-lotus",
|
||||
".wri" => "application/mswrite",
|
||||
".wrl" => "application/x-world",
|
||||
".wrz" => "model/vrml",
|
||||
".wsc" => "text/scriplet",
|
||||
".wsrc" => "application/x-wais-source",
|
||||
".wtk" => "application/x-wintalk",
|
||||
".xbm" => "image/x-xbitmap",
|
||||
".xdr" => "video/x-amt-demorun",
|
||||
".xgz" => "xgl/drawing",
|
||||
".xif" => "image/vnd.xiff",
|
||||
".xl" => "application/excel",
|
||||
".xla" => "application/excel",
|
||||
".xlb" => "application/excel",
|
||||
".xlc" => "application/excel",
|
||||
".xld" => "application/excel",
|
||||
".xlk" => "application/excel",
|
||||
".xll" => "application/excel",
|
||||
".xlm" => "application/excel",
|
||||
".xls" => "application/excel",
|
||||
".xlt" => "application/excel",
|
||||
".xlv" => "application/excel",
|
||||
".xlw" => "application/excel",
|
||||
".xm" => "audio/xm",
|
||||
".xml" => "application/xml",
|
||||
".xmz" => "xgl/movie",
|
||||
".xpix" => "application/x-vnd.ls-xpix",
|
||||
".x-png" => "image/png",
|
||||
".xsr" => "video/x-amt-showrun",
|
||||
".xwd" => "image/x-xwd",
|
||||
".xyz" => "chemical/x-pdb",
|
||||
".zip" => "application/zip",
|
||||
".zoo" => "application/octet-stream",
|
||||
".zsh" => "text/x-script.zsh",
|
||||
".apk" => "application/vnd.android.package-archive",
|
||||
".ipa" => "application/octet-stream.ipa",
|
||||
".flv" => "video/x-flv",
|
||||
".mp4" => "video/mp4",
|
||||
".m3u8" => "application/x-mpegURL",
|
||||
".ts" => "video/MP2T",
|
||||
".3gp" => "video/3gpp",
|
||||
".wmv" => "video/x-ms-wmv",
|
||||
);
|
@ -0,0 +1,361 @@
|
||||
<?php
|
||||
|
||||
require_once("conf.php");
|
||||
require_once("http.php");
|
||||
require_once("utils.php");
|
||||
require_once("digest.php");
|
||||
|
||||
|
||||
//------------------------------普通上传------------------------------
|
||||
function UCloud_PutFile($bucket, $key, $file)
|
||||
{
|
||||
$action_type = ActionType::PUTFILE;
|
||||
$err = CheckConfig(ActionType::PUTFILE);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
$f = @fopen($file, "r");
|
||||
if (!$f) return array(null, new UCloud_Error(-1, -1, "open $file error"));
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = $key;
|
||||
$content = @fread($f, filesize($file));
|
||||
list($mimetype, $err) = GetFileMimeType($file);
|
||||
if ($err) {
|
||||
fclose($f);
|
||||
return array("", $err);
|
||||
}
|
||||
$req = new HTTP_Request('PUT', array('host'=>$host, 'path'=>$path), $content, $bucket, $key, $action_type);
|
||||
$req->Header['Expect'] = '';
|
||||
$req->Header['Content-Type'] = $mimetype;
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null, $mimetype);
|
||||
list($data, $err) = UCloud_Client_Call($client, $req);
|
||||
fclose($f);
|
||||
return array($data, $err);
|
||||
}
|
||||
|
||||
//------------------------------表单上传------------------------------
|
||||
function UCloud_MultipartForm($bucket, $key, $file)
|
||||
{
|
||||
$action_type = ActionType::POSTFILE;
|
||||
$err = CheckConfig(ActionType::POSTFILE);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
$f = @fopen($file, "r");
|
||||
if (!$f) return array(null, new UCloud_Error(-1, -1, "open $file error"));
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = "";
|
||||
$fsize = filesize($file);
|
||||
$content = "";
|
||||
if ($fsize != 0) {
|
||||
$content = @fread($f, filesize($file));
|
||||
if ($content == FALSE) {
|
||||
fclose($f);
|
||||
return array(null, new UCloud_Error(0, -1, "read file error"));
|
||||
}
|
||||
}
|
||||
list($mimetype, $err) = GetFileMimeType($file);
|
||||
if ($err) {
|
||||
fclose($f);
|
||||
return array("", $err);
|
||||
}
|
||||
|
||||
$req = new HTTP_Request('POST', array('host'=>$host, 'path'=>$path), $content, $bucket, $key, $action_type);
|
||||
$req->Header['Expect'] = '';
|
||||
$token = UCloud_SignRequest(null, $req, $mimetype);
|
||||
|
||||
$fields = array('Authorization'=>$token, 'FileName' => $key);
|
||||
$files = array('files'=>array('file', $file, $content, $mimetype));
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null, NO_AUTH_CHECK);
|
||||
list($data, $err) = UCloud_Client_CallWithMultipartForm($client, $req, $fields, $files);
|
||||
fclose($f);
|
||||
return array($data, $err);
|
||||
}
|
||||
|
||||
//------------------------------分片上传------------------------------
|
||||
function UCloud_MInit($bucket, $key)
|
||||
{
|
||||
|
||||
$err = CheckConfig(ActionType::MINIT);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = $key;
|
||||
$querys = array(
|
||||
"uploads" => ""
|
||||
);
|
||||
$req = new HTTP_Request('POST', array('host'=>$host, 'path'=>$path, 'query'=>$querys), null, $bucket, $key);
|
||||
$req->Header['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
return UCloud_Client_Call($client, $req);
|
||||
}
|
||||
|
||||
//@results: (tagList, err)
|
||||
function UCloud_MUpload($bucket, $key, $file, $uploadId, $blkSize, $partNumber=0)
|
||||
{
|
||||
|
||||
$err = CheckConfig(ActionType::MUPLOAD);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
$f = @fopen($file, "r");
|
||||
if (!$f) return array(null, new UCloud_Error(-1, -1, "open $file error"));
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
|
||||
$etagList = array();
|
||||
list($mimetype, $err) = GetFileMimeType($file);
|
||||
if ($err) {
|
||||
fclose($f);
|
||||
return array("", $err);
|
||||
}
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
for(;;) {
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = $key;
|
||||
if (@fseek($f, $blkSize*$partNumber, SEEK_SET) < 0) {
|
||||
fclose($f);
|
||||
return array(null, new UCloud_Error(0, -1, "fseek error"));
|
||||
}
|
||||
$content = @fread($f, $blkSize);
|
||||
if ($content == FALSE) {
|
||||
if (feof($f)) break;
|
||||
fclose($f);
|
||||
return array(null, new UCloud_Error(0, -1, "read file error"));
|
||||
}
|
||||
|
||||
$querys = array(
|
||||
"uploadId" => $uploadId,
|
||||
"partNumber" => $partNumber
|
||||
);
|
||||
$req = new HTTP_Request('PUT', array('host'=>$host, 'path'=>$path, 'query'=>$querys), $content, $bucket, $key);
|
||||
$req->Header['Content-Type'] = $mimetype;
|
||||
$req->Header['Expect'] = '';
|
||||
list($data, $err) = UCloud_Client_Call($client, $req);
|
||||
if ($err) {
|
||||
fclose($f);
|
||||
return array(null, $err);
|
||||
}
|
||||
$etag = @$data['ETag'];
|
||||
$part = @$data['PartNumber'];
|
||||
if ($part != $partNumber) {
|
||||
fclose($f);
|
||||
return array(null, new UCloud_Error(0, -1, "unmatch partnumber"));
|
||||
}
|
||||
$etagList[] = $etag;
|
||||
$partNumber += 1;
|
||||
}
|
||||
fclose($f);
|
||||
return array($etagList, null);
|
||||
}
|
||||
|
||||
function UCloud_MFinish($bucket, $key, $uploadId, $etagList, $newKey = '')
|
||||
{
|
||||
|
||||
$err = CheckConfig(ActionType::MFINISH);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = $key;
|
||||
$querys = array(
|
||||
'uploadId' => $uploadId,
|
||||
'newKey' => $newKey,
|
||||
);
|
||||
|
||||
$body = @implode(',', $etagList);
|
||||
$req = new HTTP_Request('POST', array('host'=>$host, 'path'=>$path, 'query'=>$querys), $body, $bucket, $key);
|
||||
$req->Header['Content-Type'] = 'text/plain';
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
return UCloud_Client_Call($client, $req);
|
||||
}
|
||||
|
||||
function UCloud_MCancel($bucket, $key, $uploadId)
|
||||
{
|
||||
|
||||
$err = CheckConfig(ActionType::MCANCEL);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = $key;
|
||||
$querys = array(
|
||||
'uploadId' => $uploadId
|
||||
);
|
||||
|
||||
$req = new HTTP_Request('DELETE', array('host'=>$host, 'path'=>$path, 'query'=>$querys), null, $bucket, $key);
|
||||
$req->Header['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
return UCloud_Client_Call($client, $req);
|
||||
}
|
||||
|
||||
//------------------------------秒传------------------------------
|
||||
function UCloud_UploadHit($bucket, $key, $file)
|
||||
{
|
||||
|
||||
$err = CheckConfig(ActionType::UPLOADHIT);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
$f = @fopen($file, "r");
|
||||
if (!$f) return array(null, new UCloud_Error(-1, -1, "open $file error"));
|
||||
|
||||
$content = "";
|
||||
$fileSize = filesize($file);
|
||||
if ($fileSize != 0) {
|
||||
$content = @fread($f, $fileSize);
|
||||
if ($content == FALSE) {
|
||||
fclose($f);
|
||||
return array(null, new UCloud_Error(0, -1, "read file error"));
|
||||
}
|
||||
}
|
||||
list($fileHash, $err) = UCloud_FileHash($file);
|
||||
if ($err) {
|
||||
fclose($f);
|
||||
return array(null, $err);
|
||||
}
|
||||
fclose($f);
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = "uploadhit";
|
||||
$querys = array(
|
||||
'Hash' => $fileHash,
|
||||
'FileName' => $key,
|
||||
'FileSize' => $fileSize
|
||||
);
|
||||
|
||||
$req = new HTTP_Request('POST', array('host'=>$host, 'path'=>$path, 'query'=>$querys), null, $bucket, $key);
|
||||
$req->Header['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
return UCloud_Client_Call($client, $req);
|
||||
}
|
||||
|
||||
//------------------------------删除文件------------------------------
|
||||
function UCloud_Delete($bucket, $key)
|
||||
{
|
||||
|
||||
$err = CheckConfig(ActionType::DELETE);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = "$key";
|
||||
|
||||
$req = new HTTP_Request('DELETE', array('host'=>$host, 'path'=>$path), null, $bucket, $key);
|
||||
$req->Header['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
return UCloud_Client_Call($client, $req);
|
||||
}
|
||||
|
||||
//------------------------------追加上传------------------------------
|
||||
function UCloud_AppendFile($bucket, $key, $file, $position)
|
||||
{
|
||||
$action_type = ActionType::APPENDFILE;
|
||||
$err = CheckConfig(ActionType::APPENDFILE);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
$f = @fopen($file, "r");
|
||||
if (!$f) return array(null, new UCloud_Error(-1, -1, "open $file error"));
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$key = $key . "?append&position=" . $position;
|
||||
$path = $key;
|
||||
$content = @fread($f, filesize($file));
|
||||
list($mimetype, $err) = GetFileMimeType($file);
|
||||
if ($err) {
|
||||
fclose($f);
|
||||
return array("", $err);
|
||||
}
|
||||
$req = new HTTP_Request('PUT', array('host'=>$host, 'path'=>$path), $content, $bucket, $key, $action_type);
|
||||
$req->Header['Expect'] = '';
|
||||
$req->Header['Content-Type'] = $mimetype;
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null, $mimetype);
|
||||
list($data, $err) = UCloud_Client_Call($client, $req);
|
||||
fclose($f);
|
||||
return array($data, $err);
|
||||
}
|
||||
|
||||
//------------------------------列表目录------------------------------
|
||||
function UCloud_ListObjects($bucket, $path_prefix, $marker, $count, $delimiter)
|
||||
{
|
||||
$action_type = ActionType::LISTOBJECTS;
|
||||
$err = CheckConfig(ActionType::LISTOBJECTS);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
$host = $bucket . $UCLOUD_PROXY_SUFFIX;
|
||||
$path = "?listobjects&prefix=" . $path_prefix ."&marker=". $marker . "&max-keys=" . $count ."&delimiter=" .$delimiter;
|
||||
|
||||
$req = new HTTP_Request('GET', array('host'=>$host, 'path'=>$path), null, $bucket, null, $action_type);
|
||||
$req->Header['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
list($data, $err) = UCloud_Client_Call($client, $req);
|
||||
return array($data, $err);
|
||||
}
|
||||
|
||||
//------------------------------生成公有文件Url------------------------------
|
||||
// @results: $url
|
||||
function UCloud_MakePublicUrl($bucket, $key)
|
||||
{
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
return $bucket . $UCLOUD_PROXY_SUFFIX . "/" . rawurlencode($key);
|
||||
}
|
||||
//------------------------------生成私有文件Url------------------------------
|
||||
// @results: $url
|
||||
function UCloud_MakePrivateUrl($bucket, $key, $expires = 0)
|
||||
{
|
||||
|
||||
$err = CheckConfig(ActionType::GETFILE);
|
||||
if ($err != null) {
|
||||
return array(null, $err);
|
||||
}
|
||||
|
||||
global $UCLOUD_PUBLIC_KEY;
|
||||
|
||||
$public_url = UCloud_MakePublicUrl($bucket, $key);
|
||||
$req = new HTTP_Request('GET', array('path'=>$public_url), null, $bucket, $key);
|
||||
if ($expires > 0) {
|
||||
$req->Header['Expires'] = $expires;
|
||||
}
|
||||
|
||||
$client = new UCloud_AuthHttpClient(null);
|
||||
$temp = $client->Auth->SignRequest($req, null, QUERY_STRING_CHECK);
|
||||
$signature = substr($temp, -28, 28);
|
||||
$url = $public_url . "?UCloudPublicKey=" . rawurlencode($UCLOUD_PUBLIC_KEY) . "&Signature=" . rawurlencode($signature);
|
||||
if ('' != $expires) {
|
||||
$url .= "&Expires=" . rawurlencode($expires);
|
||||
}
|
||||
return $url;
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
require_once("mimetypes.php");
|
||||
|
||||
define('BLKSIZE', 4*1024*1024);
|
||||
|
||||
abstract class ActionType
|
||||
{
|
||||
const NONE = -1;
|
||||
const PUTFILE = 0;
|
||||
const POSTFILE = 1;
|
||||
const MINIT = 2;
|
||||
const MUPLOAD = 3;
|
||||
const MFINISH = 4;
|
||||
const MCANCEL = 5;
|
||||
const DELETE = 6;
|
||||
const UPLOADHIT = 7;
|
||||
const GETFILE = 8;
|
||||
const APPENDFILE = 9;
|
||||
const LISTOBJECTS = 10;
|
||||
}
|
||||
|
||||
class UCloud_Error
|
||||
{
|
||||
public $Code; // int
|
||||
public $ErrRet; // int
|
||||
public $ErrMsg; // string
|
||||
public $SessionId; // string
|
||||
|
||||
public function __construct($code, $errRet, $errMsg)
|
||||
{
|
||||
$this->Code = $code;
|
||||
$this->ErrRet = $errRet;
|
||||
$this->ErrMsg = $errMsg;
|
||||
}
|
||||
}
|
||||
|
||||
function UCloud_UrlSafe_Encode($data)
|
||||
{
|
||||
$find = array('+', '/');
|
||||
$replace = array('-', '_');
|
||||
return str_replace($find, $replace, $data);
|
||||
}
|
||||
|
||||
function UCloud_UrlSafe_Decode($data)
|
||||
{
|
||||
$find = array('-', '_');
|
||||
$replace = array('+', '/');
|
||||
return str_replace($find, $replace, $data);
|
||||
}
|
||||
|
||||
//@results: (hash, err)
|
||||
function UCloud_FileHash($file)
|
||||
{
|
||||
$f = fopen($file, "r");
|
||||
if (!$f) return array(null, new UCloud_Error(0, -1, "open $file error"));
|
||||
|
||||
$fileSize = filesize($file);
|
||||
$buffer = '';
|
||||
$sha = '';
|
||||
$blkcnt = $fileSize/BLKSIZE;
|
||||
if ($fileSize % BLKSIZE) $blkcnt += 1;
|
||||
$buffer .= pack("L", $blkcnt);
|
||||
if ($fileSize <= BLKSIZE) {
|
||||
$content = fread($f, BLKSIZE);
|
||||
if (!$content) {
|
||||
fclose($f);
|
||||
return array("", new UCloud_Error(0, -1, "read file error"));
|
||||
}
|
||||
$sha .= sha1($content, TRUE);
|
||||
} else {
|
||||
for($i=0; $i<$blkcnt; $i+=1) {
|
||||
$content = fread($f, BLKSIZE);
|
||||
if (!$content) {
|
||||
if (feof($f)) break;
|
||||
fclose($f);
|
||||
return array("", new UCloud_Error(0, -1, "read file error"));
|
||||
}
|
||||
$sha .= sha1($content, TRUE);
|
||||
}
|
||||
$sha = sha1($sha, TRUE);
|
||||
}
|
||||
$buffer .= $sha;
|
||||
$hash = UCloud_UrlSafe_Encode(base64_encode($buffer));
|
||||
fclose($f);
|
||||
return array($hash, null);
|
||||
}
|
||||
|
||||
//@results: (mime, err)
|
||||
function GetFileMimeType($filename)
|
||||
{
|
||||
$mimetype = "";
|
||||
$ext = "";
|
||||
$filename_component = explode(".", $filename);
|
||||
if (count($filename_component) >= 2) {
|
||||
$ext = "." . $filename_component[count($filename_component)-1];
|
||||
}
|
||||
|
||||
global $mimetype_complete_map;
|
||||
if (array_key_exists($ext, $mimetype_complete_map)) {
|
||||
$mimetype = $mimetype_complete_map[$ext];
|
||||
} else if (function_exists('mime_content_type')) {
|
||||
$mimetype = mime_content_type($filename);
|
||||
} else if (function_exists('finfo_file')) {
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE); // 返回 mime 类型
|
||||
$mimetype = finfo_file($finfo, $filename);
|
||||
finfo_close($finfo);
|
||||
} else {
|
||||
return array("application/octet-stream", null);
|
||||
}
|
||||
return array($mimetype, null);
|
||||
}
|
||||
|
||||
function CheckConfig($action) {
|
||||
|
||||
global $UCLOUD_PUBLIC_KEY;
|
||||
global $UCLOUD_PRIVATE_KEY;
|
||||
global $UCLOUD_PROXY_SUFFIX;
|
||||
|
||||
switch ($action) {
|
||||
case ActionType::PUTFILE:
|
||||
case ActionType::POSTFILE:
|
||||
case ActionType::MINIT:
|
||||
case ActionType::MUPLOAD:
|
||||
case ActionType::MCANCEL:
|
||||
case ActionType::MFINISH:
|
||||
case ActionType::DELETE:
|
||||
case ActionType::UPLOADHIT:
|
||||
case ActionType::LISTOBJECTS:
|
||||
if ($UCLOUD_PROXY_SUFFIX == "") {
|
||||
return new UCloud_Error(400, -1, "no proxy suffix found in config");
|
||||
} else if ($UCLOUD_PUBLIC_KEY == "" || strstr($UCLOUD_PUBLIC_KEY, " ") != FALSE) {
|
||||
return new UCloud_Error(400, -1, "invalid public key found in config");
|
||||
} else if ($UCLOUD_PRIVATE_KEY == "" || strstr($UCLOUD_PRIVATE_KEY, " ") != FALSE) {
|
||||
return new UCloud_Error(400, -1, "invalid private key found in config");
|
||||
}
|
||||
break;
|
||||
case ActionType::GETFILE:
|
||||
if ($UCLOUD_PROXY_SUFFIX == "") {
|
||||
return new UCloud_Error(400, -1, "no proxy suffix found in config");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
Loading…
Reference in new issue