From 180660325b98856eddfb64e4d5a61a099caf451b Mon Sep 17 00:00:00 2001 From: sunjiapeng Date: Fri, 28 Apr 2023 17:14:25 +0800 Subject: [PATCH] update php sdk --- src/FDS/GalaxyFDS.php | 24 +++++++- src/FDS/GalaxyFDSClient.php | 89 ++++++++++++++++++++++++----- src/FDS/auth/Common.php | 5 +- src/FDS/auth/signature/Signer.php | 7 ++- src/FDS/model/FDSObjectMetadata.php | 15 +++-- tests/FDS/GalaxyFDSClientTest.php | 19 +++++- 6 files changed, 136 insertions(+), 23 deletions(-) diff --git a/src/FDS/GalaxyFDS.php b/src/FDS/GalaxyFDS.php index 9548d3b..791a6ba 100644 --- a/src/FDS/GalaxyFDS.php +++ b/src/FDS/GalaxyFDS.php @@ -309,6 +309,13 @@ public function setPublic($bucket_name, $object_name); */ public function initMultipartUpload($bucket_name, $object_name); + /** Init a multipart copy session + * @param $bucket_name + * @param $object_name + * @return mixed + */ + public function initMultipartUploadCopy($bucket_name, $object_name); + /** Upload a part * @param $bucket_name * @param $object_name @@ -320,6 +327,21 @@ public function initMultipartUpload($bucket_name, $object_name); public function uploadPart($bucket_name, $object_name, $upload_id, $part_number, $content); + /** Copy a part + * @param $bucket_name + * @param $object_name + * @param $upload_id + * @param $part_number + * @param $source_bucket_name + * @param $source_object_name + * @param $start_byte + * @param $end_byte + * @return mixed + */ + public function uploadPartCopy($bucket_name, $object_name, $upload_id, + $part_number, $source_bucket_name, $source_object_name, + $start_byte = null, $end_byte = null); + /** Complete the multipart upload * @param $bucket_name * @param $object_name @@ -362,4 +384,4 @@ public function generatePresignedUri($bucket_name, $object_name, $expiration, * @throws GalaxyFDSClientException */ public function generateDownloadObjectUri($bucket_name, $object_name); -} \ No newline at end of file +} diff --git a/src/FDS/GalaxyFDSClient.php b/src/FDS/GalaxyFDSClient.php index e2b6f73..ad012c1 100644 --- a/src/FDS/GalaxyFDSClient.php +++ b/src/FDS/GalaxyFDSClient.php @@ -570,7 +570,7 @@ public function generatePresignedUri($bucket_name, $object_name, $expiration, $this->credential->getGalaxyAccessSecret(), self::SIGN_ALGORITHM); $uri = $this->formatUri($base_uri, - urlencode($bucket_name) . "/" . urlencode($object_name), + $bucket_name . "/" . $object_name, Common::GALAXY_ACCESS_KEY_ID . "=" . $this->credential->getGalaxyAccessId(), Common::EXPIRES . "=" . $expiration, Common::SIGNATURE . "=" . $signature); @@ -614,8 +614,7 @@ private function prepareRequestHeader($uri, $http_method, $media_type, } // 3. Set authorization information - $sign_uri = substr($uri, strpos($uri, "/", strpos($uri, ":") +3)); - $signature = Signer::signToBase64($http_method, $sign_uri, $headers, + $signature = Signer::signToBase64($http_method, $uri, $headers, $this->credential->getGalaxyAccessSecret(), self::SIGN_ALGORITHM); $auth_string = "Galaxy-V2 " . $this->credential->getGalaxyAccessId() . ":" . $signature; @@ -633,12 +632,26 @@ private function formatUri() { $uri = ""; $args = func_get_args(); foreach ($args as $arg) { - if ($count == 0 || $count == 1) { + if ($count == 0) { + $uri .= $arg; + } else if ($count == 1) { + $arrArg = explode("/", $arg, 2); + if (count($arrArg) == 2) { + $arrArg[1] = str_replace('%2F', '/',rawurlencode($arrArg[1])); + $arg = implode("/", $arrArg); + } $uri .= $arg; - } else if ($count == 2) { - $uri .= "?" . $arg; } else { - $uri .= "&" . $arg; + $arrArg = explode("=", $arg, 2); + if (count($arrArg) == 2) { + $arrArg[1] = rawurlencode($arrArg[1]); + $arg = implode("=", $arrArg); + } + if ($count == 2) { + $uri .= "?" . $arg; + } else { + $uri .= "&" . $arg; + } } ++$count; } @@ -811,10 +824,31 @@ public function initMultipartUpload($bucket_name, $object_name) { } } + public function initMultipartUploadCopy($bucket_name, $object_name) { + $uri = $this->formatUri($this->fds_config->getBaseUri(), + $bucket_name . "/" . $object_name, SubResource::UPLOADS); + $metadata = new FDSObjectMetadata(); + $metadata->addHeader(Common::MULITPART_UPLOAD_MODE, 'MULTI_BLOB'); + $headers = $this->prepareRequestHeader($uri, Http::PUT, Mime::JSON, $metadata); + + $response = $this->invoke(Action::InitMultipartUpload, $uri, $headers, Http::PUT, + null, null); + + if ($response->code == self::HTTP_OK) { + $result = InitMultipartUploadResult::fromJson($response->body); + return $result; + } else { + $message = "Init multipart upload failed, status=" . $response->code . + ", reason=" . $response->raw_body; + $this->printResponse($response); + throw new GalaxyFDSClientException($message); + } + } + public function uploadPart($bucket_name, $object_name, $upload_id, $part_number, $content) { - $uri = $this->fds_config->getBaseUri() . $bucket_name . "/" . $object_name . - "?uploadId=" . $upload_id . "&partNumber=" . $part_number; + $uri = $this->formatUri($this->fds_config->getBaseUri(), + $bucket_name . "/" . $object_name, "uploadId=" . $upload_id, "partNumber=" . $part_number); $headers = $this->prepareRequestHeader($uri, Http::PUT, self::APPLICATION_OCTET_STREAM); @@ -832,10 +866,39 @@ public function uploadPart($bucket_name, $object_name, $upload_id, } } + public function uploadPartCopy($bucket_name, $object_name, $upload_id, + $part_number, $source_bucket_name, $source_object_name, + $start_byte = null, $end_byte = null) { + $uri = $this->formatUri($this->fds_config->getBaseUri(), + $bucket_name . "/" . $object_name, "uploadId=" . $upload_id, "partNumber=" . $part_number); + + $metadata = new FDSObjectMetadata(); + $metadata->addHeader(Common::COPY_SOURCE, '/' . $source_bucket_name . '/' . rawurlencode($source_object_name)); + if ($start_byte !== null && $end_byte !== null) { + $metadata->addHeader(Common::COPY_SOURCE_RANGE, 'bytes=' . $start_byte . '-' . $end_byte); + } + + $headers = $this->prepareRequestHeader($uri, Http::PUT, + self::APPLICATION_OCTET_STREAM, $metadata); + + $response = $this->invoke(Action::UploadPart, $uri, $headers, Http::PUT, + null, null); + + if ($response->code == self::HTTP_OK) { + $result = UploadPartResult::fromJson($response->body); + return $result; + } else { + $message = "Upload part failed, status=" . $response->code . + ", reason=" . $response->raw_body; + $this->printResponse($response); + throw new GalaxyFDSClientException($message); + } + } + public function completeMultipartUpload($bucket_name, $object_name, $upload_id, $metadata, $upload_part_result_list) { - $uri = $this->fds_config->getBaseUri() . $bucket_name . "/" . $object_name . - "?uploadId=" . $upload_id; + $uri = $this->formatUri($this->fds_config->getBaseUri(), + $bucket_name . "/" . $object_name, "uploadId=" . $upload_id); $headers = $this->prepareRequestHeader($uri, Http::PUT, self::APPLICATION_OCTET_STREAM, $metadata); $response = $this->invoke(Action::CompleteMultipartUpload, $uri, $headers, @@ -853,8 +916,8 @@ public function completeMultipartUpload($bucket_name, $object_name, } public function abortMultipartUpload($bucket_name, $object_name, $upload_id) { - $uri = $this->fds_config->getBaseUri() . $bucket_name . "/" . $object_name . - "?uploadId=" . $upload_id; + $uri = $this->formatUri($this->fds_config->getBaseUri(), + $bucket_name . "/" . $object_name, "uploadId=" . $upload_id); $headers = $this->prepareRequestHeader($uri, Http::DELETE, Mime::JSON); $response = $this->invoke(Action::AbortMultipartUpload, $uri, $headers, diff --git a/src/FDS/auth/Common.php b/src/FDS/auth/Common.php index ddf4e61..929e63f 100644 --- a/src/FDS/auth/Common.php +++ b/src/FDS/auth/Common.php @@ -32,7 +32,10 @@ abstract class Common { const CONTENT_ENCODING = "content-encoding"; const CONTENT_LENGTH = "content-length"; const LAST_MODIFIED = "last-modified"; + const MULITPART_UPLOAD_MODE = "x-xiaomi-multipart-upload-mode"; + const COPY_SOURCE = "x-xiaomi-copy-source"; + const COPY_SOURCE_RANGE = "x-xiaomi-copy-source-range"; const DEFAULT_FDS_SERVICE_BASE_URI = "http://files.fds.api.xiaomi.com/"; const DEFAULT_CDN_SERVICE_URI = "http://cdn.fds.api.xiaomi.com/"; -} \ No newline at end of file +} diff --git a/src/FDS/auth/signature/Signer.php b/src/FDS/auth/signature/Signer.php index c65283c..4bb0658 100644 --- a/src/FDS/auth/signature/Signer.php +++ b/src/FDS/auth/signature/Signer.php @@ -128,11 +128,14 @@ function ($matches) { static function canonicalizeResource($uri) { $result = ""; - $result .= self::mb_parse_url($uri)["path"]; + $result .= rawurldecode(self::mb_parse_url($uri)["path"]); // 1. Parse and sort subresource $sorted_params = array(); $query = parse_url($uri, PHP_URL_QUERY); + if (!$query) { + return $result; + } $params = array(); parse_str($query, $params); foreach ($params as $key => $value) { @@ -157,7 +160,7 @@ static function canonicalizeResource($uri) { } if (!(empty($value) && $value !== "0")) { - $result .= "=" . $value; + $result .= "=" . rawurldecode($value); } } } diff --git a/src/FDS/model/FDSObjectMetadata.php b/src/FDS/model/FDSObjectMetadata.php index 8e5ecea..3eec0a4 100644 --- a/src/FDS/model/FDSObjectMetadata.php +++ b/src/FDS/model/FDSObjectMetadata.php @@ -16,10 +16,17 @@ class FDSObjectMetadata { const USER_DEFINED_METADATA_PREFIX = "x-xiaomi-meta-"; static $PRE_DEFINED_METADATA = array( - Common::CACHE_CONTROL, Common::CONTENT_ENCODING, - Common::CONTENT_LENGTH, Common::CONTENT_MD5, - Common::CONTENT_TYPE, Common::LAST_MODIFIED + Common::CACHE_CONTROL, + Common::CONTENT_ENCODING, + Common::CONTENT_LENGTH, + Common::CONTENT_MD5, + Common::CONTENT_TYPE, + Common::LAST_MODIFIED, + Common::MULITPART_UPLOAD_MODE, + Common::COPY_SOURCE, + Common::COPY_SOURCE_RANGE, ); + private $metadata = array(); public function addHeader($key, $value) { @@ -125,4 +132,4 @@ private function startsWith($haystack, $needle) { $len = strlen($needle); return (substr($haystack, 0, $len) === $needle); } -} \ No newline at end of file +} diff --git a/tests/FDS/GalaxyFDSClientTest.php b/tests/FDS/GalaxyFDSClientTest.php index 8fbf517..6f2f7d6 100644 --- a/tests/FDS/GalaxyFDSClientTest.php +++ b/tests/FDS/GalaxyFDSClientTest.php @@ -22,8 +22,9 @@ use FDS\model\Permission; use FDS\model\UploadPartResultList; use Httpful\Request; +use PHPUnit\Framework\TestCase; -class GalaxyFDSClientTest extends \PHPUnit_Framework_TestCase { +class GalaxyFDSClientTest extends TestCase { private static $credential; private static $fds_client; @@ -33,7 +34,7 @@ public static function setUpBeforeClass() { $fdsConfig = new FDSClientConfiguration(); $fdsConfig->setEnableMd5Calculate(true); $fdsConfig->enableUnitTestMode(true); - $fdsConfig->setBaseUriforunittest("http://files.fds.api.xiaomi.com/"); + $fdsConfig->setBaseUriforunittest(BASE_URI_FOR_UNIT_TEST); self::$credential = new BasicFDSCredential(ACCESS_ID, ACCESS_SECRET); self::$fds_client = new GalaxyFDSClient(self::$credential, $fdsConfig); self::$bucket_name = "test-php-sdk-bucket-".substr(md5(rand()),0,7); @@ -450,6 +451,20 @@ public function testMultipartUpload() { $actualObjectContent = $object->getObjectContent(); $this->assertEquals($content, $actualObjectContent); $this->assertEquals("text/html", $object->getObjectMetadata()->getContentType()); + + //test multipart-upload-copy + $copyObjetName = "multipart-upload-copy"; + $initMultipartCopyResult = self::$fds_client->initMultipartUploadCopy(self::$bucket_name, $copyObjetName); + $copyPartResult = self::$fds_client->uploadPartCopy(self::$bucket_name, + $copyObjetName, $initMultipartCopyResult->getUploadId(), 1, self::$bucket_name, $object_name, 0, $object->getObjectSummary()->getSize() - 1); + $copyPartResultArray = array($copyPartResult); + $copyPartResultList = new UploadPartResultList(); + $copyPartResultList->setUploadPartResultList($copyPartResultArray); + self::$fds_client->completeMultipartUpload(self::$bucket_name, $copyObjetName, + $initMultipartCopyResult->getUploadId(), $metadata, $copyPartResultList); + $copyObject = self::$fds_client->getObject(self::$bucket_name, $copyObjetName); + $copyContent = $copyObject->getObjectContent(); + $this->assertEquals($actualObjectContent, $copyContent); } private static function emptyBucket() {