添加网站文件
This commit is contained in:
280
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Client.php
vendored
Normal file
280
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Client.php
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
include("Common.php");
|
||||
|
||||
use Qcloud\Cos\Signature;
|
||||
use GuzzleHttp\Client as HttpClient;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use GuzzleHttp\Command\Guzzle\Description;
|
||||
use GuzzleHttp\Command\Guzzle\GuzzleClient;
|
||||
use GuzzleHttp\Command\Guzzle\Deserializer;
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use GuzzleHttp\Command\Exception\CommandException;
|
||||
use GuzzleHttp\Middleware;
|
||||
use GuzzleHttp\Psr7;
|
||||
|
||||
class Client extends GuzzleClient {
|
||||
const VERSION = '2.1.1';
|
||||
|
||||
public $httpClient;
|
||||
|
||||
private $api;
|
||||
private $desc;
|
||||
private $action;
|
||||
private $operation;
|
||||
private $cosConfig;
|
||||
private $signature;
|
||||
private $rawCosConfig;
|
||||
|
||||
public function __construct($cosConfig) {
|
||||
$this->rawCosConfig = $cosConfig;
|
||||
$this->cosConfig['schema'] = isset($cosConfig['schema']) ? $cosConfig['schema'] : 'http';
|
||||
$this->cosConfig['region'] = region_map($cosConfig['region']);
|
||||
$this->cosConfig['appId'] = isset($cosConfig['credentials']['appId']) ? $cosConfig['credentials']['appId'] : null;
|
||||
$this->cosConfig['secretId'] = isset($cosConfig['credentials']['secretId']) ? $cosConfig['credentials']['secretId'] : "";
|
||||
$this->cosConfig['secretKey'] = isset($cosConfig['credentials']['secretKey']) ? $cosConfig['credentials']['secretKey'] : "";
|
||||
$this->cosConfig['anonymous'] = isset($cosConfig['credentials']['anonymous']) ? $cosConfig['anonymous']['anonymous'] : false;
|
||||
$this->cosConfig['token'] = isset($cosConfig['credentials']['token']) ? $cosConfig['credentials']['token'] : null;
|
||||
$this->cosConfig['timeout'] = isset($cosConfig['timeout']) ? $cosConfig['timeout'] : 3600;
|
||||
$this->cosConfig['connect_timeout'] = isset($cosConfig['connect_timeout']) ? $cosConfig['connect_timeout'] : 3600;
|
||||
$this->cosConfig['ip'] = isset($cosConfig['ip']) ? $cosConfig['ip'] : null;
|
||||
$this->cosConfig['port'] = isset($cosConfig['port']) ? $cosConfig['port'] : null;
|
||||
$this->cosConfig['endpoint'] = isset($cosConfig['endpoint']) ? $cosConfig['endpoint'] : null;
|
||||
$this->cosConfig['domain'] = isset($cosConfig['domain']) ? $cosConfig['domain'] : null;
|
||||
$this->cosConfig['proxy'] = isset($cosConfig['proxy']) ? $cosConfig['proxy'] : null;
|
||||
$this->cosConfig['retry'] = isset($cosConfig['retry']) ? $cosConfig['retry'] : 1;
|
||||
$this->cosConfig['userAgent'] = isset($cosConfig['userAgent']) ? $cosConfig['userAgent'] : 'cos-php-sdk-v5.'. Client::VERSION;
|
||||
$this->cosConfig['pathStyle'] = isset($cosConfig['pathStyle']) ? $cosConfig['pathStyle'] : false;
|
||||
|
||||
|
||||
$service = Service::getService();
|
||||
$handler = HandlerStack::create();
|
||||
$handler->push(Middleware::mapRequest(function (RequestInterface $request) {
|
||||
return $request->withHeader('User-Agent', $this->cosConfig['userAgent']);
|
||||
}));
|
||||
if ($this->cosConfig['anonymous'] != true) {
|
||||
$handler->push($this::handleSignature($this->cosConfig['secretId'], $this->cosConfig['secretKey']));
|
||||
}
|
||||
if ($this->cosConfig['token'] != null) {
|
||||
$handler->push(Middleware::mapRequest(function (RequestInterface $request) {
|
||||
return $request->withHeader('x-cos-security-token', $this->cosConfig['token']);
|
||||
}));
|
||||
}
|
||||
$handler->push($this::handleErrors());
|
||||
$this->signature = new Signature($this->cosConfig['secretId'], $this->cosConfig['secretKey'], $this->cosConfig['token']);
|
||||
$this->httpClient = new HttpClient([
|
||||
'base_uri' => $this->cosConfig['schema'].'://cos.' . $this->cosConfig['region'] . '.myqcloud.com/',
|
||||
'timeout' => $this->cosConfig['timeout'],
|
||||
'handler' => $handler,
|
||||
'proxy' => $this->cosConfig['proxy'],
|
||||
]);
|
||||
$this->desc = new Description($service);
|
||||
$this->api = (array)($this->desc->getOperations());
|
||||
parent::__construct($this->httpClient, $this->desc, [$this,
|
||||
'commandToRequestTransformer'], [$this, 'responseToResultTransformer'],
|
||||
null);
|
||||
}
|
||||
|
||||
public function commandToRequestTransformer(CommandInterface $command)
|
||||
{
|
||||
$this->action = $command->GetName();
|
||||
$this->operation = $this->api[$this->action];
|
||||
$transformer = new CommandToRequestTransformer($this->cosConfig, $this->operation);
|
||||
$seri = new Serializer($this->desc);
|
||||
$request = $seri($command);
|
||||
$request = $transformer->bucketStyleTransformer($command, $request);
|
||||
$request = $transformer->uploadBodyTransformer($command, $request);
|
||||
$request = $transformer->metadataTransformer($command, $request);
|
||||
$request = $transformer->md5Transformer($command, $request);
|
||||
$request = $transformer->specialParamTransformer($command, $request);
|
||||
return $request;
|
||||
}
|
||||
|
||||
public function responseToResultTransformer(ResponseInterface $response, RequestInterface $request, CommandInterface $command)
|
||||
{
|
||||
$transformer = new ResultTransformer($this->cosConfig, $this->operation);
|
||||
$transformer->writeDataToLocal($command, $request, $response);
|
||||
$deseri = new Deserializer($this->desc, true);
|
||||
$result = $deseri($response, $request, $command);
|
||||
|
||||
$result = $transformer->metaDataTransformer($command, $response, $result);
|
||||
$result = $transformer->extraHeadersTransformer($command, $request, $result);
|
||||
$result = $transformer->selectContentTransformer($command, $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
}
|
||||
|
||||
public function __call($method, array $args) {
|
||||
for ($i = 1; $i <= $this->cosConfig['retry']; $i++) {
|
||||
try {
|
||||
return parent::__call(ucfirst($method), $args);
|
||||
} catch (CommandException $e) {
|
||||
if ($i != $this->cosConfig['retry']) {
|
||||
sleep(1 << ($i-1));
|
||||
continue;
|
||||
}
|
||||
$previous = $e->getPrevious();
|
||||
if ($previous !== null) {
|
||||
throw $previous;
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getApi() {
|
||||
return $this->api;
|
||||
}
|
||||
|
||||
private function getCosConfig() {
|
||||
return $this->cosConfig;
|
||||
}
|
||||
|
||||
private function createPresignedUrl(RequestInterface $request, $expires) {
|
||||
return $this->signature->createPresignedUrl($request, $expires);
|
||||
}
|
||||
|
||||
public function getPresignetUrl($method, $args, $expires = "+30 minutes") {
|
||||
$command = $this->getCommand($method, $args);
|
||||
$request = $this->commandToRequestTransformer($command);
|
||||
return $this->createPresignedUrl($request, $expires);
|
||||
}
|
||||
|
||||
public function getObjectUrl($bucket, $key, $expires = "+30 minutes", array $args = array()) {
|
||||
$command = $this->getCommand('GetObject', $args + array('Bucket' => $bucket, 'Key' => $key));
|
||||
$request = $this->commandToRequestTransformer($command);
|
||||
return $this->createPresignedUrl($request, $expires)->__toString();
|
||||
}
|
||||
|
||||
public function upload($bucket, $key, $body, $options = array()) {
|
||||
$body = Psr7\stream_for($body);
|
||||
$options['PartSize'] = isset($options['PartSize']) ? $options['PartSize'] : MultipartUpload::DEFAULT_PART_SIZE;
|
||||
if ($body->getSize() < $options['PartSize']) {
|
||||
$rt = $this->putObject(array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key,
|
||||
'Body' => $body,
|
||||
) + $options);
|
||||
}
|
||||
else {
|
||||
$multipartUpload = new MultipartUpload($this, $body, array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key,
|
||||
) + $options);
|
||||
|
||||
$rt = $multipartUpload->performUploading();
|
||||
}
|
||||
return $rt;
|
||||
}
|
||||
|
||||
public function resumeUpload($bucket, $key, $body, $uploadId, $options = array()) {
|
||||
$body = Psr7\stream_for($body);
|
||||
$options['PartSize'] = isset($options['PartSize']) ? $options['PartSize'] : MultipartUpload::DEFAULT_PART_SIZE;
|
||||
$multipartUpload = new MultipartUpload($this, $body, array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key,
|
||||
'UploadId' => $uploadId,
|
||||
) + $options);
|
||||
|
||||
$rt = $multipartUpload->resumeUploading();
|
||||
return $rt;
|
||||
}
|
||||
|
||||
public function copy($bucket, $key, $copySource, $options = array()) {
|
||||
|
||||
$options['PartSize'] = isset($options['PartSize']) ? $options['PartSize'] : Copy::DEFAULT_PART_SIZE;
|
||||
|
||||
// set copysource client
|
||||
$sourceConfig = $this->rawCosConfig;
|
||||
$sourceConfig['region'] = $copySource['Region'];
|
||||
$cosSourceClient = new Client($sourceConfig);
|
||||
$copySource['VersionId'] = isset($copySource['VersionId']) ? $copySource['VersionId'] : "";
|
||||
try {
|
||||
$rt = $cosSourceClient->headObject(
|
||||
array('Bucket'=>$copySource['Bucket'],
|
||||
'Key'=>$copySource['Key'],
|
||||
'VersionId'=>$copySource['VersionId'],
|
||||
)
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$contentLength =$rt['ContentLength'];
|
||||
// sample copy
|
||||
if ($contentLength < $options['PartSize']) {
|
||||
$rt = $this->copyObject(array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key,
|
||||
'CopySource' => $copySource['Bucket']. '.cos.'. $copySource['Region'].
|
||||
".myqcloud.com/". $copySource['Key']. "?versionId=". $copySource['VersionId'],
|
||||
) + $options
|
||||
);
|
||||
return $rt;
|
||||
}
|
||||
// multi part copy
|
||||
$copySource['ContentLength'] = $contentLength;
|
||||
$copy = new Copy($this, $copySource, array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key
|
||||
) + $options
|
||||
);
|
||||
return $copy->copy();
|
||||
}
|
||||
|
||||
public function doesBucketExist($bucket, array $options = array())
|
||||
{
|
||||
try {
|
||||
$this->HeadBucket(array(
|
||||
'Bucket' => $bucket));
|
||||
return True;
|
||||
} catch (\Exception $e){
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
public function doesObjectExist($bucket, $key, array $options = array())
|
||||
{
|
||||
try {
|
||||
$this->HeadObject(array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key));
|
||||
return True;
|
||||
} catch (\Exception $e){
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
public static function explodeKey($key) {
|
||||
// Remove a leading slash if one is found
|
||||
$split_key = explode('/', $key && $key[0] == '/' ? substr($key, 1) : $key);
|
||||
// Remove empty element
|
||||
$split_key = array_filter($split_key, function($var) {
|
||||
return !($var == '' || $var == null);
|
||||
});
|
||||
$final_key = implode("/", $split_key);
|
||||
if (substr($key, -1) == '/') {
|
||||
$final_key = $final_key . '/';
|
||||
}
|
||||
return $final_key;
|
||||
}
|
||||
|
||||
public static function handleSignature($secretId, $secretKey) {
|
||||
return function (callable $handler) use ($secretId, $secretKey) {
|
||||
return new SignatureMiddleware($handler, $secretId, $secretKey);
|
||||
};
|
||||
}
|
||||
|
||||
public static function handleErrors() {
|
||||
return function (callable $handler) {
|
||||
return new ExceptionMiddleware($handler);
|
||||
};
|
||||
}
|
||||
}
|
||||
176
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/CommandToRequestTransformer.php
vendored
Normal file
176
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/CommandToRequestTransformer.php
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class CommandToRequestTransformer {
|
||||
private $config;
|
||||
private $operation;
|
||||
|
||||
public function __construct( $config, $operation ) {
|
||||
$this->config = $config;
|
||||
$this->operation = $operation;
|
||||
}
|
||||
|
||||
// format bucket style
|
||||
|
||||
public function bucketStyleTransformer( CommandInterface $command, RequestInterface $request ) {
|
||||
$action = $command->getName();
|
||||
if ($action == 'ListBuckets') {
|
||||
$uri = "service.cos.myqcloud.com";
|
||||
|
||||
if ($this->config['endpoint'] != null) {
|
||||
$uri = $this->config['endpoint'];
|
||||
}
|
||||
if ($this->config['domain'] != null) {
|
||||
$uri = $this->config['domain'];
|
||||
}
|
||||
if ($this->config['ip'] != null) {
|
||||
$uri = $this->config['ip'];
|
||||
if ($this->config['port'] != null) {
|
||||
$uri = $this->config['ip'] . ":" . $this->config['port'];
|
||||
}
|
||||
}
|
||||
return $request->withUri(new Uri($this->config['schema']."://". $uri. "/"));
|
||||
}
|
||||
$operation = $this->operation;
|
||||
$bucketname = $command['Bucket'];
|
||||
|
||||
$appId = $this->config['appId'];
|
||||
if ( $appId != null && endWith( $bucketname, '-'.$appId ) == False ) {
|
||||
$bucketname = $bucketname.'-'.$appId;
|
||||
}
|
||||
$command['Bucket'] = $bucketname;
|
||||
$path = '';
|
||||
|
||||
$http_method = $operation['httpMethod'];
|
||||
$uri = $operation['uri'];
|
||||
|
||||
// Hoststyle is used by default
|
||||
// Pathstyle
|
||||
if ( $this->config['pathStyle'] != true ) {
|
||||
if ( isset( $operation['parameters']['Bucket'] ) && $command->hasParam( 'Bucket' ) ) {
|
||||
$uri = str_replace( '{Bucket}', '', $uri );
|
||||
}
|
||||
|
||||
if ( isset( $operation['parameters']['Key'] ) && $command->hasParam( 'Key' ) ) {
|
||||
$uri = str_replace( '{/Key*}', encodeKey( $command['Key'] ), $uri );
|
||||
}
|
||||
}
|
||||
if ($this->config['endpoint'] == null) {
|
||||
$this->config['endpoint'] = "myqcloud.com";
|
||||
}
|
||||
$origin_host = $bucketname. '.cos.' . $this->config['region'] . '.' . $this->config['endpoint'];
|
||||
// domain
|
||||
if ( $this->config['domain'] != null ) {
|
||||
$origin_host = $this->config['domain'];
|
||||
}
|
||||
$host = $origin_host;
|
||||
if ( $this->config['ip'] != null ) {
|
||||
$host = $this->config['ip'];
|
||||
if ( $this->config['port'] != null ) {
|
||||
$host = $this->config['ip'] . ':' . $this->config['port'];
|
||||
}
|
||||
}
|
||||
|
||||
$path = $this->config['schema'].'://'. $host . $uri;
|
||||
$uri = new Uri( $path );
|
||||
$query = $request->getUri()->getQuery();
|
||||
if ( $uri->getQuery() != $query && $uri->getQuery() != '' ) {
|
||||
$query = $uri->getQuery() . '&' . $request->getUri()->getQuery();
|
||||
}
|
||||
$uri = $uri->withQuery( $query );
|
||||
$request = $request->withUri( $uri );
|
||||
$request = $request->withHeader( 'Host', $origin_host );
|
||||
return $request;
|
||||
}
|
||||
|
||||
// format upload body
|
||||
|
||||
public function uploadBodyTransformer( CommandInterface $command, $request, $bodyParameter = 'Body', $sourceParameter = 'SourceFile' ) {
|
||||
|
||||
$operation = $this->operation;
|
||||
if ( !isset( $operation['parameters']['Body'] ) ) {
|
||||
return $request;
|
||||
}
|
||||
$source = isset( $command[$sourceParameter] ) ? $command[$sourceParameter] : null;
|
||||
$body = isset( $command[$bodyParameter] ) ? $command[$bodyParameter] : null;
|
||||
// If a file path is passed in then get the file handle
|
||||
if ( is_string( $source ) && file_exists( $source ) ) {
|
||||
$body = fopen( $source, 'rb' );
|
||||
}
|
||||
// Prepare the body parameter and remove the source file parameter
|
||||
if ( null !== $body ) {
|
||||
return $request;
|
||||
} else {
|
||||
throw new InvalidArgumentException(
|
||||
"You must specify a non-null value for the {$bodyParameter} or {$sourceParameter} parameters." );
|
||||
}
|
||||
}
|
||||
|
||||
// update md5
|
||||
|
||||
public function md5Transformer( CommandInterface $command, $request ) {
|
||||
$operation = $this->operation;
|
||||
if ( isset( $operation['data']['contentMd5'] ) ) {
|
||||
$request = $this->addMd5( $request );
|
||||
}
|
||||
if ( isset( $operation['parameters']['ContentMD5'] ) &&
|
||||
isset( $command['ContentMD5'] ) ) {
|
||||
$value = $command['ContentMD5'];
|
||||
if ( $value === true ) {
|
||||
$request = $this->addMd5( $request );
|
||||
}
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
// add meta
|
||||
|
||||
public function metadataTransformer( CommandInterface $command, $request ) {
|
||||
$operation = $this->operation;
|
||||
if ( isset( $command['Metadata'] ) ) {
|
||||
$meta = $command['Metadata'];
|
||||
foreach ( $meta as $key => $value ) {
|
||||
$request = $request->withHeader( 'x-cos-meta-' . $key, $value );
|
||||
}
|
||||
}
|
||||
$request = headersMap( $command, $request );
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
// count md5
|
||||
|
||||
private function addMd5( $request ) {
|
||||
$body = $request->getBody();
|
||||
if ( $body && $body->getSize() > 0 ) {
|
||||
$md5 = base64_encode( md5( $body, true ) );
|
||||
return $request->withHeader( 'Content-MD5', $md5 );
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
// inventoryId
|
||||
|
||||
public function specialParamTransformer( CommandInterface $command, $request ) {
|
||||
$action = $command->getName();
|
||||
if ( $action == 'PutBucketInventory' ) {
|
||||
$id = $command['Id'];
|
||||
$uri = $request->getUri();
|
||||
$query = $uri->getQuery();
|
||||
$uri = $uri->withQuery( $query . '&Id='.$id );
|
||||
return $request->withUri( $uri );
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
}
|
||||
|
||||
}
|
||||
55
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Common.php
vendored
Normal file
55
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Common.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
function region_map( $region ) {
|
||||
$regionmap = array( 'cn-east'=>'ap-shanghai',
|
||||
'cn-south'=>'ap-guangzhou',
|
||||
'cn-north'=>'ap-beijing-1',
|
||||
'cn-south-2'=>'ap-guangzhou-2',
|
||||
'cn-southwest'=>'ap-chengdu',
|
||||
'sg'=>'ap-singapore',
|
||||
'tj'=>'ap-beijing-1',
|
||||
'bj'=>'ap-beijing',
|
||||
'sh'=>'ap-shanghai',
|
||||
'gz'=>'ap-guangzhou',
|
||||
'cd'=>'ap-chengdu',
|
||||
'sgp'=>'ap-singapore' );
|
||||
if ( array_key_exists( $region, $regionmap ) ) {
|
||||
return $regionmap[$region];
|
||||
}
|
||||
return $region;
|
||||
}
|
||||
|
||||
function encodeKey( $key ) {
|
||||
return str_replace( '%2F', '/', rawurlencode( $key ) );
|
||||
}
|
||||
|
||||
function endWith( $haystack, $needle ) {
|
||||
$length = strlen( $needle );
|
||||
if ( $length == 0 ) {
|
||||
return true;
|
||||
}
|
||||
return ( substr( $haystack, -$length ) === $needle );
|
||||
}
|
||||
|
||||
function startWith( $haystack, $needle ) {
|
||||
$length = strlen( $needle );
|
||||
if ( $length == 0 ) {
|
||||
return true;
|
||||
}
|
||||
return ( substr( $haystack, $length ) === $needle );
|
||||
}
|
||||
|
||||
function headersMap( $command, $request ) {
|
||||
$headermap = array(
|
||||
'TransferEncoding'=>'Transfer-Encoding',
|
||||
'ChannelId'=>'x-cos-channel-id'
|
||||
);
|
||||
foreach ( $headermap as $key => $value ) {
|
||||
if ( isset( $command[$key] ) ) {
|
||||
$request = $request->withHeader( $value, $command[$key] );
|
||||
}
|
||||
}
|
||||
return $request;
|
||||
}
|
||||
141
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Copy.php
vendored
Normal file
141
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Copy.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Pool;
|
||||
|
||||
class Copy {
|
||||
const MIN_PART_SIZE = 1048576;
|
||||
const MAX_PART_SIZE = 5368709120;
|
||||
const DEFAULT_PART_SIZE = 52428800;
|
||||
const MAX_PARTS = 10000;
|
||||
|
||||
private $client;
|
||||
private $copySource;
|
||||
private $options;
|
||||
private $partSize;
|
||||
private $parts;
|
||||
private $size;
|
||||
private $commandList = [];
|
||||
private $requestList = [];
|
||||
|
||||
public function __construct($client, $source, $options = array()) {
|
||||
$minPartSize = $options['PartSize'];
|
||||
unset($options['PartSize']);
|
||||
$this->client = $client;
|
||||
$this->copySource = $source;
|
||||
$this->options = $options;
|
||||
$this->size = $source['ContentLength'];
|
||||
unset($source['ContentLength']);
|
||||
$this->partSize = $this->calculatePartSize($minPartSize);
|
||||
$this->concurrency = isset($options['Concurrency']) ? $options['Concurrency'] : 10;
|
||||
$this->retry = isset($options['Retry']) ? $options['Retry'] : 5;
|
||||
}
|
||||
public function copy() {
|
||||
$uploadId= $this->initiateMultipartUpload();
|
||||
for ($i = 0; $i < $this->retry; $i += 1) {
|
||||
$rt = $this->uploadParts($uploadId);
|
||||
if ($rt == 0) {
|
||||
break;
|
||||
}
|
||||
sleep(1 << $i);
|
||||
}
|
||||
foreach ( $this->parts as $key => $row ){
|
||||
$num1[$key] = $row ['PartNumber'];
|
||||
$num2[$key] = $row ['ETag'];
|
||||
}
|
||||
array_multisort($num1, SORT_ASC, $num2, SORT_ASC, $this->parts);
|
||||
return $this->client->completeMultipartUpload(array(
|
||||
'Bucket' => $this->options['Bucket'],
|
||||
'Key' => $this->options['Key'],
|
||||
'UploadId' => $uploadId,
|
||||
'Parts' => $this->parts)
|
||||
);
|
||||
|
||||
}
|
||||
public function uploadParts($uploadId) {
|
||||
$copyRequests = function ($uploadId) {
|
||||
$offset = 0;
|
||||
$partNumber = 1;
|
||||
$partSize = $this->partSize;
|
||||
$finishedNum = 0;
|
||||
$this->parts = array();
|
||||
for ($index = 1; ; $index ++) {
|
||||
if ($offset + $partSize >= $this->size)
|
||||
{
|
||||
$partSize = $this->size - $offset;
|
||||
}
|
||||
$copySourcePath = $this->copySource['Bucket']. '.cos.'. $this->copySource['Region'].
|
||||
".myqcloud.com/". $this->copySource['Key']. "?versionId=". $this->copySource['VersionId'];
|
||||
$params = array(
|
||||
'Bucket' => $this->options['Bucket'],
|
||||
'Key' => $this->options['Key'],
|
||||
'UploadId' => $uploadId,
|
||||
'PartNumber' => $partNumber,
|
||||
'CopySource'=> $copySourcePath,
|
||||
'CopySourceRange' => 'bytes='.((string)$offset).'-'.(string)($offset+$partSize - 1),
|
||||
);
|
||||
if(!isset($this->parts[$partNumber])) {
|
||||
$command = $this->client->getCommand('uploadPartCopy', $params);
|
||||
$request = $this->client->commandToRequestTransformer($command);
|
||||
$this->commandList[$index] = $command;
|
||||
$this->requestList[$index] = $request;
|
||||
yield $request;
|
||||
}
|
||||
++$partNumber;
|
||||
$offset += $partSize;
|
||||
if ($this->size == $offset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
$pool = new Pool($this->client->httpClient, $copyRequests($uploadId), [
|
||||
'concurrency' => $this->concurrency,
|
||||
'fulfilled' => function ($response, $index) {
|
||||
$index = $index + 1;
|
||||
$response = $this->client->responseToResultTransformer($response, $this->requestList[$index], $this->commandList[$index]);
|
||||
$part = array('PartNumber' => $index, 'ETag' => $response['ETag']);
|
||||
$this->parts[$index] = $part;
|
||||
},
|
||||
|
||||
'rejected' => function ($reason, $index) {
|
||||
$index = $index += 1;
|
||||
$retry = 2;
|
||||
for ($i = 1; $i <= $retry; $i++) {
|
||||
try {
|
||||
$rt =$this->client->execute($this->commandList[$index]);
|
||||
$part = array('PartNumber' => $index, 'ETag' => $rt['ETag']);
|
||||
$this->parts[$index] = $part;
|
||||
} catch(\Exception $e) {
|
||||
if ($i == $retry) {
|
||||
throw($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
]);
|
||||
|
||||
// Initiate the transfers and create a promise
|
||||
$promise = $pool->promise();
|
||||
|
||||
// Force the pool of requests to complete.
|
||||
$promise->wait();
|
||||
}
|
||||
|
||||
|
||||
private function calculatePartSize($minPartSize)
|
||||
{
|
||||
$partSize = intval(ceil(($this->size / self::MAX_PARTS)));
|
||||
$partSize = max($minPartSize, $partSize);
|
||||
$partSize = min($partSize, self::MAX_PART_SIZE);
|
||||
$partSize = max($partSize, self::MIN_PART_SIZE);
|
||||
return $partSize;
|
||||
}
|
||||
|
||||
private function initiateMultipartUpload() {
|
||||
$result = $this->client->createMultipartUpload($this->options);
|
||||
return $result['UploadId'];
|
||||
}
|
||||
|
||||
}
|
||||
7
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Exception/CosException.php
vendored
Normal file
7
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Exception/CosException.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos\Exception;
|
||||
|
||||
use Qcloud\Cos\Exception\ServiceResponseException;
|
||||
|
||||
class CosException extends ServiceResponseException {}
|
||||
189
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Exception/ServiceResponseException.php
vendored
Normal file
189
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Exception/ServiceResponseException.php
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos\Exception;
|
||||
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class ServiceResponseException extends \RuntimeException {
|
||||
|
||||
/**
|
||||
* @var Response Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var RequestInterface Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var string Request ID
|
||||
*/
|
||||
protected $requestId;
|
||||
|
||||
/**
|
||||
* @var string Exception type (client / server)
|
||||
*/
|
||||
protected $exceptionType;
|
||||
|
||||
/**
|
||||
* @var string Exception code
|
||||
*/
|
||||
protected $exceptionCode;
|
||||
|
||||
/**
|
||||
* Set the exception code
|
||||
*
|
||||
* @param string $code Exception code
|
||||
*/
|
||||
public function setExceptionCode($code) {
|
||||
$this->exceptionCode = $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception code
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExceptionCode() {
|
||||
return $this->exceptionCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exception type
|
||||
*
|
||||
* @param string $type Exception type
|
||||
*/
|
||||
public function setExceptionType($type) {
|
||||
$this->exceptionType = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception type (one of client or server)
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExceptionType() {
|
||||
return $this->exceptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the request ID
|
||||
*
|
||||
* @param string $id Request ID
|
||||
*/
|
||||
public function setRequestId($id) {
|
||||
$this->requestId = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Request ID
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRequestId() {
|
||||
return $this->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the associated response
|
||||
*
|
||||
* @param Response $response Response
|
||||
*/
|
||||
public function setResponse(ResponseInterface $response) {
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated response object
|
||||
*
|
||||
* @return Response|null
|
||||
*/
|
||||
public function getResponse() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the associated request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
*/
|
||||
public function setRequest(RequestInterface $request) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated request object
|
||||
*
|
||||
* @return RequestInterface|null
|
||||
*/
|
||||
public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status code of the response
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getStatusCode() {
|
||||
return $this->response ? $this->response->getStatusCode() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast to a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
$message = get_class($this) . ': '
|
||||
. 'Cos Error Code: ' . $this->getExceptionCode() . ', '
|
||||
. 'Status Code: ' . $this->getStatusCode() . ', '
|
||||
. 'Cos Request ID: ' . $this->getRequestId() . ', '
|
||||
. 'Cos Error Type: ' . $this->getExceptionType() . ', '
|
||||
. 'Cos Error Message: ' . $this->getMessage();
|
||||
|
||||
// Add the User-Agent if available
|
||||
if ($this->request) {
|
||||
$message .= ', ' . 'User-Agent: ' . $this->request->getHeader('User-Agent')[0];
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request ID of the error. This value is only present if a
|
||||
* response was received, and is not present in the event of a networking
|
||||
* error.
|
||||
*
|
||||
* Same as `getRequestId()` method, but matches the interface for SDKv3.
|
||||
*
|
||||
* @return string|null Returns null if no response was received
|
||||
*/
|
||||
public function getCosRequestId() {
|
||||
return $this->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Cos error type.
|
||||
*
|
||||
* Same as `getExceptionType()` method, but matches the interface for SDKv3.
|
||||
*
|
||||
* @return string|null Returns null if no response was received
|
||||
*/
|
||||
public function getCosErrorType() {
|
||||
return $this->exceptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Cos error code.
|
||||
*
|
||||
* Same as `getExceptionCode()` method, but matches the interface for SDKv3.
|
||||
*
|
||||
* @return string|null Returns null if no response was received
|
||||
*/
|
||||
public function getCosErrorCode() {
|
||||
return $this->exceptionCode;
|
||||
}
|
||||
}
|
||||
72
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/ExceptionMiddleware.php
vendored
Normal file
72
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/ExceptionMiddleware.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use Qcloud\Cos\Exception\ServiceResponseException;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\Psr7;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
|
||||
class ExceptionMiddleware {
|
||||
private $nextHandler;
|
||||
protected $parser;
|
||||
protected $defaultException;
|
||||
|
||||
/**
|
||||
* @param callable $nextHandler Next handler to invoke.
|
||||
*/
|
||||
public function __construct(callable $nextHandler) {
|
||||
$this->nextHandler = $nextHandler;
|
||||
$this->parser = new ExceptionParser();
|
||||
$this->defaultException = 'Qcloud\Cos\Exception\ServiceResponseException';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @param array $options
|
||||
*
|
||||
* @return PromiseInterface
|
||||
*/
|
||||
public function __invoke(RequestInterface $request, array $options) {
|
||||
$fn = $this->nextHandler;
|
||||
return $fn($request, $options)->then(
|
||||
function (ResponseInterface $response) use ($request) {
|
||||
return $this->handle($request, $response);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function handle(RequestInterface $request, ResponseInterface $response) {
|
||||
$code = $response->getStatusCode();
|
||||
if ($code < 400) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
//throw RequestException::create($request, $response);
|
||||
$parts = $this->parser->parse($request, $response);
|
||||
|
||||
$className = 'Qcloud\\Cos\\Exception\\' . $parts['code'];
|
||||
if (substr($className, -9) !== 'Exception') {
|
||||
$className .= 'Exception';
|
||||
}
|
||||
|
||||
$className = class_exists($className) ? $className : $this->defaultException;
|
||||
|
||||
throw $this->createException($className, $request, $response, $parts);
|
||||
}
|
||||
|
||||
protected function createException($className, RequestInterface $request, ResponseInterface $response, array $parts) {
|
||||
$class = new $className($parts['message']);
|
||||
|
||||
if ($class instanceof ServiceResponseException) {
|
||||
$class->setExceptionCode($parts['code']);
|
||||
$class->setExceptionType($parts['type']);
|
||||
$class->setResponse($response);
|
||||
$class->setRequest($request);
|
||||
$class->setRequestId($parts['request_id']);
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
112
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/ExceptionParser.php
vendored
Normal file
112
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/ExceptionParser.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Parses default XML exception responses
|
||||
*/
|
||||
class ExceptionParser {
|
||||
|
||||
public function parse(RequestInterface $request, ResponseInterface $response) {
|
||||
$data = array(
|
||||
'code' => null,
|
||||
'message' => null,
|
||||
//'type' => $response->isClientError() ? 'client' : 'server',
|
||||
'type' => 'client',
|
||||
'request_id' => null,
|
||||
'parsed' => null
|
||||
);
|
||||
|
||||
$body = strval($response->getBody());
|
||||
|
||||
if (empty($body)) {
|
||||
$this->parseHeaders($request, $response, $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
try {
|
||||
$xml = new \SimpleXMLElement(utf8_encode($body));
|
||||
$this->parseBody($xml, $data);
|
||||
return $data;
|
||||
} catch (\Exception $e) {
|
||||
$data['code'] = 'PhpInternalXmlParseError';
|
||||
$data['message'] = 'A non-XML response was received';
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses additional exception information from the response headers
|
||||
*
|
||||
* @param RequestInterface $request Request that was issued
|
||||
* @param Response $response The response from the request
|
||||
* @param array $data The current set of exception data
|
||||
*/
|
||||
protected function parseHeaders(RequestInterface $request, ResponseInterface $response, array &$data) {
|
||||
$data['message'] = $response->getStatusCode() . ' ' . $response->getReasonPhrase();
|
||||
$requestId = $response->getHeader('x-cos-request-id');
|
||||
if (isset($requestId[0])) {
|
||||
$requestId = $requestId[0];
|
||||
$data['request_id'] = $requestId;
|
||||
$data['message'] .= " (Request-ID: $requestId)";
|
||||
}
|
||||
|
||||
// Get the request
|
||||
$status = $response->getStatusCode();
|
||||
$method = $request->getMethod();
|
||||
|
||||
// Attempt to determine code for 403s and 404s
|
||||
if ($status === 403) {
|
||||
$data['code'] = 'AccessDenied';
|
||||
} elseif ($method === 'HEAD' && $status === 404) {
|
||||
$path = explode('/', trim($request->getUri()->getPath(), '/'));
|
||||
$host = explode('.', $request->getUri()->getHost());
|
||||
$bucket = (count($host) >= 4) ? $host[0] : array_shift($path);
|
||||
$object = array_shift($path);
|
||||
|
||||
if ($bucket && $object) {
|
||||
$data['code'] = 'NoSuchKey';
|
||||
} elseif ($bucket) {
|
||||
$data['code'] = 'NoSuchBucket';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses additional exception information from the response body
|
||||
*
|
||||
* @param \SimpleXMLElement $body The response body as XML
|
||||
* @param array $data The current set of exception data
|
||||
*/
|
||||
protected function parseBody(\SimpleXMLElement $body, array &$data) {
|
||||
$data['parsed'] = $body;
|
||||
|
||||
$namespaces = $body->getDocNamespaces();
|
||||
if (isset($namespaces[''])) {
|
||||
// Account for the default namespace being defined and PHP not being able to handle it :(
|
||||
$body->registerXPathNamespace('ns', $namespaces['']);
|
||||
$prefix = 'ns:';
|
||||
} else {
|
||||
$prefix = '';
|
||||
}
|
||||
|
||||
if ($tempXml = $body->xpath("//{$prefix}Code[1]")) {
|
||||
$data['code'] = (string) $tempXml[0];
|
||||
}
|
||||
|
||||
if ($tempXml = $body->xpath("//{$prefix}Message[1]")) {
|
||||
$data['message'] = (string) $tempXml[0];
|
||||
}
|
||||
|
||||
$tempXml = $body->xpath("//{$prefix}RequestId[1]");
|
||||
if (empty($tempXml)) {
|
||||
$tempXml = $body->xpath("//{$prefix}RequestID[1]");
|
||||
}
|
||||
if (isset($tempXml[0])) {
|
||||
$data['request_id'] = (string) $tempXml[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
136
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/MultipartUpload.php
vendored
Normal file
136
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/MultipartUpload.php
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use Qcloud\Cos\Exception\CosException;
|
||||
use GuzzleHttp\Pool;
|
||||
|
||||
class MultipartUpload {
|
||||
const MIN_PART_SIZE = 1048576;
|
||||
const MAX_PART_SIZE = 5368709120;
|
||||
const DEFAULT_PART_SIZE = 52428800;
|
||||
const MAX_PARTS = 10000;
|
||||
|
||||
private $client;
|
||||
private $options;
|
||||
private $partSize;
|
||||
private $parts;
|
||||
private $body;
|
||||
|
||||
public function __construct($client, $body, $options = array()) {
|
||||
$minPartSize = $options['PartSize'];
|
||||
unset($options['PartSize']);
|
||||
$this->body = $body;
|
||||
$this->client = $client;
|
||||
$this->options = $options;
|
||||
$this->partSize = $this->calculatePartSize($minPartSize);
|
||||
$this->concurrency = isset($options['Concurrency']) ? $options['Concurrency'] : 10;
|
||||
$this->parts = [];
|
||||
$this->partNumberList = [];
|
||||
}
|
||||
public function performUploading() {
|
||||
$uploadId= $this->initiateMultipartUpload();
|
||||
$this->uploadParts($uploadId);
|
||||
foreach ( $this->parts as $key => $row ){
|
||||
$num1[$key] = $row ['PartNumber'];
|
||||
$num2[$key] = $row ['ETag'];
|
||||
}
|
||||
array_multisort($num1, SORT_ASC, $num2, SORT_ASC, $this->parts);
|
||||
return $this->client->completeMultipartUpload(array(
|
||||
'Bucket' => $this->options['Bucket'],
|
||||
'Key' => $this->options['Key'],
|
||||
'UploadId' => $uploadId,
|
||||
'Parts' => $this->parts)
|
||||
);
|
||||
|
||||
}
|
||||
public function uploadParts($uploadId) {
|
||||
$uploadRequests = function ($uploadId) {
|
||||
$partNumber = 1;
|
||||
$index = 1;
|
||||
for ( ; ; $partNumber ++) {
|
||||
if ($this->body->eof()) {
|
||||
break;
|
||||
}
|
||||
$body = $this->body->read($this->partSize);
|
||||
if (empty($body)) {
|
||||
break;
|
||||
}
|
||||
if (isset($this->parts[$partNumber])) {
|
||||
continue;
|
||||
}
|
||||
$this->partNumberList[$index] = $partNumber;
|
||||
$params = array(
|
||||
'Bucket' => $this->options['Bucket'],
|
||||
'Key' => $this->options['Key'],
|
||||
'UploadId' => $uploadId,
|
||||
'PartNumber' => $partNumber,
|
||||
'Body' => $body
|
||||
);
|
||||
if(!isset($this->parts[$partNumber])) {
|
||||
$command = $this->client->getCommand('uploadPart', $params);
|
||||
$request = $this->client->commandToRequestTransformer($command);
|
||||
$index ++;
|
||||
yield $request;
|
||||
}
|
||||
}
|
||||
};
|
||||
$pool = new Pool($this->client->httpClient, $uploadRequests($uploadId), [
|
||||
'concurrency' => $this->concurrency,
|
||||
'fulfilled' => function ($response, $index) {
|
||||
$index = $index + 1;
|
||||
$partNumber = $this->partNumberList[$index];
|
||||
$etag = $response->getHeaders()["ETag"][0];
|
||||
$part = array('PartNumber' => $partNumber, 'ETag' => $etag);
|
||||
$this->parts[$partNumber] = $part;
|
||||
},
|
||||
|
||||
'rejected' => function ($reason, $index) {
|
||||
throw($reason);
|
||||
}
|
||||
]);
|
||||
$promise = $pool->promise();
|
||||
$promise->wait();
|
||||
}
|
||||
|
||||
public function resumeUploading() {
|
||||
$uploadId = $this->options['UploadId'];
|
||||
$rt = $this->client->ListParts(
|
||||
array('UploadId' => $uploadId,
|
||||
'Bucket'=>$this->options['Bucket'],
|
||||
'Key'=>$this->options['Key']));
|
||||
$parts = array();
|
||||
if (count($rt['Parts']) > 0) {
|
||||
foreach ($rt['Parts'] as $part) {
|
||||
$this->parts[$part['PartNumber']] = array('PartNumber' => $part['PartNumber'], 'ETag' => $part['ETag']);
|
||||
}
|
||||
}
|
||||
$this->uploadParts($uploadId);
|
||||
foreach ( $this->parts as $key => $row ){
|
||||
$num1[$key] = $row ['PartNumber'];
|
||||
$num2[$key] = $row ['ETag'];
|
||||
}
|
||||
array_multisort($num1, SORT_ASC, $num2, SORT_ASC, $this->parts);
|
||||
return $this->client->completeMultipartUpload(array(
|
||||
'Bucket' => $this->options['Bucket'],
|
||||
'Key' => $this->options['Key'],
|
||||
'UploadId' => $uploadId,
|
||||
'Parts' => $this->parts)
|
||||
);
|
||||
}
|
||||
|
||||
private function calculatePartSize($minPartSize)
|
||||
{
|
||||
$partSize = intval(ceil(($this->body->getSize() / self::MAX_PARTS)));
|
||||
$partSize = max($minPartSize, $partSize);
|
||||
$partSize = min($partSize, self::MAX_PART_SIZE);
|
||||
$partSize = max($partSize, self::MIN_PART_SIZE);
|
||||
return $partSize;
|
||||
}
|
||||
|
||||
private function initiateMultipartUpload() {
|
||||
$result = $this->client->createMultipartUpload($this->options);
|
||||
return $result['UploadId'];
|
||||
}
|
||||
|
||||
}
|
||||
49
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Request/BodyLocation.php
vendored
Normal file
49
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Request/BodyLocation.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos\Request;
|
||||
|
||||
use GuzzleHttp\Command\Guzzle\RequestLocation\AbstractLocation;
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use GuzzleHttp\Command\Guzzle\Parameter;
|
||||
use GuzzleHttp\Psr7;
|
||||
use Psr\Http\Message\MessageInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Adds a raw/binary body to a request.
|
||||
* This is here because: https://github.com/guzzle/guzzle-services/issues/160
|
||||
*/
|
||||
class BodyLocation extends AbstractLocation
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the name of the location
|
||||
*
|
||||
* @param string $locationName
|
||||
*/
|
||||
public function __construct($locationName = 'body')
|
||||
{
|
||||
parent::__construct($locationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
* @param Parameter $param
|
||||
*
|
||||
* @return MessageInterface
|
||||
*/
|
||||
public function visit(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request,
|
||||
Parameter $param
|
||||
) {
|
||||
$value = $request->getBody()->getContents();
|
||||
if ('' !== $value) {
|
||||
throw new \RuntimeException('Only one "body" location may exist per operation');
|
||||
}
|
||||
// binary string data from bound parameter
|
||||
$value = $command[$param->getName()];
|
||||
return $request->withBody(Psr7\stream_for($value));
|
||||
}
|
||||
}
|
||||
127
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/ResultTransformer.php
vendored
Normal file
127
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/ResultTransformer.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use Guzzle\Service\Description\Parameter;
|
||||
use Guzzle\Service\Description\ServiceDescription;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Qcloud\Cos\Signature;
|
||||
use GuzzleHttp\Command\Guzzle\Description;
|
||||
use GuzzleHttp\Command\Guzzle\GuzzleClient;
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Middleware;
|
||||
use GuzzleHttp\Psr7;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use GuzzleHttp\Command\Result;
|
||||
use InvalidArgumentException;
|
||||
|
||||
|
||||
class ResultTransformer {
|
||||
private $config;
|
||||
private $operation;
|
||||
|
||||
public function __construct($config, $operation) {
|
||||
$this->config = $config;
|
||||
$this->operation = $operation;
|
||||
}
|
||||
|
||||
public function writeDataToLocal(CommandInterface $command, RequestInterface $request, ResponseInterface $response) {
|
||||
$action = $command->getName();
|
||||
if ($action == "GetObject") {
|
||||
if (isset($command['SaveAs'])) {
|
||||
$fp = fopen($command['SaveAs'], "wb");
|
||||
$stream = $response->getBody();
|
||||
$offset = 0;
|
||||
$partsize = 8192;
|
||||
while (!$stream->eof()) {
|
||||
$output = $stream->read($partsize);
|
||||
fseek($fp, $offset);
|
||||
fwrite($fp, $output);
|
||||
$offset += $partsize;
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function metaDataTransformer(CommandInterface $command, ResponseInterface $response, Result $result) {
|
||||
$headers = $response->getHeaders();
|
||||
$metadata = array();
|
||||
foreach ($headers as $key => $value) {
|
||||
if (strpos($key, "x-cos-meta-") === 0) {
|
||||
$metadata[substr($key, 11)] = $value[0];
|
||||
}
|
||||
}
|
||||
if (!empty($metadata)) {
|
||||
$result['Metadata'] = $metadata;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function extraHeadersTransformer(CommandInterface $command, RequestInterface $request, Result $result) {
|
||||
if ($command['Key'] != null && $result['Key'] == null) {
|
||||
$result['Key'] = $command['Key'];
|
||||
}
|
||||
if ($command['Bucket'] != null && $result['Bucket'] == null) {
|
||||
$result['Bucket'] = $command['Bucket'];
|
||||
}
|
||||
$result['Location'] = $request->getHeader("Host")[0] . $request->getUri()->getPath();
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function selectContentTransformer(CommandInterface $command, Result $result) {
|
||||
$action = $command->getName();
|
||||
if ($action == "SelectObjectContent") {
|
||||
$result['Data'] = $this->getSelectContents($result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getSelectContents($result) {
|
||||
$f = $result['RawData'];
|
||||
while (!$f->eof()) {
|
||||
$data = array();
|
||||
$tmp = $f->read(4);
|
||||
if (empty($tmp)) {
|
||||
break;
|
||||
}
|
||||
$totol_length = (int)(unpack("N", $tmp)[1]);
|
||||
$headers_length = (int)(unpack("N", $f->read(4))[1]);
|
||||
$body_length = $totol_length - $headers_length - 16;
|
||||
$predule_crc = (int)(unpack("N", $f->read(4))[1]);
|
||||
$headers = array();
|
||||
for ($offset = 0; $offset < $headers_length;) {
|
||||
$key_length = (int)(unpack("C", $f->read(1))[1]);
|
||||
$key = $f->read($key_length);
|
||||
|
||||
$head_value_type = (int)(unpack("C", $f->read(1))[1]);
|
||||
|
||||
$value_length = (int)(unpack("n", $f->read(2))[1]);
|
||||
$value = $f->read($value_length);
|
||||
$offset += 4 + $key_length + $value_length;
|
||||
if ($key == ":message-type") {
|
||||
$data['MessageType'] = $value;
|
||||
}
|
||||
if ($key == ":event-type") {
|
||||
$data['EventType'] = $value;
|
||||
}
|
||||
if ($key == ":error-code") {
|
||||
$data['ErrorCode'] = $value;
|
||||
}
|
||||
if ($key == ":error-message") {
|
||||
$data['ErrorMessage'] = $value;
|
||||
}
|
||||
}
|
||||
$body = $f->read($body_length);
|
||||
$message_crc = (int)(unpack("N", $f->read(4))[1]);
|
||||
$data['Body'] = $body;
|
||||
yield $data;
|
||||
}
|
||||
}
|
||||
public function __destruct() {
|
||||
}
|
||||
|
||||
}
|
||||
79
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Serializer.php
vendored
Normal file
79
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Serializer.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace Qcloud\Cos;
|
||||
use GuzzleHttp\Command\CommandInterface;
|
||||
use GuzzleHttp\Command\Guzzle\SchemaValidator;
|
||||
use GuzzleHttp\Command\Guzzle\DescriptionInterface;
|
||||
use GuzzleHttp\Command\Guzzle\Serializer as DefaultSerializer;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
/**
|
||||
* Override Request serializer to modify authentication mechanism
|
||||
*/
|
||||
class Serializer extends DefaultSerializer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(
|
||||
DescriptionInterface $description,
|
||||
array $requestLocations = []
|
||||
) {
|
||||
// Override Guzzle's body location as it isn't raw binary data
|
||||
$requestLocations['body'] = new Request\BodyLocation;
|
||||
parent::__construct($description, $requestLocations);
|
||||
}
|
||||
/**
|
||||
* Authorization header is Loco's preferred authorization method.
|
||||
* Add Authorization header to request if API key is set, unless query is explicitly configured as auth method.
|
||||
* Unset key from command to avoid sending it as a query param.
|
||||
*
|
||||
* @override
|
||||
*
|
||||
* @param CommandInterface $command
|
||||
* @param RequestInterface $request
|
||||
*
|
||||
* @return RequestInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function prepareRequest(
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) {
|
||||
/*
|
||||
if ($command->offsetExists('key') === true) {
|
||||
$mode = empty($command->offsetGet('auth')) === false
|
||||
? $command->offsetGet('auth')
|
||||
: 'loco';
|
||||
if ($mode !== 'query') {
|
||||
// else use Authorization header of various types
|
||||
if ($mode === 'loco') {
|
||||
$value = 'Loco '.$command->offsetGet('key');
|
||||
$request = $request->withHeader('Authorization', $value);
|
||||
} elseif ($mode === 'basic') {
|
||||
$value = 'Basic '.base64_encode($command->offsetGet('key').':');
|
||||
$request = $request->withHeader('Authorization', $value);
|
||||
} else {
|
||||
throw new \InvalidArgumentException("Invalid auth type: {$mode}");
|
||||
}
|
||||
// avoid request sending key parameter in query string
|
||||
$command->offsetUnset('key');
|
||||
}
|
||||
}
|
||||
// Remap legacy parameters to common `data` binding on request body
|
||||
static $remap = [
|
||||
'import' => ['src'=>'data'],
|
||||
'translate' => ['translation'=>'data'],
|
||||
];
|
||||
$name = $command->getName();
|
||||
if (isset($remap[$name])) {
|
||||
foreach ($remap[$name] as $old => $new) {
|
||||
if ($command->offsetExists($old)) {
|
||||
$command->offsetSet($new, $command->offsetGet($old));
|
||||
$command->offsetUnset($old);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
return parent::prepareRequest($command, $request);
|
||||
}
|
||||
}
|
||||
4843
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Service.php
vendored
Normal file
4843
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Service.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Signature.php
vendored
Normal file
103
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Signature.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
class Signature {
|
||||
private $accessKey;
|
||||
// string: access key.
|
||||
private $secretKey;
|
||||
// string: secret key.
|
||||
|
||||
public function __construct( $accessKey, $secretKey, $token = null ) {
|
||||
$this->accessKey = $accessKey;
|
||||
$this->secretKey = $secretKey;
|
||||
$this->token = $token;
|
||||
$this->signHeader = [
|
||||
'host',
|
||||
'content-type',
|
||||
'content-md5',
|
||||
'content-disposition',
|
||||
'content-encoding',
|
||||
'content-length',
|
||||
'transfer-encoding',
|
||||
'range',
|
||||
];
|
||||
date_default_timezone_set( 'PRC' );
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
}
|
||||
|
||||
public function needCheckHeader( $header ) {
|
||||
if ( startWith( $header, 'x-cos-' ) ) {
|
||||
return true;
|
||||
}
|
||||
if ( in_array( $header, $this->signHeader ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function signRequest( RequestInterface $request ) {
|
||||
$authorization = $this->createAuthorization( $request );
|
||||
return $request->withHeader( 'Authorization', $authorization );
|
||||
}
|
||||
|
||||
public function createAuthorization( RequestInterface $request, $expires = '+30 minutes' ) {
|
||||
if ( is_null( $expires ) ) {
|
||||
$expires = '+30 minutes';
|
||||
}
|
||||
$signTime = ( string )( time() - 60 ) . ';' . ( string )( strtotime( $expires ) );
|
||||
$urlParamListArray = [];
|
||||
foreach ( explode( '&', $request->getUri()->getQuery() ) as $query ) {
|
||||
if (!empty($query)) {
|
||||
$tmpquery = explode( '=', $query );
|
||||
$key = strtolower( $tmpquery[0] );
|
||||
if (count($tmpquery) >= 2) {
|
||||
$value = $tmpquery[1];
|
||||
} else {
|
||||
$value = "";
|
||||
}
|
||||
$urlParamListArray[$key] = $key. '='. $value;
|
||||
}
|
||||
}
|
||||
ksort($urlParamListArray);
|
||||
$urlParamList = join(';', array_keys($urlParamListArray));
|
||||
$httpParameters = join('&', array_values($urlParamListArray));
|
||||
|
||||
$headerListArray = [];
|
||||
foreach ( $request->getHeaders() as $key => $value ) {
|
||||
$key = strtolower( urlencode( $key ) );
|
||||
$value = urlencode( $value[0] );
|
||||
if ( $this->needCheckHeader( $key ) ) {
|
||||
$headerListArray[$key] = $key. '='. $value;
|
||||
}
|
||||
}
|
||||
ksort($headerListArray);
|
||||
$headerList = join(';', array_keys($headerListArray));
|
||||
$httpHeaders = join('&', array_values($headerListArray));
|
||||
$httpString = strtolower( $request->getMethod() ) . "\n" . urldecode( $request->getUri()->getPath() ) . "\n" . $httpParameters.
|
||||
"\n". $httpHeaders. "\n";
|
||||
$sha1edHttpString = sha1( $httpString );
|
||||
$stringToSign = "sha1\n$signTime\n$sha1edHttpString\n";
|
||||
$signKey = hash_hmac( 'sha1', $signTime, $this->secretKey );
|
||||
$signature = hash_hmac( 'sha1', $stringToSign, $signKey );
|
||||
$authorization = 'q-sign-algorithm=sha1&q-ak='. $this->accessKey .
|
||||
"&q-sign-time=$signTime&q-key-time=$signTime&q-header-list=$headerList&q-url-param-list=$urlParamList&" .
|
||||
"q-signature=$signature";
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
public function createPresignedUrl( RequestInterface $request, $expires = '+30 minutes' ) {
|
||||
$authorization = $this->createAuthorization( $request, $expires );
|
||||
$uri = $request->getUri();
|
||||
$query = 'sign='.urlencode( $authorization );
|
||||
if ( $this->token != null ) {
|
||||
$query = $query.'&x-cos-security-token='.$this->token;
|
||||
}
|
||||
$uri = $uri->withQuery( $query );
|
||||
return $uri;
|
||||
}
|
||||
}
|
||||
28
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/SignatureMiddleware.php
vendored
Normal file
28
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/SignatureMiddleware.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos;
|
||||
|
||||
use Qcloud\Cos\Exception\ServiceResponseException;
|
||||
use GuzzleHttp\Promise\PromiseInterface;
|
||||
use GuzzleHttp\Psr7;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
|
||||
class SignatureMiddleware {
|
||||
private $nextHandler;
|
||||
protected $signature;
|
||||
|
||||
/**
|
||||
* @param callable $nextHandler Next handler to invoke.
|
||||
*/
|
||||
public function __construct(callable $nextHandler, $accessKey, $secretKey) {
|
||||
$this->nextHandler = $nextHandler;
|
||||
$this->signature = new Signature($accessKey, $secretKey);
|
||||
}
|
||||
|
||||
public function __invoke(RequestInterface $request, array $options) {
|
||||
$fn = $this->nextHandler;
|
||||
return $fn($this->signature->signRequest($request), $options);
|
||||
}
|
||||
}
|
||||
1699
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/COSTest.php
vendored
Normal file
1699
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/COSTest.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
45
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/TestHelper.php
vendored
Normal file
45
vendor/qcloud/cos-sdk-v5/src/Qcloud/Cos/Tests/TestHelper.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Qcloud\Cos\Tests;
|
||||
|
||||
use Qcloud\Cos\Client;
|
||||
|
||||
class TestHelper {
|
||||
|
||||
public static function nuke($bucket) {
|
||||
try {
|
||||
$cosClient = new Client(array('region' => getenv('COS_REGION'),
|
||||
'credentials'=> array(
|
||||
'appId' => getenv('COS_APPID'),
|
||||
'secretId' => getenv('COS_KEY'),
|
||||
'secretKey' => getenv('COS_SECRET'))));
|
||||
$result = $cosClient->listObjects(array('Bucket' => $bucket));
|
||||
if (isset($result['Contents'])) {
|
||||
foreach ($result['Contents'] as $content) {
|
||||
$cosClient->deleteObject(array('Bucket' => $bucket, 'Key' => $content['Key']));
|
||||
}
|
||||
}
|
||||
|
||||
while(True){
|
||||
$result = $cosClient->ListMultipartUploads(
|
||||
array('Bucket' => $bucket));
|
||||
if (count($result['Uploads']) == 0){
|
||||
break;
|
||||
}
|
||||
foreach ($result['Uploads'] as $upload) {
|
||||
try {
|
||||
$rt = $cosClient->AbortMultipartUpload(
|
||||
array('Bucket' => $bucket,
|
||||
'Key' => $upload['Key'],
|
||||
'UploadId' => $upload['UploadId']));
|
||||
} catch (\Exception $e) {
|
||||
print_r($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
$cosClient->deleteBucket(array('Bucket' => $bucket));
|
||||
} catch (\Exception $e) {
|
||||
// echo "$e\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user