PHP S3 Download Progress

This happens many times, but I'm still a little puzzled. Many answers only confirm that they are talking about content loading bars and do not get the actual download result from the S3 download.

I read a number of questions and found several pieces of software, but I'm still not closer to understanding the fundamental issue of loading S3.

Is there a way to boot to S3, understanding the progress of this download, without using the application serverโ€™s own resources, to save the file in the temp directory first?

Do I need to first store the file on my own server, and then click on S3? I heard people talking about a bit stream at a time to S3 (one piece at a time), but I'm not sure what that means. Imagine that I was loading from the client side on an HTML page, how could I transfer a file stream with a piece of several parts from what is included? (I see no example of that, only an example of when the file is already on your system, and you know the pieces that are useless tbh).

The API docs, of course, have an example of download progress, but again, assuming the file is located on your server and does not come from another computer provided by the user.

EDIT: My initial thought was to create a PHP script that could ping AWS once so that each gets a boot process. I look through the API to see if they support something similar, but no luck. Let me know if there is anything ...

Next EDIT: Is flash the only way to do this?

Thanks,

+6
source share
5 answers

YES , this is possible in the AWS PHP SDK v3.

$client = new S3Client(/* config */); $result = $client->putObject([ 'Bucket' => 'bucket-name', 'Key' => 'bucket-name/file.ext', 'SourceFile' => 'local-file.ext', 'ContentType' => 'application/pdf', '@http' => [ 'progress' => function ($downloadTotalSize, $downloadSizeSoFar, $uploadTotalSize, $uploadSizeSoFar) { printf( "%s of %s downloaded, %s of %s uploaded.\n", $downloadSizeSoFar, $downloadTotalSize, $uploadSizeSoFar, $uploadTotalSize ); } ] ]); 

This is explained in AWS docs - Section S3 Config . It works by exposing GuzzleHttp progress property called, as described in this SO answer .

+3
source

After much searching, I found a simple answer to this question: NO.

Basically, the best way to do this, as I learned from Amazons' own coding (their small loading widget on the AWS S3 console), is it really possible to make progress on loading by sending it to another server that can read PHP first to get progress information .

This creates an end-to-end policy using native / tmp application servers as a step. This is apparently the preferred method.

0
source

The AWS PHP SDK has sample code where they show the progress of loading on boot to S3. I'm not sure if it is valid for small files, but it works for streaming.

You can find out more - http://aws.amazon.com/sdkforphp/

In a sense, if they show progress - we can certainly get it as a progress bar using a Javascript framework like jquery, etc.

I will work on this very soon and will definitely publish a textbook. Hurrah!

0
source

Yes, you can via multi-page download: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMPphpAPI.html

Multipage loading is a three-step process: you initiate a download, load parts of an object, and after you have downloaded all the parts, you will perform a multi-page download. With a full multi-page download request, Amazon S3 constructs the object from the loaded parts, and you can access the object just like any other object in your bucket.

http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html

I will do it personally very soon, but this is what you need to start.

0
source

