PageRenderTime 70ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/backwpup/libs/aws/services/s3.class.php

https://bitbucket.org/ssellek/saywhatnation.bitbucket
PHP | 4491 lines | 2227 code | 593 blank | 1671 comment | 352 complexity | bdbd19960bd66fdf07f0bad18816b127 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1, GPL-2.0, GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License").
  6. * You may not use this file except in compliance with the License.
  7. * A copy of the License is located at
  8. *
  9. * http://aws.amazon.com/apache2.0
  10. *
  11. * or in the "license" file accompanying this file. This file is distributed
  12. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  13. * express or implied. See the License for the specific language governing
  14. * permissions and limitations under the License.
  15. */
  16. /*%******************************************************************************************%*/
  17. // EXCEPTIONS
  18. /**
  19. * Default S3 Exception.
  20. */
  21. class S3_Exception extends Exception {}
  22. /*%******************************************************************************************%*/
  23. // MAIN CLASS
  24. /**
  25. * Amazon S3 is a web service that enables you to store data in the cloud. You can then download the data
  26. * or use the data with other AWS services, such as Amazon Elastic Cloud Computer (EC2).
  27. *
  28. * Amazon Simple Storage Service (Amazon S3) is storage for the Internet. You can use Amazon S3 to store
  29. * and retrieve any amount of data at any time, from anywhere on the web. You can accomplish these tasks
  30. * using the AWS Management Console, which is a simple and intuitive web interface.
  31. *
  32. * To get the most out of Amazon S3, you need to understand a few simple concepts. Amazon S3 stores data
  33. * as objects in buckets. An object is comprised of a file and optionally any metadata that describes
  34. * that file.
  35. *
  36. * To store an object in Amazon S3, you upload the file you want to store to a bucket. When you upload a
  37. * file, you can set permissions on the object as well as any metadata.
  38. *
  39. * Buckets are the containers for objects. You can have one or more buckets. For each bucket, you can control
  40. * access to the bucket (who can create, delete, and list objects in the bucket), view access logs for the
  41. * bucket and its objects, and choose the geographical region where Amazon S3 will store the bucket and its
  42. * contents.
  43. *
  44. * Visit <http://aws.amazon.com/s3/> for more information.
  45. *
  46. * @version 2012.10.02
  47. * @license See the included NOTICE.md file for more information.
  48. * @copyright See the included NOTICE.md file for more information.
  49. * @link http://aws.amazon.com/s3/ Amazon Simple Storage Service
  50. * @link http://aws.amazon.com/documentation/s3/ Amazon Simple Storage Service documentation
  51. */
  52. class AmazonS3 extends CFRuntime
  53. {
  54. /*%******************************************************************************************%*/
  55. // REGIONAL ENDPOINTS
  56. /**
  57. * Specify the queue URL for the US-Standard (Northern Virginia & Washington State) Region.
  58. */
  59. const REGION_US_E1 = 's3.amazonaws.com';
  60. /**
  61. * Specify the queue URL for the US-Standard (Northern Virginia & Washington State) Region.
  62. */
  63. const REGION_VIRGINIA = self::REGION_US_E1;
  64. /**
  65. * Specify the queue URL for the US-Standard (Northern Virginia & Washington State) Region.
  66. */
  67. const REGION_US_STANDARD = self::REGION_US_E1;
  68. /**
  69. * Specify the queue URL for the US-West 1 (Northern California) Region.
  70. */
  71. const REGION_US_W1 = 's3-us-west-1.amazonaws.com';
  72. /**
  73. * Specify the queue URL for the US-West 1 (Northern California) Region.
  74. */
  75. const REGION_CALIFORNIA = self::REGION_US_W1;
  76. /**
  77. * Specify the queue URL for the US-West 2 (Oregon) Region.
  78. */
  79. const REGION_US_W2 = 's3-us-west-2.amazonaws.com';
  80. /**
  81. * Specify the queue URL for the US-West 2 (Oregon) Region.
  82. */
  83. const REGION_OREGON = self::REGION_US_W2;
  84. /**
  85. * Specify the queue URL for the EU (Ireland) Region.
  86. */
  87. const REGION_EU_W1 = 's3-eu-west-1.amazonaws.com';
  88. /**
  89. * Specify the queue URL for the EU (Ireland) Region.
  90. */
  91. const REGION_IRELAND = self::REGION_EU_W1;
  92. /**
  93. * Specify the queue URL for the Asia Pacific (Singapore) Region.
  94. */
  95. const REGION_APAC_SE1 = 's3-ap-southeast-1.amazonaws.com';
  96. /**
  97. * Specify the queue URL for the Asia Pacific (Singapore) Region.
  98. */
  99. const REGION_SINGAPORE = self::REGION_APAC_SE1;
  100. /**
  101. * Specify the queue URL for the Asia Pacific (Sydney) Region.
  102. */
  103. const REGION_APAC_SE2 = 's3-ap-southeast-2.amazonaws.com';
  104. /**
  105. * Specify the queue URL for the Asia Pacific (Sydney) Region.
  106. */
  107. const REGION_SYDNEY = self::REGION_APAC_SE2;
  108. /**
  109. * Specify the queue URL for the Asia Pacific (Japan) Region.
  110. */
  111. const REGION_APAC_NE1 = 's3-ap-northeast-1.amazonaws.com';
  112. /**
  113. * Specify the queue URL for the Asia Pacific (Japan) Region.
  114. */
  115. const REGION_TOKYO = self::REGION_APAC_NE1;
  116. /**
  117. * Specify the queue URL for the South America (Sao Paulo) Region.
  118. */
  119. const REGION_SA_E1 = 's3-sa-east-1.amazonaws.com';
  120. /**
  121. * Specify the queue URL for the South America (Sao Paulo) Region.
  122. */
  123. const REGION_SAO_PAULO = self::REGION_SA_E1;
  124. /**
  125. * Specify the queue URL for the United States GovCloud Region.
  126. */
  127. const REGION_US_GOV1 = 's3-us-gov-west-1.amazonaws.com';
  128. /**
  129. * Specify the queue URL for the United States GovCloud FIPS 140-2 Region.
  130. */
  131. const REGION_US_GOV1_FIPS = 's3-fips-us-gov-west-1.amazonaws.com';
  132. /**
  133. * The default endpoint.
  134. */
  135. const DEFAULT_URL = self::REGION_US_E1;
  136. /*%******************************************************************************************%*/
  137. // REGIONAL WEBSITE ENDPOINTS
  138. /**
  139. * Specify the queue URL for the US-Standard (Northern Virginia & Washington State) Website Region.
  140. */
  141. const REGION_US_E1_WEBSITE = 's3-website-us-east-1.amazonaws.com';
  142. /**
  143. * Specify the queue URL for the US-Standard (Northern Virginia & Washington State) Website Region.
  144. */
  145. const REGION_VIRGINIA_WEBSITE = self::REGION_US_E1_WEBSITE;
  146. /**
  147. * Specify the queue URL for the US-Standard (Northern Virginia & Washington State) Website Region.
  148. */
  149. const REGION_US_STANDARD_WEBSITE = self::REGION_US_E1_WEBSITE;
  150. /**
  151. * Specify the queue URL for the US-West 1 (Northern California) Website Region.
  152. */
  153. const REGION_US_W1_WEBSITE = 's3-website-us-west-1.amazonaws.com';
  154. /**
  155. * Specify the queue URL for the US-West 1 (Northern California) Website Region.
  156. */
  157. const REGION_CALIFORNIA_WEBSITE = self::REGION_US_W1_WEBSITE;
  158. /**
  159. * Specify the queue URL for the US-West 2 (Oregon) Website Region.
  160. */
  161. const REGION_US_W2_WEBSITE = 's3-website-us-west-2.amazonaws.com';
  162. /**
  163. * Specify the queue URL for the US-West 2 (Oregon) Website Region.
  164. */
  165. const REGION_OREGON_WEBSITE = self::REGION_US_W2_WEBSITE;
  166. /**
  167. * Specify the queue URL for the EU (Ireland) Website Region.
  168. */
  169. const REGION_EU_W1_WEBSITE = 's3-website-eu-west-1.amazonaws.com';
  170. /**
  171. * Specify the queue URL for the EU (Ireland) Website Region.
  172. */
  173. const REGION_IRELAND_WEBSITE = self::REGION_EU_W1_WEBSITE;
  174. /**
  175. * Specify the queue URL for the Asia Pacific (Singapore) Website Region.
  176. */
  177. const REGION_APAC_SE1_WEBSITE = 's3-website-ap-southeast-1.amazonaws.com';
  178. /**
  179. * Specify the queue URL for the Asia Pacific (Singapore) Website Region.
  180. */
  181. const REGION_SINGAPORE_WEBSITE = self::REGION_APAC_SE1_WEBSITE;
  182. /**
  183. * Specify the queue URL for the Asia Pacific (Sydney) Website Region.
  184. */
  185. const REGION_APAC_SE2_WEBSITE = 's3-website-ap-southeast-2.amazonaws.com';
  186. /**
  187. * Specify the queue URL for the Asia Pacific (Sydney) Website Region.
  188. */
  189. const REGION_SYDNEY_WEBSITE = self::REGION_APAC_SE2_WEBSITE;
  190. /**
  191. * Specify the queue URL for the Asia Pacific (Japan) Website Region.
  192. */
  193. const REGION_APAC_NE1_WEBSITE = 's3-website-ap-northeast-1.amazonaws.com';
  194. /**
  195. * Specify the queue URL for the Asia Pacific (Japan) Website Region.
  196. */
  197. const REGION_TOKYO_WEBSITE = self::REGION_APAC_NE1_WEBSITE;
  198. /**
  199. * Specify the queue URL for the South America (Sao Paulo) Website Region.
  200. */
  201. const REGION_SA_E1_WEBSITE = 's3-website-sa-east-1.amazonaws.com';
  202. /**
  203. * Specify the queue URL for the South America (Sao Paulo) Website Region.
  204. */
  205. const REGION_SAO_PAULO_WEBSITE = self::REGION_SA_E1_WEBSITE;
  206. /**
  207. * Specify the queue URL for the United States GovCloud Website Region.
  208. */
  209. const REGION_US_GOV1_WEBSITE = 's3-website-us-gov-west-1.amazonaws.com';
  210. /*%******************************************************************************************%*/
  211. // ACL
  212. /**
  213. * ACL: Owner-only read/write.
  214. */
  215. const ACL_PRIVATE = 'private';
  216. /**
  217. * ACL: Owner read/write, public read.
  218. */
  219. const ACL_PUBLIC = 'public-read';
  220. /**
  221. * ACL: Public read/write.
  222. */
  223. const ACL_OPEN = 'public-read-write';
  224. /**
  225. * ACL: Owner read/write, authenticated read.
  226. */
  227. const ACL_AUTH_READ = 'authenticated-read';
  228. /**
  229. * ACL: Bucket owner read.
  230. */
  231. const ACL_OWNER_READ = 'bucket-owner-read';
  232. /**
  233. * ACL: Bucket owner full control.
  234. */
  235. const ACL_OWNER_FULL_CONTROL = 'bucket-owner-full-control';
  236. /*%******************************************************************************************%*/
  237. // GRANTS
  238. /**
  239. * When applied to a bucket, grants permission to list the bucket. When applied to an object, this
  240. * grants permission to read the object data and/or metadata.
  241. */
  242. const GRANT_READ = 'READ';
  243. /**
  244. * When applied to a bucket, grants permission to create, overwrite, and delete any object in the
  245. * bucket. This permission is not supported for objects.
  246. */
  247. const GRANT_WRITE = 'WRITE';
  248. /**
  249. * Grants permission to read the ACL for the applicable bucket or object. The owner of a bucket or
  250. * object always has this permission implicitly.
  251. */
  252. const GRANT_READ_ACP = 'READ_ACP';
  253. /**
  254. * Gives permission to overwrite the ACP for the applicable bucket or object. The owner of a bucket
  255. * or object always has this permission implicitly. Granting this permission is equivalent to granting
  256. * FULL_CONTROL because the grant recipient can make any changes to the ACP.
  257. */
  258. const GRANT_WRITE_ACP = 'WRITE_ACP';
  259. /**
  260. * Provides READ, WRITE, READ_ACP, and WRITE_ACP permissions. It does not convey additional rights and
  261. * is provided only for convenience.
  262. */
  263. const GRANT_FULL_CONTROL = 'FULL_CONTROL';
  264. /*%******************************************************************************************%*/
  265. // USERS
  266. /**
  267. * The "AuthenticatedUsers" group for access control policies.
  268. */
  269. const USERS_AUTH = 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers';
  270. /**
  271. * The "AllUsers" group for access control policies.
  272. */
  273. const USERS_ALL = 'http://acs.amazonaws.com/groups/global/AllUsers';
  274. /**
  275. * The "LogDelivery" group for access control policies.
  276. */
  277. const USERS_LOGGING = 'http://acs.amazonaws.com/groups/s3/LogDelivery';
  278. /*%******************************************************************************************%*/
  279. // PATTERNS
  280. /**
  281. * PCRE: Match all items
  282. */
  283. const PCRE_ALL = '/.*/i';
  284. /*%******************************************************************************************%*/
  285. // STORAGE
  286. /**
  287. * Standard storage redundancy.
  288. */
  289. const STORAGE_STANDARD = 'STANDARD';
  290. /**
  291. * Reduced storage redundancy.
  292. */
  293. const STORAGE_REDUCED = 'REDUCED_REDUNDANCY';
  294. /**
  295. * Storage in Glacier.
  296. */
  297. const STORAGE_GLACIER = 'GLACIER';
  298. /*%******************************************************************************************%*/
  299. // PROPERTIES
  300. /**
  301. * The request URL.
  302. */
  303. public $request_url;
  304. /**
  305. * The virtual host setting.
  306. */
  307. public $vhost;
  308. /**
  309. * The base XML elements to use for access control policy methods.
  310. */
  311. public $base_acp_xml;
  312. /**
  313. * The base XML elements to use for creating buckets in regions.
  314. */
  315. public $base_location_constraint;
  316. /**
  317. * The base XML elements to use for logging methods.
  318. */
  319. public $base_logging_xml;
  320. /**
  321. * The base XML elements to use for notifications.
  322. */
  323. public $base_notification_xml;
  324. /**
  325. * The base XML elements to use for versioning.
  326. */
  327. public $base_versioning_xml;
  328. /**
  329. * The base XML elements to use for completing a multipart upload.
  330. */
  331. public $complete_mpu_xml;
  332. /**
  333. * The base XML elements to use for website support.
  334. */
  335. public $website_config_xml;
  336. /**
  337. * The base XML elements to use for multi-object delete support.
  338. */
  339. public $multi_object_delete_xml;
  340. /**
  341. * The base XML elements to use for object expiration support.
  342. */
  343. public $object_expiration_xml;
  344. /**
  345. * The base XML elements to use for bucket tagging.
  346. */
  347. public $bucket_tagging_xml;
  348. /**
  349. * The base XML elements to use for CORS support.
  350. */
  351. public $cors_config_xml;
  352. /**
  353. * The base XML elements to use for restoration requests.
  354. */
  355. public $restore_request_xml;
  356. /**
  357. * The DNS vs. Path-style setting.
  358. */
  359. public $path_style = false;
  360. /**
  361. * The state of whether the prefix change is temporary or permanent.
  362. */
  363. public $temporary_prefix = false;
  364. /*%******************************************************************************************%*/
  365. // CONSTRUCTOR
  366. /**
  367. * Constructs a new instance of <AmazonS3>.
  368. *
  369. * @param array $options (Optional) An associative array of parameters that can have the following keys: <ul>
  370. * <li><code>certificate_authority</code> - <code>boolean</code> - Optional - Determines which Cerificate Authority file to use. A value of boolean <code>false</code> will use the Certificate Authority file available on the system. A value of boolean <code>true</code> will use the Certificate Authority provided by the SDK. Passing a file system path to a Certificate Authority file (chmodded to <code>0755</code>) will use that. Leave this set to <code>false</code> if you're not sure.</li>
  371. * <li><code>credentials</code> - <code>string</code> - Optional - The name of the credential set to use for authentication.</li>
  372. * <li><code>default_cache_config</code> - <code>string</code> - Optional - This option allows a preferred storage type to be configured for long-term caching. This can be changed later using the <set_cache_config()> method. Valid values are: <code>apc</code>, <code>xcache</code>, or a file system path such as <code>./cache</code> or <code>/tmp/cache/</code>.</li>
  373. * <li><code>key</code> - <code>string</code> - Optional - Your AWS key, or a session key. If blank, the default credential set will be used.</li>
  374. * <li><code>secret</code> - <code>string</code> - Optional - Your AWS secret key, or a session secret key. If blank, the default credential set will be used.</li>
  375. * <li><code>token</code> - <code>string</code> - Optional - An AWS session token.</li></ul>
  376. * @return void
  377. */
  378. public function __construct(array $options = array())
  379. {
  380. $this->vhost = null;
  381. $this->api_version = '2006-03-01';
  382. $this->hostname = self::DEFAULT_URL;
  383. $this->base_acp_xml = '<?xml version="1.0" encoding="UTF-8"?><AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/latest/"/>';
  384. $this->base_location_constraint = '<?xml version="1.0" encoding="UTF-8"?><CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/' . $this->api_version . '/"><LocationConstraint/></CreateBucketConfiguration>';
  385. $this->base_logging_xml = '<?xml version="1.0" encoding="utf-8"?><BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/' . $this->api_version . '"/>';
  386. $this->base_notification_xml = '<?xml version="1.0" encoding="utf-8"?><NotificationConfiguration/>';
  387. $this->base_versioning_xml = '<?xml version="1.0" encoding="utf-8"?><VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/' . $this->api_version . '/"/>';
  388. $this->complete_mpu_xml = '<?xml version="1.0" encoding="utf-8"?><CompleteMultipartUpload/>';
  389. $this->website_config_xml = '<?xml version="1.0" encoding="utf-8"?><WebsiteConfiguration xmlns="http://s3.amazonaws.com/doc/' . $this->api_version . '/"><IndexDocument><Suffix>index.html</Suffix></IndexDocument><ErrorDocument><Key>error.html</Key></ErrorDocument></WebsiteConfiguration>';
  390. $this->multi_object_delete_xml = '<?xml version="1.0" encoding="utf-8"?><Delete/>';
  391. $this->object_expiration_xml = '<?xml version="1.0" encoding="utf-8"?><LifecycleConfiguration/>';
  392. $this->bucket_tagging_xml = '<?xml version="1.0" encoding="utf-8"?><Tagging><TagSet/></Tagging>';
  393. $this->cors_config_xml = '<?xml version="1.0" encoding="utf-8"?><CORSConfiguration />';
  394. $this->restore_request_xml = '<?xml version="1.0" encoding="utf-8"?><RestoreRequest xmlns="http://s3.amazonaws.com/doc/' . $this->api_version . '"/>';
  395. parent::__construct($options);
  396. }
  397. /*%******************************************************************************************%*/
  398. // AUTHENTICATION
  399. /**
  400. * Authenticates a connection to Amazon S3. Do not use directly unless implementing custom methods for
  401. * this class.
  402. *
  403. * @param string $operation (Required) The name of the bucket to operate on (S3 Only).
  404. * @param array $payload (Required) An associative array of parameters for authenticating. See inline comments for allowed keys.
  405. * @return CFResponse A <CFResponse> object containing a parsed HTTP response.
  406. * @link http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_Authentication.html REST authentication
  407. */
  408. public function authenticate($operation, $payload)
  409. {
  410. /*
  411. * Overriding or extending this class? You can pass the following "magic" keys into $opt.
  412. *
  413. * ## verb, resource, sub_resource and query_string ##
  414. * <verb> /<resource>?<sub_resource>&<query_string>
  415. * GET /filename.txt?versions&prefix=abc&max-items=1
  416. *
  417. * ## versionId, uploadId, partNumber, response-* ##
  418. * These don't follow the same rules as above, in that the they needs to be signed, while
  419. * other query_string values do not.
  420. *
  421. * ## curlopts ##
  422. * These values get passed directly to the cURL methods in RequestCore.
  423. *
  424. * ## fileUpload, fileDownload, seekTo ##
  425. * These are slightly modified and then passed to the cURL methods in RequestCore.
  426. *
  427. * ## headers ##
  428. * $opt['headers'] is an array, whose keys are HTTP headers to be sent.
  429. *
  430. * ## body ##
  431. * This is the request body that is sent to the server via PUT/POST.
  432. *
  433. * ## preauth ##
  434. * This is a hook that tells authenticate() to generate a pre-authenticated URL.
  435. *
  436. * ## returnCurlHandle ##
  437. * Tells authenticate() to return the cURL handle for the request instead of executing it.
  438. */
  439. // Rename variables (to overcome inheritence issues)
  440. $bucket = $operation;
  441. $opt = $payload;
  442. // Validate the S3 bucket name
  443. if (!$this->validate_bucketname_support($bucket))
  444. {
  445. // @codeCoverageIgnoreStart
  446. throw new S3_Exception('S3 does not support "' . $bucket . '" as a valid bucket name. Review "Bucket Restrictions and Limitations" in the S3 Developer Guide for more information.');
  447. // @codeCoverageIgnoreEnd
  448. }
  449. // Die if $opt isn't set.
  450. if (!$opt) return false;
  451. $method_arguments = func_get_args();
  452. // Use the caching flow to determine if we need to do a round-trip to the server.
  453. if ($this->use_cache_flow)
  454. {
  455. // Generate an identifier specific to this particular set of arguments.
  456. $cache_id = $this->key . '_' . get_class($this) . '_' . $bucket . '_' . sha1(serialize($method_arguments));
  457. // Instantiate the appropriate caching object.
  458. $this->cache_object = new $this->cache_class($cache_id, $this->cache_location, $this->cache_expires, $this->cache_compress);
  459. if ($this->delete_cache)
  460. {
  461. $this->use_cache_flow = false;
  462. $this->delete_cache = false;
  463. return $this->cache_object->delete();
  464. }
  465. // Invoke the cache callback function to determine whether to pull data from the cache or make a fresh request.
  466. $data = $this->cache_object->response_manager(array($this, 'cache_callback'), $method_arguments);
  467. if ($this->parse_the_response)
  468. {
  469. // Parse the XML body
  470. $data = $this->parse_callback($data);
  471. }
  472. // End!
  473. return $data;
  474. }
  475. // If we haven't already set a resource prefix and the bucket name isn't DNS-valid...
  476. if ((!$this->resource_prefix && !$this->validate_bucketname_create($bucket)) || $this->path_style)
  477. {
  478. // Fall back to the older path-style URI
  479. $this->set_resource_prefix('/' . $bucket);
  480. $this->temporary_prefix = true;
  481. }
  482. // If the bucket name has periods and we are using SSL, we need to switch to path style URLs
  483. $bucket_name_may_cause_ssl_wildcard_failures = false;
  484. if ($this->use_ssl && strpos($bucket, '.') !== false)
  485. {
  486. $bucket_name_may_cause_ssl_wildcard_failures = true;
  487. }
  488. // Determine hostname
  489. $scheme = $this->use_ssl ? 'https://' : 'http://';
  490. if ($bucket_name_may_cause_ssl_wildcard_failures || $this->resource_prefix || $this->path_style)
  491. {
  492. // Use bucket-in-path method
  493. $hostname = $this->hostname . $this->resource_prefix . (($bucket === '' || $this->resource_prefix === '/' . $bucket) ? '' : ('/' . $bucket));
  494. }
  495. else
  496. {
  497. $hostname = $this->vhost ? $this->vhost : (($bucket === '') ? $this->hostname : ($bucket . '.') . $this->hostname);
  498. }
  499. // Get the UTC timestamp in RFC 2616 format
  500. $date = gmdate(CFUtilities::DATE_FORMAT_RFC2616, time());
  501. // Storage for request parameters.
  502. $resource = '';
  503. $sub_resource = '';
  504. $querystringparams = array();
  505. $signable_querystringparams = array();
  506. $string_to_sign = '';
  507. $headers = array(
  508. 'Content-MD5' => '',
  509. 'Content-Type' => 'application/x-www-form-urlencoded',
  510. 'Date' => $date
  511. );
  512. /*%******************************************************************************************%*/
  513. // Do we have an authentication token?
  514. if ($this->auth_token)
  515. {
  516. $headers['X-Amz-Security-Token'] = $this->auth_token;
  517. }
  518. // Handle specific resources
  519. if (isset($opt['resource']))
  520. {
  521. $resource .= $opt['resource'];
  522. }
  523. // Merge query string values
  524. if (isset($opt['query_string']))
  525. {
  526. $querystringparams = array_merge($querystringparams, $opt['query_string']);
  527. }
  528. $query_string = $this->util->to_query_string($querystringparams);
  529. // Merge the signable query string values. Must be alphabetical.
  530. $signable_list = array(
  531. 'partNumber',
  532. 'response-cache-control',
  533. 'response-content-disposition',
  534. 'response-content-encoding',
  535. 'response-content-language',
  536. 'response-content-type',
  537. 'response-expires',
  538. 'uploadId',
  539. 'versionId'
  540. );
  541. foreach ($signable_list as $item)
  542. {
  543. if (isset($opt[$item]))
  544. {
  545. $signable_querystringparams[$item] = $opt[$item];
  546. }
  547. }
  548. $signable_query_string = $this->util->to_query_string($signable_querystringparams);
  549. // Merge the HTTP headers
  550. if (isset($opt['headers']))
  551. {
  552. $headers = array_merge($headers, $opt['headers']);
  553. }
  554. // Compile the URI to request
  555. $conjunction = '?';
  556. $signable_resource = '/' . str_replace('%2F', '/', rawurlencode($resource));
  557. $non_signable_resource = '';
  558. if (isset($opt['sub_resource']))
  559. {
  560. $signable_resource .= $conjunction . rawurlencode($opt['sub_resource']);
  561. $conjunction = '&';
  562. }
  563. if ($signable_query_string !== '')
  564. {
  565. $signable_query_string = $conjunction . $signable_query_string;
  566. $conjunction = '&';
  567. }
  568. if ($query_string !== '')
  569. {
  570. $non_signable_resource .= $conjunction . $query_string;
  571. $conjunction = '&';
  572. }
  573. if (substr($hostname, -1) === substr($signable_resource, 0, 1))
  574. {
  575. $signable_resource = ltrim($signable_resource, '/');
  576. }
  577. $this->request_url = $scheme . $hostname . $signable_resource . $signable_query_string . $non_signable_resource;
  578. if (isset($opt['location']))
  579. {
  580. $this->request_url = $opt['location'];
  581. }
  582. // Gather information to pass along to other classes.
  583. $helpers = array(
  584. 'utilities' => $this->utilities_class,
  585. 'request' => $this->request_class,
  586. 'response' => $this->response_class,
  587. );
  588. // Instantiate the request class
  589. $request = new $this->request_class($this->request_url, $this->proxy, $helpers, $this->credentials);
  590. // Update RequestCore settings
  591. $request->request_class = $this->request_class;
  592. $request->response_class = $this->response_class;
  593. $request->ssl_verification = $this->ssl_verification;
  594. // Pass along registered stream callbacks
  595. if ($this->registered_streaming_read_callback)
  596. {
  597. $request->register_streaming_read_callback($this->registered_streaming_read_callback);
  598. }
  599. if ($this->registered_streaming_write_callback)
  600. {
  601. $request->register_streaming_write_callback($this->registered_streaming_write_callback);
  602. }
  603. // Streaming uploads
  604. if (isset($opt['fileUpload']))
  605. {
  606. if (is_resource($opt['fileUpload']))
  607. {
  608. // Determine the length to read from the stream
  609. $length = null; // From current position until EOF by default, size determined by set_read_stream()
  610. if (isset($headers['Content-Length']))
  611. {
  612. $length = $headers['Content-Length'];
  613. }
  614. elseif (isset($opt['seekTo']))
  615. {
  616. // Read from seekTo until EOF by default
  617. $stats = fstat($opt['fileUpload']);
  618. if ($stats && $stats['size'] >= 0)
  619. {
  620. $length = $stats['size'] - (integer) $opt['seekTo'];
  621. }
  622. }
  623. $request->set_read_stream($opt['fileUpload'], $length);
  624. if ($headers['Content-Type'] === 'application/x-www-form-urlencoded')
  625. {
  626. $headers['Content-Type'] = 'application/octet-stream';
  627. }
  628. }
  629. else
  630. {
  631. $request->set_read_file($opt['fileUpload']);
  632. // Determine the length to read from the file
  633. $length = $request->read_stream_size; // The file size by default
  634. if (isset($headers['Content-Length']))
  635. {
  636. $length = $headers['Content-Length'];
  637. }
  638. elseif (isset($opt['seekTo']) && isset($length))
  639. {
  640. // Read from seekTo until EOF by default
  641. $length -= (integer) $opt['seekTo'];
  642. }
  643. $request->set_read_stream_size($length);
  644. // Attempt to guess the correct mime-type
  645. if ($headers['Content-Type'] === 'application/x-www-form-urlencoded')
  646. {
  647. $extension = explode('.', $opt['fileUpload']);
  648. $extension = array_pop($extension);
  649. $mime_type = CFMimeTypes::get_mimetype($extension);
  650. $headers['Content-Type'] = $mime_type;
  651. }
  652. }
  653. $headers['Content-Length'] = $request->read_stream_size;
  654. $headers['Content-MD5'] = '';
  655. }
  656. // Handle streaming file offsets
  657. if (isset($opt['seekTo']))
  658. {
  659. // Pass the seek position to RequestCore
  660. $request->set_seek_position((integer) $opt['seekTo']);
  661. }
  662. // Streaming downloads
  663. if (isset($opt['fileDownload']))
  664. {
  665. if (is_resource($opt['fileDownload']))
  666. {
  667. $request->set_write_stream($opt['fileDownload']);
  668. }
  669. else
  670. {
  671. $request->set_write_file($opt['fileDownload']);
  672. }
  673. }
  674. $curlopts = array();
  675. // Set custom CURLOPT settings
  676. if (isset($opt['curlopts']))
  677. {
  678. $curlopts = $opt['curlopts'];
  679. }
  680. // Debug mode
  681. if ($this->debug_mode)
  682. {
  683. $curlopts[CURLOPT_VERBOSE] = true;
  684. }
  685. // Set the curl options.
  686. if (count($curlopts))
  687. {
  688. $request->set_curlopts($curlopts);
  689. }
  690. // Do we have a verb?
  691. if (isset($opt['verb']))
  692. {
  693. $request->set_method($opt['verb']);
  694. $string_to_sign .= $opt['verb'] . "\n";
  695. }
  696. // Add headers and content when we have a body
  697. if (isset($opt['body']))
  698. {
  699. $request->set_body($opt['body']);
  700. $headers['Content-Length'] = strlen($opt['body']);
  701. if ($headers['Content-Type'] === 'application/x-www-form-urlencoded')
  702. {
  703. $headers['Content-Type'] = 'application/octet-stream';
  704. }
  705. if (!isset($opt['NoContentMD5']) || $opt['NoContentMD5'] !== true)
  706. {
  707. $headers['Content-MD5'] = $this->util->hex_to_base64(md5($opt['body']));
  708. }
  709. }
  710. // Handle query-string authentication
  711. if (isset($opt['preauth']) && (integer) $opt['preauth'] > 0)
  712. {
  713. unset($headers['Date']);
  714. $headers['Content-Type'] = '';
  715. $headers['Expires'] = is_int($opt['preauth']) ? $opt['preauth'] : strtotime($opt['preauth']);
  716. }
  717. // Sort headers
  718. uksort($headers, 'strnatcasecmp');
  719. // Add headers to request and compute the string to sign
  720. foreach ($headers as $header_key => $header_value)
  721. {
  722. // Strip linebreaks from header values as they're illegal and can allow for security issues
  723. $header_value = str_replace(array("\r", "\n"), '', $header_value);
  724. // Add the header if it has a value
  725. if ($header_value !== '')
  726. {
  727. $request->add_header($header_key, $header_value);
  728. }
  729. // Generate the string to sign
  730. if (
  731. strtolower($header_key) === 'content-md5' ||
  732. strtolower($header_key) === 'content-type' ||
  733. strtolower($header_key) === 'date' ||
  734. (strtolower($header_key) === 'expires' && isset($opt['preauth']) && (integer) $opt['preauth'] > 0)
  735. )
  736. {
  737. $string_to_sign .= $header_value . "\n";
  738. }
  739. elseif (substr(strtolower($header_key), 0, 6) === 'x-amz-')
  740. {
  741. $string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n";
  742. }
  743. }
  744. // Add the signable resource location
  745. $string_to_sign .= ($this->resource_prefix ? $this->resource_prefix : '');
  746. $string_to_sign .= (($bucket === '' || $this->resource_prefix === '/' . $bucket) ? '' : ('/' . $bucket)) . $signable_resource . urldecode($signable_query_string);
  747. // Hash the AWS secret key and generate a signature for the request.
  748. $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->secret_key, true));
  749. $request->add_header('Authorization', 'AWS ' . $this->key . ':' . $signature);
  750. // If we're generating a URL, return the URL to the calling method.
  751. if (isset($opt['preauth']) && (integer) $opt['preauth'] > 0)
  752. {
  753. $query_params = array(
  754. 'AWSAccessKeyId' => $this->key,
  755. 'Expires' => $headers['Expires'],
  756. 'Signature' => $signature,
  757. );
  758. // If using short-term credentials, add the token to the query string
  759. if ($this->auth_token)
  760. {
  761. $query_params['x-amz-security-token'] = $this->auth_token;
  762. }
  763. return $this->request_url . $conjunction . http_build_query($query_params, '', '&');
  764. }
  765. elseif (isset($opt['preauth']))
  766. {
  767. return $this->request_url;
  768. }
  769. /*%******************************************************************************************%*/
  770. // If our changes were temporary, reset them.
  771. if ($this->temporary_prefix)
  772. {
  773. $this->temporary_prefix = false;
  774. $this->resource_prefix = null;
  775. }
  776. // Manage the (newer) batch request API or the (older) returnCurlHandle setting.
  777. if ($this->use_batch_flow)
  778. {
  779. $handle = $request->prep_request();
  780. $this->batch_object->add($handle);
  781. $this->use_batch_flow = false;
  782. return $handle;
  783. }
  784. elseif (isset($opt['returnCurlHandle']) && $opt['returnCurlHandle'] === true)
  785. {
  786. return $request->prep_request();
  787. }
  788. // Send!
  789. $request->send_request();
  790. // Prepare the response
  791. $headers = $request->get_response_header();
  792. $headers['x-aws-request-url'] = $this->request_url;
  793. $headers['x-aws-redirects'] = $this->redirects;
  794. $headers['x-aws-stringtosign'] = $string_to_sign;
  795. $headers['x-aws-requestheaders'] = $request->request_headers;
  796. // Did we have a request body?
  797. if (isset($opt['body']))
  798. {
  799. $headers['x-aws-requestbody'] = $opt['body'];
  800. }
  801. $data = new $this->response_class($headers, $this->parse_callback($request->get_response_body()), $request->get_response_code());
  802. // Did Amazon tell us to redirect? Typically happens for multiple rapid requests EU datacenters.
  803. // @see: http://docs.amazonwebservices.com/AmazonS3/latest/dev/Redirects.html
  804. // @codeCoverageIgnoreStart
  805. if ((integer) $request->get_response_code() === 307) // Temporary redirect to new endpoint.
  806. {
  807. $this->redirects++;
  808. $opt['location'] = $headers['location'];
  809. $data = $this->authenticate($bucket, $opt);
  810. }
  811. // Was it Amazon's fault the request failed? Retry the request until we reach $max_retries.
  812. elseif ((integer) $request->get_response_code() === 500 || (integer) $request->get_response_code() === 503)
  813. {
  814. if ($this->redirects <= $this->max_retries)
  815. {
  816. // Exponential backoff
  817. $delay = (integer) (pow(4, $this->redirects) * 100000);
  818. usleep($delay);
  819. $this->redirects++;
  820. $data = $this->authenticate($bucket, $opt);
  821. }
  822. }
  823. // @codeCoverageIgnoreEnd
  824. // Return!
  825. $this->redirects = 0;
  826. return $data;
  827. }
  828. /**
  829. * Validates whether or not the specified Amazon S3 bucket name is valid for DNS-style access. This
  830. * method is leveraged by any method that creates buckets.
  831. *
  832. * @param string $bucket (Required) The name of the bucket to validate.
  833. * @return boolean Whether or not the specified Amazon S3 bucket name is valid for DNS-style access. A value of <code>true</code> means that the bucket name is valid. A value of <code>false</code> means that the bucket name is invalid.
  834. */
  835. public function validate_bucketname_create($bucket)
  836. {
  837. // list_buckets() uses this. Let it pass.
  838. if ($bucket === '') return true;
  839. if (
  840. ($bucket === null || $bucket === false) || // Must not be null or false
  841. preg_match('/[^(a-z0-9\-\.)]/', $bucket) || // Must be in the lowercase Roman alphabet, period or hyphen
  842. !preg_match('/^([a-z]|\d)/', $bucket) || // Must start with a number or letter
  843. !(strlen($bucket) >= 3 && strlen($bucket) <= 63) || // Must be between 3 and 63 characters long
  844. (strpos($bucket, '..') !== false) || // Bucket names cannot contain two, adjacent periods
  845. (strpos($bucket, '-.') !== false) || // Bucket names cannot contain dashes next to periods
  846. (strpos($bucket, '.-') !== false) || // Bucket names cannot contain dashes next to periods
  847. preg_match('/(-|\.)$/', $bucket) || // Bucket names should not end with a dash or period
  848. preg_match('/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/', $bucket) // Must not be formatted as an IP address
  849. ) return false;
  850. return true;
  851. }
  852. /**
  853. * Validates whether or not the specified Amazon S3 bucket name is valid for path-style access. This
  854. * method is leveraged by any method that reads from buckets.
  855. *
  856. * @param string $bucket (Required) The name of the bucket to validate.
  857. * @return boolean Whether or not the bucket name is valid. A value of <code>true</code> means that the bucket name is valid. A value of <code>false</code> means that the bucket name is invalid.
  858. */
  859. public function validate_bucketname_support($bucket)
  860. {
  861. // list_buckets() uses this. Let it pass.
  862. if ($bucket === '') return true;
  863. // Validate
  864. if (
  865. ($bucket === null || $bucket === false) || // Must not be null or false
  866. preg_match('/[^(a-z0-9_\-\.)]/i', $bucket) || // Must be in the Roman alphabet, period, hyphen or underscore
  867. !preg_match('/^([a-z]|\d)/i', $bucket) || // Must start with a number or letter
  868. !(strlen($bucket) >= 3 && strlen($bucket) <= 255) || // Must be between 3 and 255 characters long
  869. preg_match('/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/', $bucket) // Must not be formatted as an IP address
  870. ) return false;
  871. return true;
  872. }
  873. /*%******************************************************************************************%*/
  874. // SETTERS
  875. /**
  876. * Sets the region to use for subsequent Amazon S3 operations. This will also reset any prior use of
  877. * <enable_path_style()>.
  878. *
  879. * @param string $region (Required) The region to use for subsequent Amazon S3 operations. For a complete list of REGION constants, see the <code>AmazonS3</code> Constants page in the API reference.
  880. * @return $this A reference to the current instance.
  881. */
  882. public function set_region($region)
  883. {
  884. // @codeCoverageIgnoreStart
  885. $this->set_hostname($region);
  886. switch ($region)
  887. {
  888. case self::REGION_US_E1: // Northern Virginia
  889. $this->enable_path_style(false);
  890. break;
  891. case self::REGION_EU_W1: // Ireland
  892. $this->enable_path_style(); // Always use path-style access for EU endpoint.
  893. break;
  894. default:
  895. $this->enable_path_style(false);
  896. break;
  897. }
  898. // @codeCoverageIgnoreEnd
  899. return $this;
  900. }
  901. /**
  902. * Sets the virtual host to use in place of the default `bucket.s3.amazonaws.com` domain.
  903. *
  904. * @param string $vhost (Required) The virtual host to use in place of the default `bucket.s3.amazonaws.com` domain.
  905. * @return $this A reference to the current instance.
  906. * @link http://docs.amazonwebservices.com/AmazonS3/latest/dev/VirtualHosting.html Virtual Hosting of Buckets
  907. */
  908. public function set_vhost($vhost)
  909. {
  910. $this->vhost = $vhost;
  911. return $this;
  912. }
  913. /**
  914. * Enables the use of the older path-style URI access for all requests.
  915. *
  916. * @param string $style (Optional) Whether or not to enable path-style URI access for all requests. The default value is <code>true</code>.
  917. * @return $this A reference to the current instance.
  918. */
  919. public function enable_path_style($style = true)
  920. {
  921. $this->path_style = $style;
  922. return $this;
  923. }
  924. /*%******************************************************************************************%*/
  925. // BUCKET METHODS
  926. /**
  927. * Creates an Amazon S3 bucket.
  928. *
  929. * Every object stored in Amazon S3 is contained in a bucket. Buckets partition the namespace of
  930. * objects stored in Amazon S3 at the top level. in a bucket, any name can be used for objects.
  931. * However, bucket names must be unique across all of Amazon S3.
  932. *
  933. * @param string $bucket (Required) The name of the bucket to create.
  934. * @param string $region (Required) The preferred geographical location for the bucket. [Allowed values: `AmazonS3::REGION_US_E1 `, `AmazonS3::REGION_US_W1`, `AmazonS3::REGION_EU_W1`, `AmazonS3::REGION_APAC_SE1`, `AmazonS3::REGION_APAC_NE1`]
  935. * @param string $acl (Optional) The ACL settings for the specified object. Accepts any of the following constants: [Allowed values: <code>AmazonS3::ACL_PRIVATE</code>, <code>AmazonS3::ACL_PUBLIC</code>, <code>AmazonS3::ACL_OPEN</code>, <code>AmazonS3::ACL_AUTH_READ</code>, <code>AmazonS3::ACL_OWNER_READ</code>, <code>AmazonS3::ACL_OWNER_FULL_CONTROL</code>]. Alternatively, an array of associative arrays. Each associative array contains an <code>id</code> and a <code>permission</code> key. The default value is <code>ACL_PRIVATE</code>.
  936. * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
  937. * <li><code>curlopts</code> - <code>array</code> - Optional - A set of values to pass directly into <code>curl_setopt()</code>, where the key is a pre-defined <code>CURLOPT_*</code> constant.</li>
  938. * <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request.</li></ul>
  939. * @return CFResponse A <CFResponse> object containing a parsed HTTP response.
  940. * @link http://docs.amazonwebservices.com/AmazonS3/latest/dev/UsingBucket.html Working with Amazon S3 Buckets
  941. */
  942. public function create_bucket($bucket, $region, $acl = self::ACL_PRIVATE, $opt = null)
  943. {
  944. // If the bucket contains uppercase letters...
  945. if (preg_match('/[A-Z]/', $bucket))
  946. {
  947. // Throw a warning
  948. trigger_error('Since DNS-valid bucket names cannot contain uppercase characters, "' . $bucket . '" has been automatically converted to "' . strtolower($bucket) . '"', E_USER_WARNING);
  949. // Force the bucketname to lowercase
  950. $bucket = strtolower($bucket);
  951. }
  952. // Validate the S3 bucket name for creation
  953. if (!$this->validate_bucketname_create($bucket))
  954. {
  955. // @codeCoverageIgnoreStart
  956. throw new S3_Exception('"' . $bucket . '" is not DNS-valid (i.e., <bucketname>.s3.amazonaws.com), and cannot be used as an S3 bucket name. Review "Bucket Restrictions and Limitations" in the S3 Developer Guide for more information.');
  957. // @codeCoverageIgnoreEnd
  958. }
  959. if (!$opt) $opt = array();
  960. $opt['verb'] = 'PUT';
  961. $opt['headers'] = array(
  962. 'Content-Type' => 'application/xml'
  963. );
  964. // Handle Access Control Lists. Can also be passed as an HTTP header.
  965. if (isset($acl))
  966. {
  967. if (is_array($acl))
  968. {
  969. $opt['headers'] = array_merge($opt['headers'], $this->generate_access_policy_headers($acl));
  970. }
  971. else
  972. {
  973. $opt['headers']['x-amz-acl'] = $acl;
  974. }
  975. }
  976. // Defaults
  977. $this->set_region($region); // Also sets path-style
  978. $xml = simplexml_load_string($this->base_location_constraint);
  979. switch ($region)
  980. {
  981. case self::REGION_US_E1: // Northern Virginia
  982. $opt['body'] = '';
  983. break;
  984. case self::REGION_EU_W1: // Ireland
  985. $xml->LocationConstraint = 'EU';
  986. $opt['body'] = $xml->asXML();
  987. break;
  988. default:
  989. $xml->LocationConstraint = str_replace(array('s3-', '.amazonaws.com'), '', $region);
  990. $opt['body'] = $xml->asXML();
  991. break;
  992. }
  993. $response = $this->authenticate($bucket, $opt);
  994. // Make sure we're set back to DNS-style URLs
  995. $this->enable_path_style(false);
  996. return $response;
  997. }
  998. /**
  999. * Gets the region in which the specified Amazon S3 bucket is located.
  1000. *
  1001. * @param string $bucket (Required) The name of the bucket to use.
  1002. * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
  1003. * <li><code>preauth</code> - <code>integer|string</code> - Optional - Specifies that a presigned URL for this request should be returned. May be passed as a number of seconds since UNIX Epoch, or any string compatible with <php:strtotime()>.</li>
  1004. * <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request. This toggle is useful for manually managed batch requests.</li></ul>
  1005. * @return CFResponse A <CFResponse> object containing a parsed HTTP response.
  1006. */
  1007. public function get_bucket_region($bucket, $opt = null)
  1008. {
  1009. // Add this to our request
  1010. if (!$opt) $opt = array();
  1011. $opt['verb'] = 'GET';
  1012. $opt['sub_resource'] = 'location';
  1013. // Authenticate to S3
  1014. $response = $this->authenticate($bucket, $opt);
  1015. if ($response->isOK())
  1016. {
  1017. // Handle body
  1018. $response->body = (string) $response->body;
  1019. }
  1020. return $response;
  1021. }
  1022. /**
  1023. * Gets the HTTP headers for the specified Amazon S3 bucket.
  1024. *
  1025. * @param string $bucket (Required) The name of the bucket to use.
  1026. * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
  1027. * <li><code>preauth</code> - <code>integer|string</code> - Optional - Specifies that a presigned URL for this request should be returned. May be passed as a number of seconds since UNIX Epoch, or any string compatible with <php:strtotime()>.</li>
  1028. * <li><code>curlopts</code> - <code>array</code> - Optional - A set of values to pass directly into <code>curl_setopt()</code>, where the key is a pre-defined <code>CURLOPT_*</code> constant.</li>
  1029. * <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request. This toggle is useful for manually managed batch requests.</li></ul>
  1030. * @return CFResponse A <CFResponse> object containing a parsed HTTP response.
  1031. */
  1032. public function get_bucket_headers($bucket, $opt = null)
  1033. {
  1034. if (!$opt) $opt = array();
  1035. $opt['verb'] = 'HEAD';
  1036. return $this->authenticate($bucket, $opt);
  1037. }
  1038. /**
  1039. * Deletes a bucket from an Amazon S3 account. A bucket must be empty before the bucket itself can be deleted.
  1040. *
  1041. * @param string $bucket (Required) The name of the bucket to use.
  1042. * @param boolean $force (Optional) Whether to force-delete the bucket and all of its contents. The default value is <code>false</code>.
  1043. * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
  1044. * <li><code>curlopts</code> - <code>array</code> - Optional - A set of values to pass directly into <code>curl_setopt()</code>, where the key is a pre-defined <code>CURLOPT_*</code> constant.</li>
  1045. * <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request. This toggle is useful for manually managed batch requests.</li></ul>
  1046. * @return mixed A <CFResponse> object if the bucket was deleted successfully. Returns boolean <code>false</code> if otherwise.
  1047. */
  1048. public function delete_bucket($bucket, $force = false, $opt = null)
  1049. {
  1050. // Set default value
  1051. $success = true;
  1052. if ($force)
  1053. {
  1054. // Delete all of the items from the bucket.
  1055. $success = $this->delete_all_object_versions($bucket);
  1056. }
  1057. // As long as we were successful...
  1058. if ($success)
  1059. {
  1060. if (!$opt) $opt = array();
  1061. $opt['verb'] = 'DELETE';
  1062. return $this->authenticate($bucket, $opt);
  1063. }
  1064. // @codeCoverageIgnoreStart
  1065. return false;
  1066. // @codeCoverageIgnoreEnd
  1067. }
  1068. /**
  1069. * Gets a list of all buckets contained in the caller's Amazon S3 account.
  1070. *
  1071. * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
  1072. * <li><code>preauth</code> - <code>integer|string</code> - Optional - Specifies that a presigned URL for this request should be returned. May be passed as a number of seconds since UNIX Epoch, or any string compatible with <php:strtotime()>.</li>
  1073. * <li><code>curlopts</code> - <code>array</code> - Optional - A set of values to pass directly into <code>curl_setopt()</code>, where the key is a pre-defined <code>CURLOPT_*</code> constant.</li>
  1074. * <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request. This toggle is useful for manually managed batch requests.</li></ul>
  1075. * @return CFResponse A <CFResponse> object containing a parsed HTTP response.
  1076. */
  1077. public function list_buckets($opt = null)
  1078. {
  1079. if (!$opt) $opt = array();
  1080. $opt['verb'] = 'GET';
  1081. return $this->authenticate('', $opt);
  1082. }
  1083. /**
  1084. * Gets the access control list (ACL) settings for the specified Amazon S3 bucket.
  1085. *
  1086. * @param string $bucket (Required) The name of the bucket to use.
  1087. * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
  1088. * <li><code>preauth</code> - <code>integer|string</code> - Optional - Specifies that a presigned URL for this request should be returned. May be passed as a number of seconds since UNIX Epoch, or any string compatible with <php:strtotime()>.</li>
  1089. * <li><code>curlopts</code> - <code>array</code> - Optional - A set of values to pass directly into <code>curl_setopt()</code>, where the key is a pre-defined <code>CURLOPT_*</code> constant.</li>
  1090. * <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request. This toggle is useful for manually managed batch requests.</li></ul>
  1091. * @return CFResponse A <CFResponse> object containing a parsed HTTP response.
  1092. * @link http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAccessPolicy.html REST Access Control Policy
  1093. */
  1094. public function get_bucket_acl($bucket, $opt = null)
  1095. {
  1096. // Add this to our request
  1097. if (!$opt) $opt = array();
  1098. $opt['verb'] = 'GET';
  1099. $opt['sub_resource'] = 'acl';
  1100. // Authenticate to S3
  1101. return $this->authenticate($bucket, $opt);
  1102. }
  1103. /**
  1104. * Sets the access control list (ACL) settings for the specified Amazon S3 bucket.
  1105. *
  1106. * @param string $bucket (Required) The name of the bucket to use.
  1107. * @param string $acl (Optional) The ACL settings for the specified bucket. [Allowed values: <code>AmazonS3::ACL_PRIVATE</code>, <code>AmazonS3::ACL_PUBLIC</code>, <code>AmazonS3::ACL_OPEN</code>, <code>AmazonS3::ACL_AUTH_READ</code>, <code>AmazonS3::ACL_OWNER_READ</code>, <code>AmazonS3::ACL_OWNER_FULL_CONTROL</code>]. Alternatively, an array of associative arrays. Each associative array contains an `id` and a `permission` key. The default value is <ACL_PRIVATE>.
  1108. * @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
  1109. * <li><code>curlopts</code> - <code>array</code> - Optional - A set of values to pass directly into <code>curl_setopt()</code>, where the key is a pre-defined <code>CURLOPT_*</code> constant.</li>
  1110. * <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request. This toggle is useful for manually managed batch requests.</li></ul>
  1111. * @return CFResponse A <CFResponse> object containing a parsed HTTP response.
  1112. * @link http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAccessPolicy.html REST Access Control Policy
  1113. */
  1114. public function set_bucket_acl($bucket, $acl = self::ACL_PRIVATE, $opt = null)
  1115. {
  1116. // Add this to our request
  1117. if (!$opt) $opt = array();
  1118. $opt['verb'] = 'PUT';
  1119. $opt['sub_resource'] = 'acl';
  1120. $opt['headers'] = array(
  1121. 'Content-Type' => 'application/xml'
  1122. );
  1123. // Make sure these are defined.
  1124. // @codeCoverageIgnoreStart
  1125. if (!$this->credentials->canonical_id || !$this->credentials->canonical_name)
  1126. {
  1127. // Fetch the data live.
  1128. $canonical = $this->get_canonical_user_id();
  1129. $this->credentials->canonical_id = $canonical['id'];
  1130. $this->credentials->canonical_name = $canonical['display_name'];
  1131. }
  1132. // @codeCoverageIgnoreEnd
  1133. if (is_array($acl))
  1134. {
  1135. $opt['headers'] = array_merge($opt['headers'], $this->generate_access_policy_headers($acl));
  1136. }
  1137. else
  1138. {
  1139. $opt['body'] = '';
  1140. $opt['headers']['x-amz-acl'] = $acl;
  1141. }
  1142. // Authenticate to S3
  1143. return $this->authenticate($bucket, $opt);
  1144. }
  1145. /*%******************************************************************************************%*/
  1146. // OBJECT METHODS
  1147. /**
  1148. * Creates an Amazon S3 object. After an Amazon S3 bucket is created, objects can be stored in it.
  1149. *
  1150. * Each standard object can hold up to 5 GB of data. When an object is stored in Amazon S3, the data is streamed
  1151. * to multiple storage servers in multiple data centers. This ensures the data remains available in the
  1152. * event of internal network or hardware failure.
  1153. *
  1154. * @param string $bucket (Required) The name of the bucket to use.
  1155. * @param string $filename (Required) The file name for the object.
  1156. * @param array $opt (Optional) An associative array of parameā€¦

Large files files are truncated, but you can click here to view the full file