Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for getting only portions of objects via HTTP range requests #58

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
50 changes: 41 additions & 9 deletions S3.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -697,26 +704,41 @@ 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))
$rest->fp =& $saveTo;
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",
Expand Down Expand Up @@ -1949,6 +1971,7 @@ final class S3Request
*/
public $response;

private $range = null;

/**
* Constructor
Expand All @@ -1957,16 +1980,23 @@ 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;
$this->verb = $verb;
$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
Expand Down Expand Up @@ -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
Expand Down