ObsClient.php 16 KB

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