Yes, you can do this by changing s3.php as follows:

 <?php class S3Withprogressbar { // ACL flags const ACL_PRIVATE = 'private'; const ACL_PUBLIC_READ = 'public-read'; const ACL_PUBLIC_READ_WRITE = 'public-read-write'; private static $__accessKey; // AWS Access key private static $__secretKey; // AWS Secret key public static $_uploadProgressFileName="" ;//uploadProgressFileName public function __construct($accessKey = null, $secretKey = null) { if ($accessKey !== null && $secretKey !== null) self::setAuth($accessKey, $secretKey); } public static function setAuth($accessKey, $secretKey) { self::$__accessKey = $accessKey; self::$__secretKey = $secretKey; } public static function listBuckets($detailed = false) { $rest = new S3Request('GET', '', ''); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 200) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::listBuckets(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } $results = array(); //var_dump($rest->body); if (!isset($rest->body->Buckets)) return $results; if ($detailed) { if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) $results['owner'] = array( 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID ); $results['buckets'] = array(); foreach ($rest->body->Buckets->Bucket as $b) $results['buckets'][] = array( 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate) ); } else foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name; return $results; } public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null) { $rest = new S3Request('GET', $bucket, ''); if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix); if ($marker !== null && $prefix !== '') $rest->setParameter('marker', $marker); if ($maxKeys !== null && $prefix !== '') $rest->setParameter('max-keys', $maxKeys); $response = $rest->getResponse(); if ($response->error === false && $response->code !== 200) $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status'); if ($response->error !== false) { trigger_error(sprintf("S3Withprogressbar::getBucket(): [%s] %s", $response->error['code'], $response->error['message']), E_USER_WARNING); return false; } $results = array(); $lastMarker = null; if (isset($response->body, $response->body->Contents)) foreach ($response->body->Contents as $c) { $results[(string)$c->Key] = array( 'name' => (string)$c->Key, 'time' => strToTime((string)$c->LastModified), 'size' => (int)$c->Size, 'hash' => substr((string)$c->ETag, 1, -1) ); $lastMarker = (string)$c->Key; //$response->body->IsTruncated = 'true'; break; } if (isset($response->body->IsTruncated) && (string)$response->body->IsTruncated == 'false') return $results; // Loop through truncated results if maxKeys isn't specified if ($maxKeys == null && $lastMarker !== null && (string)$response->body->IsTruncated == 'true') do { $rest = new S3Request('GET', $bucket, ''); if ($prefix !== null) $rest->setParameter('prefix', $prefix); $rest->setParameter('marker', $lastMarker); if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break; if (isset($response->body, $response->body->Contents)) foreach ($response->body->Contents as $c) { $results[(string)$c->Key] = array( 'name' => (string)$c->Key, 'time' => strToTime((string)$c->LastModified), 'size' => (int)$c->Size, 'hash' => substr((string)$c->ETag, 1, -1) ); $lastMarker = (string)$c->Key; } } while ($response !== false && (string)$response->body->IsTruncated == 'true'); return $results; } public function putBucket($bucket, $acl = self::ACL_PRIVATE) { $rest = new S3Request('PUT', $bucket, ''); $rest->setAmzHeader('x-amz-acl', $acl); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 200) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { //trigger_error(sprintf("S3Withprogressbar::putBucket({$bucket}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } return true; } public function deleteBucket($bucket = '') { $rest = new S3Request('DELETE', $bucket); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 204) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::deleteBucket({$bucket}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } return true; } public static function inputFile($file, $md5sum = true) { if (!file_exists($file) || !is_file($file) || !is_readable($file)) { trigger_error('S3Withprogressbar::inputFile(): Unable to open input file: '.$file, E_USER_WARNING); return false; } return array('file' => $file, 'size' => filesize($file), 'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum : base64_encode(md5_file($file, true))) : ''); } public static function inputResource(&$resource, $bufferSize, $md5sum = '') { if (!is_resource($resource) || $bufferSize <= 0) { trigger_error('S3Withprogressbar::inputResource(): Invalid resource or buffer size', E_USER_WARNING); return false; } $input = array('size' => $bufferSize, 'md5sum' => $md5sum); $input['fp'] =& $resource; return $input; } // Modified Function with one more parameter $uploadProgressFileName public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null,$uploadProgressFileName) { if ($input == false) return false; $rest = new S3Request('PUT', $bucket, $uri); // Set public variable value($uploadProgressFileName) in S3Request class $rest->uploadProgressFileName = $uploadProgressFileName; if (is_string($input)) $input = array( 'data' => $input, 'size' => strlen($input), 'md5sum' => base64_encode(md5($input, true)) ); // Data if (isset($input['fp'])) $rest->fp =& $input['fp']; elseif (isset($input['file'])) $rest->fp = @fopen($input['file'], 'rb'); elseif (isset($input['data'])) $rest->data = $input['data']; // Content-Length (required) if (isset($input['size']) && $input['size'] > 0) $rest->size = $input['size']; else { if (isset($input['file'])) $rest->size = filesize($input['file']); elseif (isset($input['data'])) $rest->size = strlen($input['data']); } // Content-Type if ($contentType !== null) $input['type'] = $contentType; elseif (!isset($input['type']) && isset($input['file'])) $input['type'] = self::__getMimeType($input['file']); else $input['type'] = 'application/octet-stream'; // We need to post with the content-length and content-type, MD5 is optional if ($rest->size > 0 && ($rest->fp !== false || $rest->data !== false)) { $rest->setHeader('Content-Type', $input['type']); if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']); $rest->setAmzHeader('x-amz-acl', $acl); foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v); $rest->getResponse(); } else $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters'); if ($rest->response->error === false && $rest->response->code !== 200) $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); if ($rest->response->error !== false) { //trigger_error(sprintf("S3Withprogressbar::putObject(): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING); return false; } return true; } // Modified Function with one more parameter $uploadProgressFileName public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null,$uploadProgressFileName) { return self::putObject(S3Withprogressbar::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType,$uploadProgressFileName); } public function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain') { return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType); } public static function getObject($bucket = '', $uri = '', $saveTo = false) { $rest = new S3Request('GET', $bucket, $uri); if ($saveTo !== false) { if (is_resource($saveTo)) $rest->fp =& $saveTo; else if (($rest->fp = @fopen($saveTo, 'wb')) == false) $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo); } if ($rest->response->error === false) $rest->getResponse(); if ($rest->response->error === false && $rest->response->code !== 200) $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status'); if ($rest->response->error !== false) { trigger_error(sprintf("S3Withprogressbar::getObject({$bucket}, {$uri}): [%s] %s", $rest->response->error['code'], $rest->response->error['message']), E_USER_WARNING); return false; } $rest->file = realpath($saveTo); return $rest->response; } public static function getObjectInfo($bucket = '', $uri = '', $returnInfo = true) { $rest = new S3Request('HEAD', $bucket, $uri); $rest = $rest->getResponse(); if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404)) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::getObjectInfo({$bucket}, {$uri}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false; } public static function setBucketLogging($bucket, $targetBucket, $targetPrefix) { $dom = new DOMDocument; $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus'); $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); $loggingEnabled = $dom->createElement('LoggingEnabled'); $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket)); $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix)); // TODO: Add TargetGrants $bucketLoggingStatus->appendChild($loggingEnabled); $dom->appendChild($bucketLoggingStatus); $rest = new S3Request('PUT', $bucket, ''); $rest->setParameter('logging', null); $rest->data = $dom->saveXML(); $rest->size = strlen($rest->data); $rest->setHeader('Content-Type', 'application/xml'); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 200) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::setBucketLogging({$bucket}, {$uri}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } return true; } public static function getBucketLogging($bucket = '') { $rest = new S3Request('GET', $bucket, ''); $rest->setParameter('logging', null); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 200) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::getBucketLogging({$bucket}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } if (!isset($rest->body->LoggingEnabled)) return false; // No logging return array( 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket, 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix, ); } public static function setAccessControlPolicy($bucket, $uri = '', $acp = array()) { $dom = new DOMDocument; $dom->formatOutput = true; $accessControlPolicy = $dom->createElement('AccessControlPolicy'); $accessControlList = $dom->createElement('AccessControlList'); // It seems the owner has to be passed along too $owner = $dom->createElement('Owner'); $owner->appendChild($dom->createElement('ID', $acp['owner']['id'])); $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name'])); $accessControlPolicy->appendChild($owner); foreach ($acp['acl'] as $g) { $grant = $dom->createElement('Grant'); $grantee = $dom->createElement('Grantee'); $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); if (isset($g['id'])) { // CanonicalUser (DisplayName is omitted) $grantee->setAttribute('xsi:type', 'CanonicalUser'); $grantee->appendChild($dom->createElement('ID', $g['id'])); } elseif (isset($g['email'])) { // AmazonCustomerByEmail $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail'); $grantee->appendChild($dom->createElement('EmailAddress', $g['email'])); } elseif ($g['type'] == 'Group') { // Group $grantee->setAttribute('xsi:type', 'Group'); $grantee->appendChild($dom->createElement('URI', $g['uri'])); } $grant->appendChild($grantee); $grant->appendChild($dom->createElement('Permission', $g['permission'])); $accessControlList->appendChild($grant); } $accessControlPolicy->appendChild($accessControlList); $dom->appendChild($accessControlPolicy); $rest = new S3Request('PUT', $bucket, ''); $rest->setParameter('acl', null); $rest->data = $dom->saveXML(); $rest->size = strlen($rest->data); $rest->setHeader('Content-Type', 'application/xml'); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 200) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } return true; } public static function getAccessControlPolicy($bucket, $uri = '') { $rest = new S3Request('GET', $bucket, $uri); $rest->setParameter('acl', null); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 200) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } $acp = array(); if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName)) { $acp['owner'] = array( 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName ); } if (isset($rest->body->AccessControlList)) { $acp['acl'] = array(); foreach ($rest->body->AccessControlList->Grant as $grant) { foreach ($grant->Grantee as $grantee) { if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser $acp['acl'][] = array( 'type' => 'CanonicalUser', 'id' => (string)$grantee->ID, 'name' => (string)$grantee->DisplayName, 'permission' => (string)$grant->Permission ); elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail $acp['acl'][] = array( 'type' => 'AmazonCustomerByEmail', 'email' => (string)$grantee->EmailAddress, 'permission' => (string)$grant->Permission ); elseif (isset($grantee->URI)) // Group $acp['acl'][] = array( 'type' => 'Group', 'uri' => (string)$grantee->URI, 'permission' => (string)$grant->Permission ); else continue; } } } return $acp; } public static function deleteObject($bucket = '', $uri = '') { $rest = new S3Request('DELETE', $bucket, $uri); $rest = $rest->getResponse(); if ($rest->error === false && $rest->code !== 204) $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status'); if ($rest->error !== false) { trigger_error(sprintf("S3Withprogressbar::deleteObject(): [%s] %s", $rest->error['code'], $rest->error['message']), E_USER_WARNING); return false; } return true; } public static function __getMimeType(&$file) { $type = false; // Fileinfo documentation says fileinfo_open() will use the // MAGIC env var for the magic file if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) && ($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false) { if (($type = finfo_file($finfo, $file)) !== false) { // Remove the charset and grab the last content-type $type = explode(' ', str_replace('; charset=', ';charset=', $type)); $type = array_pop($type); $type = explode(';', $type); $type = array_shift($type); } finfo_close($finfo); // If anyone is still using mime_content_type() } elseif (function_exists('mime_content_type')) $type = mime_content_type($file); if ($type !== false && strlen($type) > 0) return $type; // Otherwise do it the old fashioned way static $exts = array( 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon', 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf', 'zip' => 'application/zip', 'gz' => 'application/x-gzip', 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip', 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain', 'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html', 'xml' => 'text/xml', 'xsl' => 'application/xsl+xml', 'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav', 'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php' ); $ext = strToLower(pathInfo($file, PATHINFO_EXTENSION)); return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream'; } public static function __getSignature($string) { return 'AWS '.self::$__accessKey.':'.base64_encode(extension_loaded('hash') ? hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1( (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) . pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x36), 64))) . $string))))); } } final class S3Request { private $verb, $bucket, $uri, $resource = '', $parameters = array(), $amzHeaders = array(), $headers = array( 'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => '' ); public $fp = false, $size = 0, $data = false, $response; public $uploadProgressFileName; function __construct($verb, $bucket = '', $uri = '') { $this->verb = $verb; $this->bucket = strtolower($bucket); $this->uri = $uri !== '' ? '/'.$uri : '/'; if ($this->bucket !== '') { $this->bucket = explode('/', $this->bucket); $this->resource = '/'.$this->bucket[0].$this->uri; $this->headers['Host'] = $this->bucket[0].'.s3.amazonaws.com'; $this->bucket = implode('/', $this->bucket); } else { $this->headers['Host'] = 's3.amazonaws.com'; if (strlen($this->uri) > 1) $this->resource = '/'.$this->bucket.$this->uri; else $this->resource = $this->uri; } $this->headers['Date'] = gmdate('D, d MYH:i:s T'); $this->response = new STDClass; $this->response->error = false; $this->response->body = false; $CI =& get_instance(); $CI->load->helper('file'); } public function setParameter($key, $value) { $this->parameters[$key] = $value; } public function setHeader($key, $value) { $this->headers[$key] = $value; } public function setAmzHeader($key, $value) { $this->amzHeaders[$key] = $value; } //:callback function for upload progress. public function progressCallback_new_curl($new,$download_size, $downloaded_size, $upload_size, $uploaded_size ) { ob_start(); static $previousProgress = 0; if ( $upload_size == 0 ) $progress = 0; else $progress = round( $uploaded_size * 100 / $upload_size ); if ( $progress > $previousProgress) { flush(); $previousProgress = $progress; $new_file_path = FCPATH.'upload/'.$this->uploadProgressFileName.'.txt'; // modify this line to point to the actual location of the file write_file($new_file_path, $progress."\n"); // Check for Cancel upload text file and if exists return 1 to interrupt curl upload process. $cancel_path=FCPATH.'upload/cancel_'.$this->uploadProgressFileName.'.txt'; if(file_exists($cancel_path)){ unlink($cancel_path); if(file_exists($new_file_path)){ unlink($new_file_path); } return 1; } } ob_flush(); flush(); } public function progressCallback_old_curl($download_size, $downloaded_size, $upload_size, $uploaded_size ) { ob_start(); static $previousProgress = 0; if ( $upload_size == 0 ) $progress = 0; else $progress = round( $uploaded_size * 100 / $upload_size ); if ( $progress > $previousProgress) { flush(); $previousProgress = $progress; $new_file_path = FCPATH.'upload/'.$this->uploadProgressFileName.'.txt'; // modify this line to point to the actual location of the file write_file($new_file_path, $progress."\n"); // Check for Cancel upload text file and if exists return 1 to interrupt curl upload process. $cancel_path=FCPATH.'upload/cancel_'.$this->uploadProgressFileName.'.txt'; if(file_exists($cancel_path)){ unlink($cancel_path); if(file_exists($new_file_path)){ unlink($new_file_path); } return 1; } } ob_flush(); flush(); } public function getResponse() { $query = ''; if (sizeof($this->parameters) > 0) { $query = substr($this->uri, -1) !== '?' ? '?' : '&'; foreach ($this->parameters as $var => $value) if ($value == null || $value == '') $query .= $var.'&'; else $query .= $var.'='.$value.'&'; $query = substr($query, 0, -1); $this->uri .= $query; if (isset($this->parameters['acl']) || !isset($this->parameters['logging'])) $this->resource .= $query; } $url = (extension_loaded('openssl')?'https://':'http://').$this->headers['Host'].$this->uri; //var_dump($this->bucket, $this->uri, $this->resource, $url); // Basic setup $curl = curl_init(); curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php'); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($curl, CURLOPT_URL, $url); //:callback function call for upload progress. curl_setopt($curl, CURLOPT_NOPROGRESS, false); if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50500) { curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, array($this, 'progressCallback_old_curl')); } else { curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, array($this, 'progressCallback_new_curl')); } // Headers $headers = array(); $amz = array(); foreach ($this->amzHeaders as $header => $value) if (strlen($value) > 0) $headers[] = $header.': '.$value; foreach ($this->headers as $header => $value) if (strlen($value) > 0) $headers[] = $header.': '.$value; foreach ($this->amzHeaders as $header => $value) if (strlen($value) > 0) $amz[] = strToLower($header).':'.$value; $amz = (sizeof($amz) > 0) ? "\n".implode("\n", $amz) : ''; // Authorization string $headers[] = 'Authorization: ' . S3Withprogressbar::__getSignature( $this->verb."\n". $this->headers['Content-MD5']."\n". $this->headers['Content-Type']."\n". $this->headers['Date'].$amz."\n".$this->resource ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, false); curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback')); curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback')); // Request types switch ($this->verb) { case 'GET': break; case 'PUT': if ($this->fp !== false) { curl_setopt($curl, CURLOPT_PUT, true); curl_setopt($curl, CURLOPT_INFILE, $this->fp); if ($this->size > 0) curl_setopt($curl, CURLOPT_INFILESIZE, $this->size); } elseif ($this->data !== false) { curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data); if ($this->size > 0) curl_setopt($curl, CURLOPT_BUFFERSIZE, $this->size); } else curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); break; case 'HEAD': curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD'); curl_setopt($curl, CURLOPT_NOBODY, true); break; case 'DELETE': curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); break; default: break; } // Execute, grab errors if (curl_exec($curl)) $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE); else $this->response->error = array( 'code' => curl_errno($curl), 'message' => curl_error($curl), 'resource' => $this->resource ); @curl_close($curl); // Parse body into XML if ($this->response->error === false && isset($this->response->headers['type']) && $this->response->headers['type'] == 'application/xml' && isset($this->response->body)) { $this->response->body = simplexml_load_string($this->response->body); // Grab S3 errors if (!in_array($this->response->code, array(200, 204)) && isset($this->response->body->Code, $this->response->body->Message)) { $this->response->error = array( 'code' => (string)$this->response->body->Code, 'message' => (string)$this->response->body->Message ); if (isset($this->response->body->Resource)) $this->response->error['resource'] = (string)$this->response->body->Resource; unset($this->response->body); } } // Clean up file resources if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp); return $this->response; } private function __responseWriteCallback(&$curl, &$data) { if ($this->response->code == 200 && $this->fp !== false) return fwrite($this->fp, $data); else $this->response->body .= $data; return strlen($data); } private function __responseHeaderCallback(&$curl, &$data) { if (($strlen = strlen($data)) <= 2) return $strlen; if (substr($data, 0, 4) == 'HTTP') $this->response->code = (int)substr($data, 9, 3); else { list($header, $value) = explode(': ', trim($data)); if ($header == 'Last-Modified') $this->response->headers['time'] = strtotime($value); elseif ($header == 'Content-Length') $this->response->headers['size'] = (int)$value; elseif ($header == 'Content-Type') $this->response->headers['type'] = $value; elseif ($header == 'ETag') $this->response->headers['hash'] = substr($value, 1, -1); elseif (preg_match('/^x-amz-meta-.*$/', $header)) $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value; } return $strlen; } } ?> 
-2
source

Source: https://habr.com/ru/post/913393/


All Articles