From 7731d38e6968639d317242c91652e421e4cee864 Mon Sep 17 00:00:00 2001 From: yangpeng <183851063@qq.com> Date: Thu, 12 Jan 2023 12:13:19 +0800 Subject: [PATCH] add crc64 security verification --- samples/ObjectCrc64.php | 273 +++++++++++++++++++ src/OSS/Core/OssUtil.php | 96 +++++++ src/OSS/Model/AppendInfo.php | 40 +++ src/OSS/OssClient.php | 66 ++++- src/OSS/Result/AppendResult.php | 7 +- tests/OSS/Tests/OssClientObjectCrc64Test.php | 234 ++++++++++++++++ tests/OSS/Tests/OssClientObjectTest.php | 24 +- 7 files changed, 722 insertions(+), 18 deletions(-) create mode 100644 samples/ObjectCrc64.php create mode 100644 src/OSS/Model/AppendInfo.php create mode 100644 tests/OSS/Tests/OssClientObjectCrc64Test.php diff --git a/samples/ObjectCrc64.php b/samples/ObjectCrc64.php new file mode 100644 index 00000000..92d7e210 --- /dev/null +++ b/samples/ObjectCrc64.php @@ -0,0 +1,273 @@ + true, +); +// Upload the in-memory string (hi, oss) to an OSS file +$object = "b.file"; +$content = file_get_contents($object); +$ossClient->putObject($bucket, $object, $content,$options); + +// Download an oss object as an in-memory variable +$ossClient->getObject($bucket, $object,$options); + +// Append Object +$object = "a.txt"; +$filePath = "D:\\localpath\\b.txt"; +$filePath1 = "D:\\localpath\\c.txt"; +$content = file_get_contents($filePath); +$result = $ossClient->appendObject($bucket, $object,$content,0,$options); +$content1 = file_get_contents($filePath1); +$options[OssClient::OSS_INIT_CRC64] = $result->getCrc(); +$result1 = $ossClient->appendObject($bucket, $object, $content1,$result->getPosition(),$options); +$localCrc64 = OssUtil::crc64($content.$content1); +print("append object: OK" . "\n"); + + +// Append File +$object = "a.txt"; +$filePath = "D:\\localpath\\b.txt"; +$filePath1 = "D:\\localpath\\c.txt"; +$result = $ossClient->appendFile($bucket, $filePath,$content,0,$options); +$options[OssClient::OSS_INIT_CRC64] = $result->getCrc(); +$result1 = $ossClient->appendObject($bucket, $object, $filePath1,$result->getPosition(),$options); +$localCrc64 = OssUtil::crc64($content.$content1); +print("append file: OK" . "\n"); + + +// Upload Object By multipart upload +$uploadFile = "test/multipart-test.txt"; +$object = "oss_test/object.txt"; + /** + * step 1. Initialize a block upload event, that is, a multipart upload process to get an upload id + */ +$uploadId = $ossClient->initiateMultipartUpload($bucket, $object); +/* + * step 2. Upload parts + */ +$partSize = 10 * 1024 * 1024; +$uploadFileSize = sprintf('%u',filesize($uploadFile)); +$pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize); +$responseUploadPart = array(); +$uploadPosition = 0; +$checkCrc64 = true; +foreach ($pieces as $i => $piece) { + $fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO]; + $toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1; + $upOptions = array( + $ossClient::OSS_FILE_UPLOAD => $uploadFile, + $ossClient::OSS_PART_NUM => ($i + 1), + $ossClient::OSS_SEEK_TO => $fromPos, + $ossClient::OSS_LENGTH => $toPos - $fromPos + 1, + $ossClient::OSS_CHECK_CRC64 => $checkCrc64, + ); + //2. Upload each part to OSS + $resultPart = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions); +} +$uploadParts = array(); +foreach ($responseUploadPart as $i => $eTag) { + $uploadParts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $eTag, + ); +} +/** + * step 3. Complete the upload + */ +$cmpOptions = null; +$result = $ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts,$cmpOptions); + + + +//******************************* For complete usage, see the following functions **************************************************** +putObject($ossClient, $bucket); +getObject($ossClient, $bucket); +appendObject($ossClient,$bucket); +appendFile($ossClient,$bucket); +multipartUpload($ossClient,$bucket); + +/** + * Upload in-memory data to oss + * + * Simple upload---upload specified in-memory data to an OSS object + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function putObject($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $content = file_get_contents($object); + $options = array( + $ossClient::OSS_CHECK_CRC64 => true, + ); + try { + $ossClient->putObject($bucket, $object, $content,$options); + printf("put object success!" . "\n"); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + + +/** + * Get the content of an object. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getObject($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $options = array( + OssClient::OSS_CHECK_CRC64 => true + ); + try { + $ossClient->getObject($bucket, $object,$options); + printf("get object success!" . "\n"); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + + +/** + * Append Object + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + */ +function appendObject($ossClient,$bucket){ + $object = "a.txt"; + $filePath = "D:\\localpath\\b.txt"; + $filePath1 = "D:\\localpath\\c.txt"; + $options = array( + $ossClient::OSS_CHECK_CRC64 => true, + ); + try{ + $content = file_get_contents($filePath); + $result = $ossClient->appendObject($bucket, $object,$content,0,$options); + $options[OssClient::OSS_INIT_CRC64] = $result->getCrc(); + $content1 = file_get_contents($filePath1); + $ossClient->appendObject($bucket, $object, $content1,$result->getPosition(),$options); + print("append Object: OK" . "\n"); + } catch(OssException $e) { + printf($e->getMessage() . "\n"); + return; + } +} + +/** + * Append File + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + */ +function appendFile($ossClient,$bucket){ + $object = "a.txt"; + $filePath = "D:\\localpath\\b.txt"; + $filePath1 = "D:\\localpath\\c.txt"; + $options = array( + $ossClient::OSS_CHECK_CRC64 => true, + ); + try{ + $result = $ossClient->appendFile($bucket, $object,$filePath,0,$options); + $options[OssClient::OSS_INIT_CRC64] = $result->getCrc(); + $ossClient->appendObject($bucket, $object, $filePath1,$result->getPosition(),$options); + print("append Object: OK" . "\n"); + } catch(OssException $e) { + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + + +/** + * Use basic multipart upload for file upload. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @throws OssException + */ +function multipartUpload($ossClient, $bucket) +{ + $uploadFile = $object = "test/multipart-test.txt"; + /** + * step 1. Initialize a block upload event, that is, a multipart upload process to get an upload id + */ + try { + $uploadId = $ossClient->initiateMultipartUpload($bucket, $object); + } catch (OssException $e) { + printf(__FUNCTION__ . ": initiateMultipartUpload FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": initiateMultipartUpload OK" . "\n"); + /* + * step 2. Upload parts + */ + $partSize = 10 * 1024 * 1024; + $uploadFileSize = sprintf('%u',filesize($uploadFile)); + $pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize); + $responseUploadPart = array(); + $uploadPosition = 0; + $checkCrc64 = true; + foreach ($pieces as $i => $piece) { + $fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO]; + $toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1; + $upOptions = array( + $ossClient::OSS_FILE_UPLOAD => $uploadFile, + $ossClient::OSS_PART_NUM => ($i + 1), + $ossClient::OSS_SEEK_TO => $fromPos, + $ossClient::OSS_LENGTH => $toPos - $fromPos + 1, + $ossClient::OSS_CHECK_CRC64 => $checkCrc64, + ); + //2. Upload each part to OSS + try { + $responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions); + printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} OK\n"); + } catch (OssException $e) { + printf($e->getMessage() . "\n"); + return; + } + } + $uploadParts = array(); + foreach ($responseUploadPart as $i => $eTag) { + $uploadParts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $eTag, + ); + } + /** + * step 3. Complete the upload + */ + try { + $comOptions = null; + $ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts,$comOptions); + printf(__FUNCTION__. ": completeMultipartUpload OK\n"); + } catch (OssException $e) { + printf($e->getMessage() . "\n"); + return; + } + + print(__FUNCTION__ . ": initiateMultipartUpload OK" . "\n"); +} diff --git a/src/OSS/Core/OssUtil.php b/src/OSS/Core/OssUtil.php index e3f2037f..be6daaa1 100644 --- a/src/OSS/Core/OssUtil.php +++ b/src/OSS/Core/OssUtil.php @@ -320,6 +320,56 @@ public static function getMd5SumForFile($filename, $from_pos, $to_pos) return $content_md5; } + /** + * Get crc64 of the file. + * + * @param string $filename + * @param int $from_pos + * @param int $to_pos + * @return string + */ + public static function getCrc64SumForFile($filename, $from_pos, $to_pos) + { + $content_crc64 = 0; + if (($to_pos - $from_pos) > self::OSS_MAX_PART_SIZE) { + return $content_crc64; + } + $filesize = sprintf('%u',filesize($filename)); + if ($from_pos >= $filesize || $to_pos >= $filesize || $from_pos < 0 || $to_pos < 0) { + return $content_crc64; + } + + $total_length = $to_pos - $from_pos + 1; + $buffer = 8192; + $left_length = $total_length; + if (!file_exists($filename)) { + return $content_crc64; + } + + if (false === $fh = fopen($filename, 'rb')) { + return $content_crc64; + } + + fseek($fh, $from_pos); + $data = ''; + while (!feof($fh)) { + if ($left_length >= $buffer) { + $read_length = $buffer; + } else { + $read_length = $left_length; + } + if ($read_length <= 0) { + break; + } else { + $data .= fread($fh, $read_length); + $left_length = $left_length - $read_length; + } + } + fclose($fh); + $content_crc64 = self::crc64($data); + return $content_crc64; + } + /** * Check if the OS is Windows. The default encoding in Windows is GBK. * @@ -527,4 +577,50 @@ public static function decodeKey($key, $encoding) throw new OssException("Unrecognized encoding type: " . $encoding); } } + /** + * @return array + */ + public static function crc64Table(){ + $crc64tab = array(); + // ECMA polynomial + $poly64rev = (0xC96C5795 << 32) | 0xD7870F42; + // ISO polynomial + // $poly64rev = (0xD8 << 56); + for ($i = 0; $i < 256; $i++) + { + for ($part = $i, $bit = 0; $bit < 8; $bit++) { + if ($part & 1) { + $part = (($part >> 1) & ~(0x8 << 60)) ^ $poly64rev; + } else { + $part = ($part >> 1) & ~(0x8 << 60); + } + } + $crc64tab[$i] = $part; + } + return $crc64tab; + } + + /** + * get crc64 function + * @param string $string + * @param int $crc + * @return string + */ + public static function crc64($string,$crc = 0){ + static $crc64tab; + $format = '%u'; + if ($crc64tab === null) { + $crc64tab = self::crc64Table(); + } + $crc = (int)$crc; + for ($i = 0; $i < strlen($string); $i++) { + $crc = ~$crc; + $crc = $crc64tab[($crc ^ ord($string[$i])) & 0xff] ^ (($crc >> 8) & ~(0xff << 56)); + $crc = ~$crc; + } + return sprintf($format, $crc); + } + + + } diff --git a/src/OSS/Model/AppendInfo.php b/src/OSS/Model/AppendInfo.php new file mode 100644 index 00000000..b521eed0 --- /dev/null +++ b/src/OSS/Model/AppendInfo.php @@ -0,0 +1,40 @@ +position = $position; + $this->crc = $crc; + } + + /** + * @return int + */ + public function getPosition() + { + return $this->position; + } + + /** + * @return int + */ + public function getCrc() + { + return $this->crc; + } + + private $position; + private $crc; +} \ No newline at end of file diff --git a/src/OSS/OssClient.php b/src/OSS/OssClient.php index c41cacda..ed5178f6 100644 --- a/src/OSS/OssClient.php +++ b/src/OSS/OssClient.php @@ -6,6 +6,7 @@ use OSS\Http\RequestCore; use OSS\Http\RequestCore_Exception; use OSS\Http\ResponseCore; +use OSS\Model\AppendInfo; use OSS\Model\CorsConfig; use OSS\Model\CnameConfig; use OSS\Model\LoggingConfig; @@ -1624,6 +1625,12 @@ public function putObject($bucket, $object, $content, $options = NULL) $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); } $response = $this->auth($options); + + $is_check_crc64 = $this->isCheckCrc64($options); + if ($is_check_crc64 && $response->isOK()) { + $local_crc64 = OssUtil::crc64($content); + $this->checkCrc64($local_crc64,$response->header['x-oss-hash-crc64ecma'],"put object"); + } if (isset($options[self::OSS_CALLBACK]) && !empty($options[self::OSS_CALLBACK])) { $result = new CallbackResult($response); @@ -1712,6 +1719,11 @@ public function uploadFile($bucket, $object, $file, $options = NULL) $options[self::OSS_OBJECT] = $object; $options[self::OSS_CONTENT_LENGTH] = $file_size; $response = $this->auth($options); + $is_check_crc64 = $this->isCheckCrc64($options); + if ($is_check_crc64 && $response->isOK()) { + $local_crc64 = OssUtil::crc64(file_get_contents($options[self::OSS_FILE_UPLOAD])); + $this->checkCrc64($local_crc64,$response->header['x-oss-hash-crc64ecma'],"upload file"); + } $result = new PutSetDeleteResult($response); return $result->getData(); } @@ -1762,7 +1774,7 @@ public function uploadStream($bucket, $object, $handle, $options = NULL) * @param string $object objcet name * @param string $content content to append * @param array $options - * @return int next append position + * @return AppendInfo * @throws OssException */ public function appendObject($bucket, $object, $content, $position, $options = NULL) @@ -1792,6 +1804,12 @@ public function appendObject($bucket, $object, $content, $position, $options = N $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); } $response = $this->auth($options); + $is_check_crc64 = $this->isCheckCrc64($options); + if ($is_check_crc64 && $response->isOK()) { + $init_crc = isset($options[self::OSS_INIT_CRC64]) ? $options[self::OSS_INIT_CRC64] : 0; + $local_crc64 = OssUtil::crc64($content,$init_crc); + $this->checkCrc64($local_crc64,$response->header['x-oss-hash-crc64ecma'],"append object position:". $position); + } $result = new AppendResult($response); return $result->getData(); } @@ -1803,7 +1821,7 @@ public function appendObject($bucket, $object, $content, $position, $options = N * @param string $object object name * @param string $file The local file path to append with * @param array $options - * @return int next append position + * @return AppendInfo * @throws OssException */ public function appendFile($bucket, $object, $file, $position, $options = NULL) @@ -1834,6 +1852,12 @@ public function appendFile($bucket, $object, $file, $position, $options = NULL) $options[self::OSS_POSITION] = strval($position); $response = $this->auth($options); + $is_check_crc64 = $this->isCheckCrc64($options); + if ($is_check_crc64 && $response->isOK()) { + $init_crc = isset($options[self::OSS_INIT_CRC64]) ? $options[self::OSS_INIT_CRC64] : 0; + $local_crc64 = OssUtil::crc64(file_get_contents($options[self::OSS_FILE_UPLOAD]),$init_crc); + $this->checkCrc64($local_crc64,$response->header['x-oss-hash-crc64ecma'],"append file position:". $position); + } $result = new AppendResult($response); return $result->getData(); } @@ -2028,6 +2052,11 @@ public function getObject($bucket, $object, $options = NULL) unset($options[self::OSS_RANGE]); } $response = $this->auth($options); + $is_check_crc64 = $this->isCheckCrc64($options); + if ($is_check_crc64 && $response->isOK() && !isset($range)) { + $local_crc64 = OssUtil::crc64($response->body); + $this->checkCrc64($local_crc64,$response->header['x-oss-hash-crc64ecma'],"get object"); + } $result = new BodyResult($response); return $result->getData(); } @@ -2260,6 +2289,13 @@ public function uploadPart($bucket, $object, $uploadId, $options = null) $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; } $response = $this->auth($options); + $is_check_crc64 = $this->isCheckCrc64($options); + if ($is_check_crc64 && $response->isOK()) { + $fromPos = $options[self::OSS_SEEK_TO]; + $toPos = $options[self::OSS_LENGTH]-1+$options[self::OSS_SEEK_TO]; + $local_crc64 = OssUtil::getCrc64SumForFile($options[self::OSS_FILE_UPLOAD],$fromPos,$toPos); + $this->checkCrc64($local_crc64,$response->header['x-oss-hash-crc64ecma'],"upload part"); + } $result = new UploadPartResult($response); return $result->getData(); } @@ -2746,6 +2782,16 @@ private function isCheckMD5($options) return $this->getValue($options, self::OSS_CHECK_MD5, false, true, true); } + /** + * Checks crc64 + * + * @param array $options + * @return bool|null + */ + private function isCheckCrc64($options) + { + return $this->getValue($options, self::OSS_CHECK_CRC64, false, true, true); + } /** * Gets value of the specified key from the options * @@ -3362,6 +3408,20 @@ public static function checkEnv() } } + /** + * Check whether the contents of crc 64 are equal + * @param string $localCrc64 + * @param string $ossCrc64 + * @param string $msg + * @throws OssException + */ + public function checkCrc64($localCrc64,$ossCrc64,$msg){ + if($localCrc64 != $ossCrc64){ + $errorMsg = sprintf("%s check crc64 failed. local:%s, oss:%s.",$msg, $localCrc64, $ossCrc64); + throw new OssException($errorMsg); + } + } + /** * Sets the http's timeout (in seconds) * @@ -3443,6 +3503,8 @@ public function setConnectTimeout($connectTimeout) const OSS_SUB_RESOURCE = 'sub_resource'; const OSS_DEFAULT_PREFIX = 'x-oss-'; const OSS_CHECK_MD5 = 'checkmd5'; + const OSS_CHECK_CRC64 = 'checkcrc64'; + const OSS_INIT_CRC64 = 'init_crc64'; const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; const OSS_SYMLINK_TARGET = 'x-oss-symlink-target'; const OSS_SYMLINK = 'symlink'; diff --git a/src/OSS/Result/AppendResult.php b/src/OSS/Result/AppendResult.php index d898d585..14676ab5 100644 --- a/src/OSS/Result/AppendResult.php +++ b/src/OSS/Result/AppendResult.php @@ -3,6 +3,7 @@ namespace OSS\Result; use OSS\Core\OssException; +use OSS\Model\AppendInfo; /** * Class AppendResult @@ -11,16 +12,14 @@ class AppendResult extends Result { /** - * Get the value of next-append-position from append's response headers - * - * @return int + * @return AppendInfo * @throws OssException */ protected function parseDataFromResponse() { $header = $this->rawResponse->header; if (isset($header["x-oss-next-append-position"])) { - return intval($header["x-oss-next-append-position"]); + return new AppendInfo($header["x-oss-next-append-position"],$header["x-oss-hash-crc64ecma"]); } throw new OssException("cannot get next-append-position"); } diff --git a/tests/OSS/Tests/OssClientObjectCrc64Test.php b/tests/OSS/Tests/OssClientObjectCrc64Test.php new file mode 100644 index 00000000..4e1ae538 --- /dev/null +++ b/tests/OSS/Tests/OssClientObjectCrc64Test.php @@ -0,0 +1,234 @@ +true + ); + + try { + $this->ossClient->putObject($this->bucket . 'not_exist', $object, $content, $options); + } catch (OssException $e) { + printf($e->getMessage()); + $this->assertFalse(false); + } + + try { + $this->ossClient->putObject($this->bucket, $object, $content, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + try { + $content = $this->ossClient->getObject($this->bucket, $object,$options); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + $options[OssClient::OSS_RANGE] = "0-29"; + try { + $this->ossClient->getObject($this->bucket, $object, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + } + + public function testAppendObject() + { + $object = "oss-php-sdk-test/append-test-object-name.txt"; + $content_array = array('Hello OSS', 'Hi OSS', 'OSS OK'); + + /** + * Append the upload string + */ + $options = array( + OssClient::OSS_CHECK_CRC64=>true + ); + try { + $result = $this->ossClient->appendObject($this->bucket, $object, $content_array[0], 0,$options); + $this->assertEquals($result->getPosition(), strlen($content_array[0])); + $options[OssClient::OSS_INIT_CRC64] = $result->getCrc(); + $result1 = $this->ossClient->appendObject($this->bucket, $object, $content_array[1], $result->getPosition(),$options); + $this->assertEquals($result1->getPosition(), strlen($content_array[0]) + strlen($content_array[1])); + $options[OssClient::OSS_INIT_CRC64] = $result1->getCrc(); + $result2 = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $result1->getPosition(), $options); + $this->assertEquals($result2->getPosition(), strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[2])); + } catch (OssException $e) { + printf($e->getMessage()); + $this->assertFalse(true); + } + + + /** + * Check if the content is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, implode($content_array)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + /** + * Append the upload of local files + */ + $options = array( + OssClient::OSS_CHECK_CRC64=>true + ); + try { + $rs = $this->ossClient->appendFile($this->bucket, $object, __FILE__, 0,$options); + $this->assertEquals($rs->getPosition(), filesize(__FILE__)); + $options[OssClient::OSS_INIT_CRC64] = $rs->getCrc(); + $rs1 = $this->ossClient->appendFile($this->bucket, $object, __FILE__, $rs->getPosition(),$options); + $this->assertEquals($rs1->getPosition(), filesize(__FILE__) * 2); + } catch (OssException $e) { + printf($e->getMessage()); + $this->assertFalse(true); + } + + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__) . file_get_contents(__FILE__)); + } catch (OssException $e) { + printf($e->getMessage()); + $this->assertFalse(true); + } + + /** + * Delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testPutObjectByRawApisWithCrc64Check() + { + $object = "mpu/multipart-test.txt"; + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + $part_size = 10 * 1024 * 1024; + $upload_file = __FILE__; + $upload_filesize = filesize($upload_file); + $pieces = $this->ossClient->generateMultiuploadParts($upload_filesize, $part_size); + var_dump($pieces); + $response_upload_part = array(); + $upload_position = 0; + $is_check_crc64 = true; + foreach ($pieces as $i => $piece) { + $from_pos = $upload_position + (integer)$piece[OssClient::OSS_SEEK_TO]; + $to_pos = (integer)$piece[OssClient::OSS_LENGTH] + $from_pos - 1; + $up_options = array( + OssClient::OSS_FILE_UPLOAD => $upload_file, + OssClient::OSS_PART_NUM => ($i + 1), + OssClient::OSS_SEEK_TO => $from_pos, + OssClient::OSS_LENGTH => $to_pos - $from_pos + 1, + OssClient::OSS_CHECK_CRC64 => $is_check_crc64, + ); + try { + $response_upload_part[] = $this->ossClient->uploadPart($this->bucket, $object, $upload_id, $up_options); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + $upload_parts = array(); + foreach ($response_upload_part as $i => $eTag) { + $upload_parts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $eTag, + ); + } + } catch (OssException $e) { + $this->assertFalse(true); + } + + + try { + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + printf($e->getMessage()); + $this->assertTrue(false); + } + + try { + $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts); + } catch (OssException $e) { + printf($e->getMessage()); + $this->assertTrue(false); + } + } + + public function testPutObjectByMultipartUploadWithCrc64Check() + { + $object = "mpu/multipart-test.txt"; + $file = __FILE__; + $options = array(OssClient::OSS_CHECK_CRC64 => true); + + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $file, $options); + $this->assertFalse(false); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testMultipartUploadBigFileWithCrc64Check() + { + $bigFileName = __DIR__ . DIRECTORY_SEPARATOR . "/bigfile.tmp"; + $localFilename = __DIR__ . DIRECTORY_SEPARATOR . "/localfile.tmp"; + if (file_exists($bigFileName)){ + unlink($bigFileName); + } + if (file_exists($localFilename)){ + unlink($localFilename); + } + OssUtil::generateFile($bigFileName, 6 * 1024 * 1024); + $object = 'mpu/multipart-bigfile-test.tmp'; + $options = array( + OssClient::OSS_CHECK_CRC64 => true, + OssClient::OSS_PART_SIZE => 1024*1024, + ); + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $bigFileName, $options); + $options = array(OssClient::OSS_FILE_DOWNLOAD => $localFilename); + $this->ossClient->getObject($this->bucket, $object, $options); + $this->assertEquals(md5_file($bigFileName), md5_file($localFilename)); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertFalse(true); + } + unlink($bigFileName); + unlink($localFilename); + } + +} diff --git a/tests/OSS/Tests/OssClientObjectTest.php b/tests/OSS/Tests/OssClientObjectTest.php index 228a394d..2224780f 100644 --- a/tests/OSS/Tests/OssClientObjectTest.php +++ b/tests/OSS/Tests/OssClientObjectTest.php @@ -353,12 +353,12 @@ public function testAppendObject() * Append the upload string */ try { - $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[0], 0); - $this->assertEquals($position, strlen($content_array[0])); - $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[1], $position); - $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1])); - $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $position, array(OssClient::OSS_LENGTH => strlen($content_array[2]))); - $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[2])); + $rs = $this->ossClient->appendObject($this->bucket, $object, $content_array[0], 0); + $this->assertEquals($rs->getPosition(), strlen($content_array[0])); + $rs1 = $this->ossClient->appendObject($this->bucket, $object, $content_array[1], $rs->getPosition()); + $this->assertEquals($rs1->getPosition(), strlen($content_array[0]) + strlen($content_array[1])); + $rs2 = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $rs1->getPosition(), array(OssClient::OSS_LENGTH => strlen($content_array[2]))); + $this->assertEquals($rs2->getPosition(), strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[2])); } catch (OssException $e) { $this->assertFalse(true); } @@ -397,10 +397,10 @@ public function testAppendObject() * Append the upload of local files */ try { - $position = $this->ossClient->appendFile($this->bucket, $object, __FILE__, 0); - $this->assertEquals($position, filesize(__FILE__)); - $position = $this->ossClient->appendFile($this->bucket, $object, __FILE__, $position); - $this->assertEquals($position, filesize(__FILE__) * 2); + $result = $this->ossClient->appendFile($this->bucket, $object, __FILE__, 0); + $this->assertEquals($result->getPosition(), filesize(__FILE__)); + $result2 = $this->ossClient->appendFile($this->bucket, $object, __FILE__, $result->getPosition()); + $this->assertEquals($result2->getPosition(), filesize(__FILE__) * 2); } catch (OssException $e) { $this->assertFalse(true); } @@ -436,8 +436,8 @@ public function testAppendObject() * Append upload with option */ try { - $position = $this->ossClient->appendObject($this->bucket, $object, "Hello OSS, ", 0, $options); - $position = $this->ossClient->appendObject($this->bucket, $object, "Hi OSS.", $position); + $position1 = $this->ossClient->appendObject($this->bucket, $object, "Hello OSS, ", 0, $options); + $position = $this->ossClient->appendObject($this->bucket, $object, "Hi OSS.", $position1->getPosition()); } catch (OssException $e) { $this->assertFalse(true); }