ObsClient.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <?php
  2. /**
  3. * Copyright 2019 Huawei Technologies Co.,Ltd.
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  5. * this file except in compliance with the License. You may obtain a copy of the
  6. * License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software distributed
  11. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. * specific language governing permissions and limitations under the License.
  14. *
  15. */
  16. namespace Obs;
  17. use Obs\Log\ObsLog;
  18. use Obs\Internal\Common\SdkCurlFactory;
  19. use Obs\Internal\Common\SdkStreamHandler;
  20. use Obs\Internal\Common\Model;
  21. use Monolog\Logger;
  22. use GuzzleHttp\Client;
  23. use GuzzleHttp\HandlerStack;
  24. use GuzzleHttp\Handler\CurlHandler;
  25. use GuzzleHttp\Handler\CurlMultiHandler;
  26. use GuzzleHttp\Handler\Proxy;
  27. use GuzzleHttp\Promise\Promise;
  28. define('DEBUG', Logger::DEBUG);
  29. define('INFO', Logger::INFO);
  30. define('NOTICE', Logger::NOTICE);
  31. define('WARNING', Logger::WARNING);
  32. define('WARN', Logger::WARNING);
  33. define('ERROR', Logger::ERROR);
  34. define('CRITICAL', Logger::CRITICAL);
  35. define('ALERT', Logger::ALERT);
  36. define('EMERGENCY', Logger::EMERGENCY);
  37. /**
  38. * @method Model createPostSignature(array $args=[]);
  39. * @method Model createSignedUrl(array $args=[]);
  40. * @method Model createBucket(array $args = []);
  41. * @method Model listBuckets();
  42. * @method Model deleteBucket(array $args = []);
  43. * @method Model listObjects(array $args = []);
  44. * @method Model listVersions(array $args = []);
  45. * @method Model headBucket(array $args = []);
  46. * @method Model getBucketMetadata(array $args = []);
  47. * @method Model getBucketLocation(array $args = []);
  48. * @method Model getBucketStorageInfo(array $args = []);
  49. * @method Model setBucketQuota(array $args = []);
  50. * @method Model getBucketQuota(array $args = []);
  51. * @method Model setBucketStoragePolicy(array $args = []);
  52. * @method Model getBucketStoragePolicy(array $args = []);
  53. * @method Model setBucketAcl(array $args = []);
  54. * @method Model getBucketAcl(array $args = []);
  55. * @method Model setBucketLogging(array $args = []);
  56. * @method Model getBucketLogging(array $args = []);
  57. * @method Model setBucketPolicy(array $args = []);
  58. * @method Model getBucketPolicy(array $args = []);
  59. * @method Model deleteBucketPolicy(array $args = []);
  60. * @method Model setBucketLifecycle(array $args = []);
  61. * @method Model getBucketLifecycle(array $args = []);
  62. * @method Model deleteBucketLifecycle(array $args = []);
  63. * @method Model setBucketWebsite(array $args = []);
  64. * @method Model getBucketWebsite(array $args = []);
  65. * @method Model deleteBucketWebsite(array $args = []);
  66. * @method Model setBucketVersioning(array $args = []);
  67. * @method Model getBucketVersioning(array $args = []);
  68. * @method Model setBucketCors(array $args = []);
  69. * @method Model getBucketCors(array $args = []);
  70. * @method Model deleteBucketCors(array $args = []);
  71. * @method Model setBucketNotification(array $args = []);
  72. * @method Model getBucketNotification(array $args = []);
  73. * @method Model setBucketTagging(array $args = []);
  74. * @method Model getBucketTagging(array $args = []);
  75. * @method Model setBucketCustomDomain(array $args = []);
  76. * @method Model getBucketCustomDomain(array $args = []);
  77. * @method Model deleteBucketCustomDomain(array $args = []);
  78. * @method Model deleteBucketTagging(array $args = []);
  79. * @method Model optionsBucket(array $args = []);
  80. * @method Model getFetchPolicy(array $args = []);
  81. * @method Model setFetchPolicy(array $args = []);
  82. * @method Model deleteFetchPolicy(array $args = []);
  83. * @method Model setFetchJob(array $args = []);
  84. * @method Model getFetchJob(array $args = []);
  85. *
  86. * @method Model putObject(array $args = []);
  87. * @method Model getObject(array $args = []);
  88. * @method Model setObjectTagging(array $args = []);
  89. * @method Model deleteObjectTagging(array $args = []);
  90. * @method Model getObjectTagging(array $args = []);
  91. * @method Model copyObject(array $args = []);
  92. * @method Model deleteObject(array $args = []);
  93. * @method Model deleteObjects(array $args = []);
  94. * @method Model getObjectMetadata(array $args = []);
  95. * @method Model setObjectAcl(array $args = []);
  96. * @method Model getObjectAcl(array $args = []);
  97. * @method Model initiateMultipartUpload(array $args = []);
  98. * @method Model uploadPart(array $args = []);
  99. * @method Model copyPart(array $args = []);
  100. * @method Model listParts(array $args = []);
  101. * @method Model completeMultipartUpload(array $args = []);
  102. * @method Model abortMultipartUpload(array $args = []);
  103. * @method Model listMultipartUploads(array $args = []);
  104. * @method Model optionsObject(array $args = []);
  105. * @method Model restoreObject(array $args = []);
  106. *
  107. * @method Promise createBucketAsync(array $args = [], callable $callback);
  108. * @method Promise listBucketsAsync(callable $callback);
  109. * @method Promise deleteBucketAsync(array $args = [], callable $callback);
  110. * @method Promise listObjectsAsync(array $args = [], callable $callback);
  111. * @method Promise listVersionsAsync(array $args = [], callable $callback);
  112. * @method Promise headBucketAsync(array $args = [], callable $callback);
  113. * @method Promise getBucketMetadataAsync(array $args = [], callable $callback);
  114. * @method Promise getBucketLocationAsync(array $args = [], callable $callback);
  115. * @method Promise getBucketStorageInfoAsync(array $args = [], callable $callback);
  116. * @method Promise setBucketQuotaAsync(array $args = [], callable $callback);
  117. * @method Promise getBucketQuotaAsync(array $args = [], callable $callback);
  118. * @method Promise setBucketStoragePolicyAsync(array $args = [], callable $callback);
  119. * @method Promise getBucketStoragePolicyAsync(array $args = [], callable $callback);
  120. * @method Promise setBucketAclAsync(array $args = [], callable $callback);
  121. * @method Promise getBucketAclAsync(array $args = [], callable $callback);
  122. * @method Promise setBucketLoggingAsync(array $args = [], callable $callback);
  123. * @method Promise getBucketLoggingAsync(array $args = [], callable $callback);
  124. * @method Promise setBucketPolicyAsync(array $args = [], callable $callback);
  125. * @method Promise getBucketPolicyAsync(array $args = [], callable $callback);
  126. * @method Promise deleteBucketPolicyAsync(array $args = [], callable $callback);
  127. * @method Promise setBucketLifecycleAsync(array $args = [], callable $callback);
  128. * @method Promise getBucketLifecycleAsync(array $args = [], callable $callback);
  129. * @method Promise deleteBucketLifecycleAsync(array $args = [], callable $callback);
  130. * @method Promise setBucketWebsiteAsync(array $args = [], callable $callback);
  131. * @method Promise getBucketWebsiteAsync(array $args = [], callable $callback);
  132. * @method Promise deleteBucketWebsiteAsync(array $args = [], callable $callback);
  133. * @method Promise setBucketVersioningAsync(array $args = [], callable $callback);
  134. * @method Promise getBucketVersioningAsync(array $args = [], callable $callback);
  135. * @method Promise setBucketCorsAsync(array $args = [], callable $callback);
  136. * @method Promise getBucketCorsAsync(array $args = [], callable $callback);
  137. * @method Promise deleteBucketCorsAsync(array $args = [], callable $callback);
  138. * @method Promise setBucketNotificationAsync(array $args = [], callable $callback);
  139. * @method Promise getBucketNotificationAsync(array $args = [], callable $callback);
  140. * @method Promise setBucketTaggingAsync(array $args = [], callable $callback);
  141. * @method Promise getBucketTaggingAsync(array $args = [], callable $callback);
  142. * @method Promise setBucketCustomDomainAsync(array $args = [], callable $callback);
  143. * @method Promise getBucketCustomDomainAsync(array $args = [], callable $callback);
  144. * @method Promise deleteBucketCustomDomainAsync(array $args = [], callable $callback);
  145. * @method Promise deleteBucketTaggingAsync(array $args = [], callable $callback);
  146. * @method Promise optionsBucketAsync(array $args = [], callable $callback);
  147. *
  148. * @method Promise putObjectAsync(array $args = [], callable $callback);
  149. * @method Promise getObjectAsync(array $args = [], callable $callback);
  150. * @method Promise setObjectTaggingAsync(array $args = [], callable $callback);
  151. * @method Promise deleteObjectTaggingAsync(array $args = [], callable $callback);
  152. * @method Promise getObjectTaggingAsync(array $args = [], callable $callback);
  153. * @method Promise copyObjectAsync(array $args = [], callable $callback);
  154. * @method Promise deleteObjectAsync(array $args = [], callable $callback);
  155. * @method Promise deleteObjectsAsync(array $args = [], callable $callback);
  156. * @method Promise getObjectMetadataAsync(array $args = [], callable $callback);
  157. * @method Promise setObjectAclAsync(array $args = [], callable $callback);
  158. * @method Promise getObjectAclAsync(array $args = [], callable $callback);
  159. * @method Promise initiateMultipartUploadAsync(array $args = [], callable $callback);
  160. * @method Promise uploadPartAsync(array $args = [], callable $callback);
  161. * @method Promise copyPartAsync(array $args = [], callable $callback);
  162. * @method Promise listPartsAsync(array $args = [], callable $callback);
  163. * @method Promise completeMultipartUploadAsync(array $args = [], callable $callback);
  164. * @method Promise abortMultipartUploadAsync(array $args = [], callable $callback);
  165. * @method Promise listMultipartUploadsAsync(array $args = [], callable $callback);
  166. * @method Promise optionsObjectAsync(array $args = [], callable $callback);
  167. * @method Promise restoreObjectAsync(array $args = [], callable $callback);
  168. * @method Promise getFetchPolicyAsync(array $args = [], callable $callback);
  169. * @method Promise setFetchPolicyAsync(array $args = [], callable $callback);
  170. * @method Promise deleteFetchPolicyAsync(array $args = [], callable $callback);
  171. * @method Promise setFetchJobAsync(array $args = [], callable $callback);
  172. * @method Promise getFetchJobAsync(array $args = [], callable $callback);
  173. *
  174. */
  175. class ObsClient
  176. {
  177. const SDK_VERSION = '3.23.10';
  178. const AclPrivate = 'private';
  179. const AclPublicRead = 'public-read';
  180. const AclPublicReadWrite = 'public-read-write';
  181. const AclPublicReadDelivered = 'public-read-delivered';
  182. const AclPublicReadWriteDelivered = 'public-read-write-delivered';
  183. const AclAuthenticatedRead = 'authenticated-read';
  184. const AclBucketOwnerRead = 'bucket-owner-read';
  185. const AclBucketOwnerFullControl = 'bucket-owner-full-control';
  186. const AclLogDeliveryWrite = 'log-delivery-write';
  187. const StorageClassStandard = 'STANDARD';
  188. const StorageClassWarm = 'WARM';
  189. const StorageClassCold = 'COLD';
  190. const PermissionRead = 'READ';
  191. const PermissionWrite = 'WRITE';
  192. const PermissionReadAcp = 'READ_ACP';
  193. const PermissionWriteAcp = 'WRITE_ACP';
  194. const PermissionFullControl = 'FULL_CONTROL';
  195. const AllUsers = 'Everyone';
  196. const GroupAllUsers = 'AllUsers';
  197. const GroupAuthenticatedUsers = 'AuthenticatedUsers';
  198. const GroupLogDelivery = 'LogDelivery';
  199. const RestoreTierExpedited = 'Expedited';
  200. const RestoreTierStandard = 'Standard';
  201. const RestoreTierBulk = 'Bulk';
  202. const GranteeGroup = 'Group';
  203. const GranteeUser = 'CanonicalUser';
  204. const CopyMetadata = 'COPY';
  205. const ReplaceMetadata = 'REPLACE';
  206. const SignatureV2 = 'v2';
  207. const SignatureV4 = 'v4';
  208. const SigantureObs = 'obs';
  209. const ObjectCreatedAll = 'ObjectCreated:*';
  210. const ObjectCreatedPut = 'ObjectCreated:Put';
  211. const ObjectCreatedPost = 'ObjectCreated:Post';
  212. const ObjectCreatedCopy = 'ObjectCreated:Copy';
  213. const ObjectCreatedCompleteMultipartUpload = 'ObjectCreated:CompleteMultipartUpload';
  214. const ObjectRemovedAll = 'ObjectRemoved:*';
  215. const ObjectRemovedDelete = 'ObjectRemoved:Delete';
  216. const ObjectRemovedDeleteMarkerCreated = 'ObjectRemoved:DeleteMarkerCreated';
  217. use Internal\SendRequestTrait;
  218. use Internal\GetResponseTrait;
  219. private $factorys;
  220. public function __construct(array $config = [])
  221. {
  222. $this->factorys = [];
  223. $this->ak = strval($config['key']);
  224. $this->sk = strval($config['secret']);
  225. if (isset($config['security_token'])) {
  226. $this->securityToken = strval($config['security_token']);
  227. }
  228. if (isset($config['endpoint'])) {
  229. $this->endpoint = trim(strval($config['endpoint']));
  230. }
  231. if ($this->endpoint === '') {
  232. throw new \InvalidArgumentException('endpoint is not set');
  233. }
  234. while ($this->endpoint[strlen($this->endpoint) - 1] === '/') {
  235. $this->endpoint = substr($this->endpoint, 0, strlen($this->endpoint) - 1);
  236. }
  237. if (strpos($this->endpoint, 'http') !== 0) {
  238. $this->endpoint = 'https://' . $this->endpoint;
  239. }
  240. if (isset($config['signature'])) {
  241. $this->signature = strval($config['signature']);
  242. }
  243. if (isset($config['path_style'])) {
  244. $this->pathStyle = $config['path_style'];
  245. }
  246. if (isset($config['region'])) {
  247. $this->region = strval($config['region']);
  248. }
  249. if (isset($config['ssl_verify'])) {
  250. $this->sslVerify = $config['ssl_verify'];
  251. } elseif (isset($config['ssl.certificate_authority'])) {
  252. $this->sslVerify = $config['ssl.certificate_authority'];
  253. } else {
  254. // nothing handle
  255. }
  256. if (isset($config['max_retry_count'])) {
  257. $this->maxRetryCount = intval($config['max_retry_count']);
  258. }
  259. if (isset($config['timeout'])) {
  260. $this->timeout = intval($config['timeout']);
  261. }
  262. if (isset($config['socket_timeout'])) {
  263. $this->socketTimeout = intval($config['socket_timeout']);
  264. }
  265. if (isset($config['connect_timeout'])) {
  266. $this->connectTimeout = intval($config['connect_timeout']);
  267. }
  268. if (isset($config['chunk_size'])) {
  269. $this->chunkSize = intval($config['chunk_size']);
  270. }
  271. if (isset($config['exception_response_mode'])) {
  272. $this->exceptionResponseMode = $config['exception_response_mode'];
  273. }
  274. if (isset($config['is_cname'])) {
  275. $this->isCname = $config['is_cname'];
  276. }
  277. $host = parse_url($this->endpoint)['host'];
  278. if (filter_var($host, FILTER_VALIDATE_IP) !== false) {
  279. $this->pathStyle = true;
  280. }
  281. $handler = self::chooseHandler($this);
  282. $this->httpClient = self::createHttpClient($handler);
  283. }
  284. private function createHttpClient($handler)
  285. {
  286. return new Client(
  287. [
  288. 'timeout' => 0,
  289. 'read_timeout' => $this->socketTimeout,
  290. 'connect_timeout' => $this->connectTimeout,
  291. 'allow_redirects' => false,
  292. 'verify' => $this->sslVerify,
  293. 'expect' => false,
  294. 'handler' => HandlerStack::create($handler),
  295. 'curl' => [
  296. CURLOPT_BUFFERSIZE => $this->chunkSize,
  297. ],
  298. ]
  299. );
  300. }
  301. public function __destruct()
  302. {
  303. $this->close();
  304. }
  305. public function refresh($key, $secret, $securityToken = false)
  306. {
  307. $this->ak = strval($key);
  308. $this->sk = strval($secret);
  309. if ($securityToken) {
  310. $this->securityToken = strval($securityToken);
  311. }
  312. }
  313. /**
  314. * Get the default User-Agent string to use with Guzzle
  315. *
  316. * @return string
  317. */
  318. public static function getDefaultUserAgent()
  319. {
  320. static $defaultAgent = '';
  321. if (!$defaultAgent) {
  322. $defaultAgent = 'obs-sdk-php/' . self::SDK_VERSION;
  323. }
  324. return $defaultAgent;
  325. }
  326. /**
  327. * Factory method to create a new Obs client using an array of configuration options.
  328. *
  329. * @param array $config Client configuration data
  330. *
  331. * @return ObsClient
  332. */
  333. public static function factory(array $config = [])
  334. {
  335. return new ObsClient($config);
  336. }
  337. public function close()
  338. {
  339. if ($this->factorys) {
  340. foreach ($this->factorys as $factory) {
  341. $factory->close();
  342. }
  343. }
  344. }
  345. public function initLog(array $logConfig = [])
  346. {
  347. ObsLog::initLog($logConfig);
  348. $msg = [];
  349. $msg[] = '[OBS SDK Version=' . self::SDK_VERSION;
  350. $msg[] = 'Endpoint=' . $this->endpoint;
  351. $msg[] = 'Access Mode=' . ($this->pathStyle ? 'Path' : 'Virtual Hosting') . ']';
  352. ObsLog::commonLog(WARNING, implode("];[", $msg));
  353. }
  354. private static function chooseHandler($obsclient)
  355. {
  356. $handler = null;
  357. if (function_exists('curl_multi_exec') && function_exists('curl_exec')) {
  358. $f1 = new SdkCurlFactory(50);
  359. $f2 = new SdkCurlFactory(3);
  360. $obsclient->factorys[] = $f1;
  361. $obsclient->factorys[] = $f2;
  362. $handler = Proxy::wrapSync(
  363. new CurlMultiHandler(['handle_factory' => $f1]),
  364. new CurlHandler(['handle_factory' => $f2])
  365. );
  366. } elseif (function_exists('curl_exec')) {
  367. $f = new SdkCurlFactory(3);
  368. $obsclient->factorys[] = $f;
  369. $handler = new CurlHandler(['handle_factory' => $f]);
  370. } elseif (function_exists('curl_multi_exec')) {
  371. $f = new SdkCurlFactory(50);
  372. $obsclient->factorys[] = $f;
  373. $handler = new CurlMultiHandler(['handle_factory' => $f]);
  374. } else {
  375. // nothing handle
  376. }
  377. if (ini_get('allow_url_fopen')) {
  378. $handler = $handler
  379. ? Proxy::wrapStreaming($handler, new SdkStreamHandler())
  380. : new SdkStreamHandler();
  381. } elseif (!$handler) {
  382. throw new \UnexpectedValueException(
  383. 'GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.');
  384. } else {
  385. // nothing handle
  386. }
  387. return $handler;
  388. }
  389. }