PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/www/system/library/Zend/Service/Amazon/S3.php

https://bitbucket.org/vmihailenco/zf-blog
PHP | 900 lines | 518 code | 109 blank | 273 comment | 93 complexity | 3ea4aa5f97a2cc20e21b9390bf435908 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Service
  17. * @subpackage Amazon_S3
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: S3.php 20096 2010-01-06 02:05:09Z bkarwin $
  21. */
  22. /**
  23. * @see Zend_Service_Amazon_Abstract
  24. */
  25. /**
  26. * @see Zend_Crypt_Hmac
  27. */
  28. /**
  29. * Amazon S3 PHP connection class
  30. *
  31. * @category Zend
  32. * @package Zend_Service
  33. * @subpackage Amazon_S3
  34. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. * @see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/
  37. */
  38. class Zend_Service_Amazon_S3 extends Zend_Service_Amazon_Abstract
  39. {
  40. /**
  41. * Store for stream wrapper clients
  42. *
  43. * @var array
  44. */
  45. protected static $_wrapperClients = array();
  46. /**
  47. * Endpoint for the service
  48. *
  49. * @var Zend_Uri_Http
  50. */
  51. protected $_endpoint;
  52. const S3_ENDPOINT = 's3.amazonaws.com';
  53. const S3_ACL_PRIVATE = 'private';
  54. const S3_ACL_PUBLIC_READ = 'public-read';
  55. const S3_ACL_PUBLIC_WRITE = 'public-read-write';
  56. const S3_ACL_AUTH_READ = 'authenticated-read';
  57. const S3_REQUESTPAY_HEADER = 'x-amz-request-payer';
  58. const S3_ACL_HEADER = 'x-amz-acl';
  59. const S3_CONTENT_TYPE_HEADER = 'Content-Type';
  60. /**
  61. * Set S3 endpoint to use
  62. *
  63. * @param string|Zend_Uri_Http $endpoint
  64. * @return Zend_Service_Amazon_S3
  65. */
  66. public function setEndpoint($endpoint)
  67. {
  68. if (!($endpoint instanceof Zend_Uri_Http)) {
  69. $endpoint = Zend_Uri::factory($endpoint);
  70. }
  71. if (!$endpoint->valid()) {
  72. /**
  73. * @see Zend_Service_Amazon_S3_Exception
  74. */
  75. throw new Zend_Service_Amazon_S3_Exception('Invalid endpoint supplied');
  76. }
  77. $this->_endpoint = $endpoint;
  78. return $this;
  79. }
  80. /**
  81. * Get current S3 endpoint
  82. *
  83. * @return Zend_Uri_Http
  84. */
  85. public function getEndpoint()
  86. {
  87. return $this->_endpoint;
  88. }
  89. /**
  90. * Constructor
  91. *
  92. * @param string $accessKey
  93. * @param string $secretKey
  94. * @param string $region
  95. */
  96. public function __construct($accessKey=null, $secretKey=null, $region=null)
  97. {
  98. parent::__construct($accessKey, $secretKey, $region);
  99. $this->setEndpoint('http://'.self::S3_ENDPOINT);
  100. }
  101. /**
  102. * Verify if the bucket name is valid
  103. *
  104. * @param string $bucket
  105. * @return boolean
  106. */
  107. public function _validBucketName($bucket)
  108. {
  109. $len = strlen($bucket);
  110. if ($len < 3 || $len > 255) {
  111. /**
  112. * @see Zend_Service_Amazon_S3_Exception
  113. */
  114. throw new Zend_Service_Amazon_S3_Exception("Bucket name \"$bucket\" must be between 3 and 255 characters long");
  115. }
  116. if (preg_match('/[^a-z0-9\._-]/', $bucket)) {
  117. /**
  118. * @see Zend_Service_Amazon_S3_Exception
  119. */
  120. throw new Zend_Service_Amazon_S3_Exception("Bucket name \"$bucket\" contains invalid characters");
  121. }
  122. if (preg_match('/(\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}/', $bucket)) {
  123. /**
  124. * @see Zend_Service_Amazon_S3_Exception
  125. */
  126. throw new Zend_Service_Amazon_S3_Exception("Bucket name \"$bucket\" cannot be an IP address");
  127. }
  128. return true;
  129. }
  130. /**
  131. * Add a new bucket
  132. *
  133. * @param string $bucket
  134. * @return boolean
  135. */
  136. public function createBucket($bucket, $location = null)
  137. {
  138. $this->_validBucketName($bucket);
  139. if($location) {
  140. $data = '<CreateBucketConfiguration><LocationConstraint>'.$location.'</LocationConstraint></CreateBucketConfiguration>';
  141. }
  142. else {
  143. $data = null;
  144. }
  145. $response = $this->_makeRequest('PUT', $bucket, null, array(), $data);
  146. return ($response->getStatus() == 200);
  147. }
  148. /**
  149. * Checks if a given bucket name is available
  150. *
  151. * @param string $bucket
  152. * @return boolean
  153. */
  154. public function isBucketAvailable($bucket)
  155. {
  156. $response = $this->_makeRequest('HEAD', $bucket, array('max-keys'=>0));
  157. return ($response->getStatus() != 404);
  158. }
  159. /**
  160. * Checks if a given object exists
  161. *
  162. * @param string $object
  163. * @return boolean
  164. */
  165. public function isObjectAvailable($object)
  166. {
  167. $response = $this->_makeRequest('HEAD', $object);
  168. return ($response->getStatus() == 200);
  169. }
  170. /**
  171. * Remove a given bucket. All objects in the bucket must be removed prior
  172. * to removing the bucket.
  173. *
  174. * @param string $bucket
  175. * @return boolean
  176. */
  177. public function removeBucket($bucket)
  178. {
  179. $response = $this->_makeRequest('DELETE', $bucket);
  180. // Look for a 204 No Content response
  181. return ($response->getStatus() == 204);
  182. }
  183. /**
  184. * Get metadata information for a given object
  185. *
  186. * @param string $object
  187. * @return array|false
  188. */
  189. public function getInfo($object)
  190. {
  191. $info = array();
  192. $object = $this->_fixupObjectName($object);
  193. $response = $this->_makeRequest('HEAD', $object);
  194. if ($response->getStatus() == 200) {
  195. $info['type'] = $response->getHeader('Content-type');
  196. $info['size'] = $response->getHeader('Content-length');
  197. $info['mtime'] = strtotime($response->getHeader('Last-modified'));
  198. $info['etag'] = $response->getHeader('ETag');
  199. }
  200. else {
  201. return false;
  202. }
  203. return $info;
  204. }
  205. /**
  206. * List the S3 buckets
  207. *
  208. * @return array|false
  209. */
  210. public function getBuckets()
  211. {
  212. $response = $this->_makeRequest('GET');
  213. if ($response->getStatus() != 200) {
  214. return false;
  215. }
  216. $xml = new SimpleXMLElement($response->getBody());
  217. $buckets = array();
  218. foreach ($xml->Buckets->Bucket as $bucket) {
  219. $buckets[] = (string)$bucket->Name;
  220. }
  221. return $buckets;
  222. }
  223. /**
  224. * Remove all objects in the bucket.
  225. *
  226. * @param string $bucket
  227. * @return boolean
  228. */
  229. public function cleanBucket($bucket)
  230. {
  231. $objects = $this->getObjectsByBucket($bucket);
  232. if (!$objects) {
  233. return false;
  234. }
  235. foreach ($objects as $object) {
  236. $this->removeObject("$bucket/$object");
  237. }
  238. return true;
  239. }
  240. /**
  241. * List the objects in a bucket.
  242. *
  243. * Provides the list of object keys that are contained in the bucket. Valid params include the following.
  244. * prefix - Limits the response to keys which begin with the indicated prefix. You can use prefixes to separate a bucket into different sets of keys in a way similar to how a file system uses folders.
  245. * marker - Indicates where in the bucket to begin listing. The list will only include keys that occur lexicographically after marker. This is convenient for pagination: To get the next page of results use the last key of the current page as the marker.
  246. * max-keys - The maximum number of keys you'd like to see in the response body. The server might return fewer than this many keys, but will not return more.
  247. * delimiter - Causes keys that contain the same string between the prefix and the first occurrence of the delimiter to be rolled up into a single result element in the CommonPrefixes collection. These rolled-up keys are not returned elsewhere in the response.
  248. *
  249. * @param string $bucket
  250. * @param array $params S3 GET Bucket Paramater
  251. * @return array|false
  252. */
  253. public function getObjectsByBucket($bucket, $params = array())
  254. {
  255. $response = $this->_makeRequest('GET', $bucket, $params);
  256. if ($response->getStatus() != 200) {
  257. return false;
  258. }
  259. $xml = new SimpleXMLElement($response->getBody());
  260. $objects = array();
  261. if (isset($xml->Contents)) {
  262. foreach ($xml->Contents as $contents) {
  263. foreach ($contents->Key as $object) {
  264. $objects[] = (string)$object;
  265. }
  266. }
  267. }
  268. return $objects;
  269. }
  270. /**
  271. * Make sure the object name is valid
  272. *
  273. * @param string $object
  274. * @return string
  275. */
  276. protected function _fixupObjectName($object)
  277. {
  278. $nameparts = explode('/', $object);
  279. $this->_validBucketName($nameparts[0]);
  280. $firstpart = array_shift($nameparts);
  281. if (count($nameparts) == 0) {
  282. return $firstpart;
  283. }
  284. return $firstpart.'/'.join('/', array_map('rawurlencode', $nameparts));
  285. }
  286. /**
  287. * Get an object
  288. *
  289. * @param string $object
  290. * @param bool $paidobject This is "requestor pays" object
  291. * @return string|false
  292. */
  293. public function getObject($object, $paidobject=false)
  294. {
  295. $object = $this->_fixupObjectName($object);
  296. if ($paidobject) {
  297. $response = $this->_makeRequest('GET', $object, null, array(self::S3_REQUESTPAY_HEADER => 'requester'));
  298. }
  299. else {
  300. $response = $this->_makeRequest('GET', $object);
  301. }
  302. if ($response->getStatus() != 200) {
  303. return false;
  304. }
  305. return $response->getBody();
  306. }
  307. /**
  308. * Get an object using streaming
  309. *
  310. * Can use either provided filename for storage or create a temp file if none provided.
  311. *
  312. * @param string $object Object path
  313. * @param string $streamfile File to write the stream to
  314. * @param bool $paidobject This is "requestor pays" object
  315. * @return Zend_Http_Response_Stream|false
  316. */
  317. public function getObjectStream($object, $streamfile = null, $paidobject=false)
  318. {
  319. $object = $this->_fixupObjectName($object);
  320. self::getHttpClient()->setStream($streamfile?$streamfile:true);
  321. if ($paidobject) {
  322. $response = $this->_makeRequest('GET', $object, null, array(self::S3_REQUESTPAY_HEADER => 'requester'));
  323. }
  324. else {
  325. $response = $this->_makeRequest('GET', $object);
  326. }
  327. self::getHttpClient()->setStream(null);
  328. if ($response->getStatus() != 200 || !($response instanceof Zend_Http_Response_Stream)) {
  329. return false;
  330. }
  331. return $response;
  332. }
  333. /**
  334. * Upload an object by a PHP string
  335. *
  336. * @param string $object Object name
  337. * @param string|resource $data Object data (can be string or stream)
  338. * @param array $meta Metadata
  339. * @return boolean
  340. */
  341. public function putObject($object, $data, $meta=null)
  342. {
  343. $object = $this->_fixupObjectName($object);
  344. $headers = (is_array($meta)) ? $meta : array();
  345. if(!is_resource($data)) {
  346. $headers['Content-MD5'] = base64_encode(md5($data, true));
  347. }
  348. $headers['Expect'] = '100-continue';
  349. if (!isset($headers[self::S3_CONTENT_TYPE_HEADER])) {
  350. $headers[self::S3_CONTENT_TYPE_HEADER] = self::getMimeType($object);
  351. }
  352. $response = $this->_makeRequest('PUT', $object, null, $headers, $data);
  353. // Check the MD5 Etag returned by S3 against and MD5 of the buffer
  354. if ($response->getStatus() == 200) {
  355. // It is escaped by double quotes for some reason
  356. $etag = str_replace('"', '', $response->getHeader('Etag'));
  357. if (is_resource($data) || $etag == md5($data)) {
  358. return true;
  359. }
  360. }
  361. return false;
  362. }
  363. /**
  364. * Put file to S3 as object
  365. *
  366. * @param string $path File name
  367. * @param string $object Object name
  368. * @param array $meta Metadata
  369. * @return boolean
  370. */
  371. public function putFile($path, $object, $meta=null)
  372. {
  373. $data = @file_get_contents($path);
  374. if ($data === false) {
  375. /**
  376. * @see Zend_Service_Amazon_S3_Exception
  377. */
  378. throw new Zend_Service_Amazon_S3_Exception("Cannot read file $path");
  379. }
  380. if (!is_array($meta)) {
  381. $meta = array();
  382. }
  383. if (!isset($meta[self::S3_CONTENT_TYPE_HEADER])) {
  384. $meta[self::S3_CONTENT_TYPE_HEADER] = self::getMimeType($path);
  385. }
  386. return $this->putObject($object, $data, $meta);
  387. }
  388. /**
  389. * Put file to S3 as object, using streaming
  390. *
  391. * @param string $path File name
  392. * @param string $object Object name
  393. * @param array $meta Metadata
  394. * @return boolean
  395. */
  396. public function putFileStream($path, $object, $meta=null)
  397. {
  398. $data = @fopen($path, "rb");
  399. if ($data === false) {
  400. /**
  401. * @see Zend_Service_Amazon_S3_Exception
  402. */
  403. throw new Zend_Service_Amazon_S3_Exception("Cannot open file $path");
  404. }
  405. if (!is_array($meta)) {
  406. $meta = array();
  407. }
  408. if (!isset($meta[self::S3_CONTENT_TYPE_HEADER])) {
  409. $meta[self::S3_CONTENT_TYPE_HEADER] = self::getMimeType($path);
  410. }
  411. if(!isset($meta['Content-MD5'])) {
  412. $headers['Content-MD5'] = base64_encode(md5_file($path, true));
  413. }
  414. return $this->putObject($object, $data, $meta);
  415. }
  416. /**
  417. * Remove a given object
  418. *
  419. * @param string $object
  420. * @return boolean
  421. */
  422. public function removeObject($object)
  423. {
  424. $object = $this->_fixupObjectName($object);
  425. $response = $this->_makeRequest('DELETE', $object);
  426. // Look for a 204 No Content response
  427. return ($response->getStatus() == 204);
  428. }
  429. /**
  430. * Make a request to Amazon S3
  431. *
  432. * @param string $method Request method
  433. * @param string $path Path to requested object
  434. * @param array $params Request parameters
  435. * @param array $headers HTTP headers
  436. * @param string|resource $data Request data
  437. * @return Zend_Http_Response
  438. */
  439. public function _makeRequest($method, $path='', $params=null, $headers=array(), $data=null)
  440. {
  441. $retry_count = 0;
  442. if (!is_array($headers)) {
  443. $headers = array($headers);
  444. }
  445. $headers['Date'] = gmdate(DATE_RFC1123, time());
  446. if(is_resource($data) && $method != 'PUT') {
  447. /**
  448. * @see Zend_Service_Amazon_S3_Exception
  449. */
  450. throw new Zend_Service_Amazon_S3_Exception("Only PUT request supports stream data");
  451. }
  452. // build the end point out
  453. $parts = explode('/', $path, 2);
  454. $endpoint = clone($this->_endpoint);
  455. if ($parts[0]) {
  456. // prepend bucket name to the hostname
  457. $endpoint->setHost($parts[0].'.'.$endpoint->getHost());
  458. }
  459. if (!empty($parts[1])) {
  460. $endpoint->setPath('/'.$parts[1]);
  461. }
  462. else {
  463. $endpoint->setPath('/');
  464. if ($parts[0]) {
  465. $path = $parts[0].'/';
  466. }
  467. }
  468. self::addSignature($method, $path, $headers);
  469. $client = self::getHttpClient();
  470. $client->resetParameters();
  471. $client->setUri($endpoint);
  472. $client->setAuth(false);
  473. // Work around buglet in HTTP client - it doesn't clean headers
  474. // Remove when ZHC is fixed
  475. $client->setHeaders(array('Content-MD5' => null,
  476. 'Expect' => null,
  477. 'Range' => null,
  478. 'x-amz-acl' => null));
  479. $client->setHeaders($headers);
  480. if (is_array($params)) {
  481. foreach ($params as $name=>$value) {
  482. $client->setParameterGet($name, $value);
  483. }
  484. }
  485. if (($method == 'PUT') && ($data !== null)) {
  486. if (!isset($headers['Content-type'])) {
  487. $headers['Content-type'] = self::getMimeType($path);
  488. }
  489. $client->setRawData($data, $headers['Content-type']);
  490. }
  491. do {
  492. $retry = false;
  493. $response = $client->request($method);
  494. $response_code = $response->getStatus();
  495. // Some 5xx errors are expected, so retry automatically
  496. if ($response_code >= 500 && $response_code < 600 && $retry_count <= 5) {
  497. $retry = true;
  498. $retry_count++;
  499. sleep($retry_count / 4 * $retry_count);
  500. }
  501. else if ($response_code == 307) {
  502. // Need to redirect, new S3 endpoint given
  503. // This should never happen as Zend_Http_Client will redirect automatically
  504. }
  505. else if ($response_code == 100) {
  506. // echo 'OK to Continue';
  507. }
  508. } while ($retry);
  509. return $response;
  510. }
  511. /**
  512. * Add the S3 Authorization signature to the request headers
  513. *
  514. * @param string $method
  515. * @param string $path
  516. * @param array &$headers
  517. * @return string
  518. */
  519. protected function addSignature($method, $path, &$headers)
  520. {
  521. if (!is_array($headers)) {
  522. $headers = array($headers);
  523. }
  524. $type = $md5 = $date = '';
  525. // Search for the Content-type, Content-MD5 and Date headers
  526. foreach ($headers as $key=>$val) {
  527. if (strcasecmp($key, 'content-type') == 0) {
  528. $type = $val;
  529. }
  530. else if (strcasecmp($key, 'content-md5') == 0) {
  531. $md5 = $val;
  532. }
  533. else if (strcasecmp($key, 'date') == 0) {
  534. $date = $val;
  535. }
  536. }
  537. // If we have an x-amz-date header, use that instead of the normal Date
  538. if (isset($headers['x-amz-date']) && isset($date)) {
  539. $date = '';
  540. }
  541. $sig_str = "$method\n$md5\n$type\n$date\n";
  542. // For x-amz- headers, combine like keys, lowercase them, sort them
  543. // alphabetically and remove excess spaces around values
  544. $amz_headers = array();
  545. foreach ($headers as $key=>$val) {
  546. $key = strtolower($key);
  547. if (substr($key, 0, 6) == 'x-amz-') {
  548. if (is_array($val)) {
  549. $amz_headers[$key] = $val;
  550. }
  551. else {
  552. $amz_headers[$key][] = preg_replace('/\s+/', ' ', $val);
  553. }
  554. }
  555. }
  556. if (!empty($amz_headers)) {
  557. ksort($amz_headers);
  558. foreach ($amz_headers as $key=>$val) {
  559. $sig_str .= $key.':'.implode(',', $val)."\n";
  560. }
  561. }
  562. $sig_str .= '/'.parse_url($path, PHP_URL_PATH);
  563. if (strpos($path, '?location') !== false) {
  564. $sig_str .= '?location';
  565. }
  566. else if (strpos($path, '?acl') !== false) {
  567. $sig_str .= '?acl';
  568. }
  569. else if (strpos($path, '?torrent') !== false) {
  570. $sig_str .= '?torrent';
  571. }
  572. $signature = base64_encode(Zend_Crypt_Hmac::compute($this->_getSecretKey(), 'sha1', utf8_encode($sig_str), Zend_Crypt_Hmac::BINARY));
  573. $headers['Authorization'] = 'AWS '.$this->_getAccessKey().':'.$signature;
  574. return $sig_str;
  575. }
  576. /**
  577. * Attempt to get the content-type of a file based on the extension
  578. *
  579. * @param string $path
  580. * @return string
  581. */
  582. public static function getMimeType($path)
  583. {
  584. $ext = substr(strrchr($path, '.'), 1);
  585. if(!$ext) {
  586. // shortcut
  587. return 'binary/octet-stream';
  588. }
  589. switch (strtolower($ext)) {
  590. case 'xls':
  591. $content_type = 'application/excel';
  592. break;
  593. case 'hqx':
  594. $content_type = 'application/macbinhex40';
  595. break;
  596. case 'doc':
  597. case 'dot':
  598. case 'wrd':
  599. $content_type = 'application/msword';
  600. break;
  601. case 'pdf':
  602. $content_type = 'application/pdf';
  603. break;
  604. case 'pgp':
  605. $content_type = 'application/pgp';
  606. break;
  607. case 'ps':
  608. case 'eps':
  609. case 'ai':
  610. $content_type = 'application/postscript';
  611. break;
  612. case 'ppt':
  613. $content_type = 'application/powerpoint';
  614. break;
  615. case 'rtf':
  616. $content_type = 'application/rtf';
  617. break;
  618. case 'tgz':
  619. case 'gtar':
  620. $content_type = 'application/x-gtar';
  621. break;
  622. case 'gz':
  623. $content_type = 'application/x-gzip';
  624. break;
  625. case 'php':
  626. case 'php3':
  627. case 'php4':
  628. $content_type = 'application/x-httpd-php';
  629. break;
  630. case 'js':
  631. $content_type = 'application/x-javascript';
  632. break;
  633. case 'ppd':
  634. case 'psd':
  635. $content_type = 'application/x-photoshop';
  636. break;
  637. case 'swf':
  638. case 'swc':
  639. case 'rf':
  640. $content_type = 'application/x-shockwave-flash';
  641. break;
  642. case 'tar':
  643. $content_type = 'application/x-tar';
  644. break;
  645. case 'zip':
  646. $content_type = 'application/zip';
  647. break;
  648. case 'mid':
  649. case 'midi':
  650. case 'kar':
  651. $content_type = 'audio/midi';
  652. break;
  653. case 'mp2':
  654. case 'mp3':
  655. case 'mpga':
  656. $content_type = 'audio/mpeg';
  657. break;
  658. case 'ra':
  659. $content_type = 'audio/x-realaudio';
  660. break;
  661. case 'wav':
  662. $content_type = 'audio/wav';
  663. break;
  664. case 'bmp':
  665. $content_type = 'image/bitmap';
  666. break;
  667. case 'gif':
  668. $content_type = 'image/gif';
  669. break;
  670. case 'iff':
  671. $content_type = 'image/iff';
  672. break;
  673. case 'jb2':
  674. $content_type = 'image/jb2';
  675. break;
  676. case 'jpg':
  677. case 'jpe':
  678. case 'jpeg':
  679. $content_type = 'image/jpeg';
  680. break;
  681. case 'jpx':
  682. $content_type = 'image/jpx';
  683. break;
  684. case 'png':
  685. $content_type = 'image/png';
  686. break;
  687. case 'tif':
  688. case 'tiff':
  689. $content_type = 'image/tiff';
  690. break;
  691. case 'wbmp':
  692. $content_type = 'image/vnd.wap.wbmp';
  693. break;
  694. case 'xbm':
  695. $content_type = 'image/xbm';
  696. break;
  697. case 'css':
  698. $content_type = 'text/css';
  699. break;
  700. case 'txt':
  701. $content_type = 'text/plain';
  702. break;
  703. case 'htm':
  704. case 'html':
  705. $content_type = 'text/html';
  706. break;
  707. case 'xml':
  708. $content_type = 'text/xml';
  709. break;
  710. case 'xsl':
  711. $content_type = 'text/xsl';
  712. break;
  713. case 'mpg':
  714. case 'mpe':
  715. case 'mpeg':
  716. $content_type = 'video/mpeg';
  717. break;
  718. case 'qt':
  719. case 'mov':
  720. $content_type = 'video/quicktime';
  721. break;
  722. case 'avi':
  723. $content_type = 'video/x-ms-video';
  724. break;
  725. case 'eml':
  726. $content_type = 'message/rfc822';
  727. break;
  728. default:
  729. $content_type = 'binary/octet-stream';
  730. break;
  731. }
  732. return $content_type;
  733. }
  734. /**
  735. * Register this object as stream wrapper client
  736. *
  737. * @param string $name
  738. * @return Zend_Service_Amazon_S3
  739. */
  740. public function registerAsClient($name)
  741. {
  742. self::$_wrapperClients[$name] = $this;
  743. return $this;
  744. }
  745. /**
  746. * Unregister this object as stream wrapper client
  747. *
  748. * @param string $name
  749. * @return Zend_Service_Amazon_S3
  750. */
  751. public function unregisterAsClient($name)
  752. {
  753. unset(self::$_wrapperClients[$name]);
  754. return $this;
  755. }
  756. /**
  757. * Get wrapper client for stream type
  758. *
  759. * @param string $name
  760. * @return Zend_Service_Amazon_S3
  761. */
  762. public static function getWrapperClient($name)
  763. {
  764. return self::$_wrapperClients[$name];
  765. }
  766. /**
  767. * Register this object as stream wrapper
  768. *
  769. * @param string $name
  770. * @return Zend_Service_Amazon_S3
  771. */
  772. public function registerStreamWrapper($name='s3')
  773. {
  774. /**
  775. * @see Zend_Service_Amazon_S3_Stream
  776. */
  777. stream_register_wrapper($name, 'Zend_Service_Amazon_S3_Stream');
  778. $this->registerAsClient($name);
  779. }
  780. /**
  781. * Unregister this object as stream wrapper
  782. *
  783. * @param string $name
  784. * @return Zend_Service_Amazon_S3
  785. */
  786. public function unregisterStreamWrapper($name='s3')
  787. {
  788. stream_wrapper_unregister($name);
  789. $this->unregisterAsClient($name);
  790. }
  791. }