ObsClient.php 15 KB

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