diff --git a/README.md b/README.md index 6643f90b..04ad3436 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,24 @@ Save an object to a resource of any type: ```php S3::getObject($bucketName, $uploadName, fopen('savefile.txt', 'wb')) ``` +#### This fork adds the ability to grab ranges of HTTP requests. +Get an object range of bytes: + +```php +S3::getObject($bucketName, $uploadName, array(1,10)) +``` + +Save an object to file: + +```php +S3::getObject($bucketName, $uploadName, $saveName, array(2048-16384)) +``` + +Save an object to a resource of any type: + +```php +S3::getObject($bucketName, $uploadName, fopen('savefile.txt', 'wb'), array(1,100)) +``` #### Copying and deleting objects diff --git a/S3.php b/S3.php index 70e305e4..86dfe8ac 100644 --- a/S3.php +++ b/S3.php @@ -34,6 +34,13 @@ * @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class * @version 0.5.0-dev */ +// Check for CURL +if (!extension_loaded('curl') && !@dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) + throw new Exception("\nERROR: CURL extension not available and dynamic loading failed\n\n"); + +// Try to use PECL Fileinfo for MIME types: +if (!extension_loaded('fileinfo') && @dl('fileinfo.so')) $_ENV['MAGIC'] = '/usr/share/file/magic'; + class S3 { // ACL flags @@ -337,7 +344,7 @@ public static function listBuckets($detailed = false) { $rest = new S3Request('GET', '', '', self::$endpoint); $rest = $rest->getResponse(); - if ($rest->error === false && $rest->code !== 200) + if ($rest->error === false && $rest->code !== 200 ) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { @@ -697,12 +704,25 @@ public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_ * * @param string $bucket Bucket name * @param string $uri Object URI - * @param mixed $saveTo Filename or resource to write to + * @param mixed $saveto_or_range Filename or resource to write to, or an array which represents the range of bytes to retrieve + * @param mixed $range An array which represents the range of bytes to retrieve * @return mixed */ - public static function getObject($bucket, $uri, $saveTo = false) - { - $rest = new S3Request('GET', $bucket, $uri, self::$endpoint); + public static function getObject($bucket, $uri, $saveto_or_range = null, $range=null) + { $saveTo = false; + + if(isset($range)) { + $saveTo = $saveto_or_range; + } elseif(isset($saveto_or_range)) { + if(is_array($saveto_or_range)) { + $range = $saveto_or_range; + } else { + $saveTo = $saveto_or_range; + $range = false; + } + } + + $rest = new S3Request('GET', $bucket, $uri, self::$endpoint, $range); if ($saveTo !== false) { if (is_resource($saveTo)) @@ -710,13 +730,15 @@ public static function getObject($bucket, $uri, $saveTo = false) else if (($rest->fp = @fopen($saveTo, 'wb')) !== false) $rest->file = realpath($saveTo); - else + else $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo); + } - if ($rest->response->error === false) $rest->getResponse(); + if(($saveTo && $rest->fp) || (!$saveTo)) $rest->getResponse(); - if ($rest->response->error === false && $rest->response->code !== 200) + if ($rest->response->error === false && ($rest->response->code !== 200 && $rest->response->code !== 206)) $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); + if ($rest->response->error !== false) { self::__triggerError(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s", @@ -1949,6 +1971,7 @@ final class S3Request */ public $response; + private $range = null; /** * Constructor @@ -1957,9 +1980,10 @@ final class S3Request * @param string $bucket Bucket name * @param string $uri Object URI * @param string $endpoint AWS endpoint URI + * @param array $endpoint Array that has start and end bytes * @return mixed */ - function __construct($verb, $bucket = '', $uri = '', $endpoint = 's3.amazonaws.com') + function __construct($verb, $bucket = '', $uri = '', $endpoint = 's3.amazonaws.com', $range=null) { $this->endpoint = $endpoint; @@ -1967,6 +1991,12 @@ function __construct($verb, $bucket = '', $uri = '', $endpoint = 's3.amazonaws.c $this->bucket = $bucket; $this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/'; + if(isset($range) && $range !== null) { + $this->range = $range; + } else { + unset($this->range); + } + //if ($this->bucket !== '') // $this->resource = '/'.$this->bucket.$this->uri; //else @@ -2074,6 +2104,8 @@ public function getResponse() $curl = curl_init(); curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php'); + if(isset($this->range)) curl_setopt($curl, CURLOPT_RANGE, $this->range[0] . "-" . $this->range[1]); + if (S3::$useSSL) { // SSL Validation can now be optional for those with broken OpenSSL installations