From 7d0233f5940d034cc2fab6fcec2b73763a489d6b Mon Sep 17 00:00:00 2001 From: Steve Meyers Date: Thu, 11 Oct 2018 16:49:13 -0600 Subject: [PATCH 01/12] Changed mb_strlen() to strlen() for file size calculation The file size was being calculated incorrectly, since it was done in multibyte characters instead of bytes. This resulted in B2 rejecting uploads due to a hash mismatch. --- src/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 15e1281..27ada4f 100755 --- a/src/Client.php +++ b/src/Client.php @@ -200,7 +200,7 @@ public function upload(array $options) } else { // We've been given a simple string body, it's super simple to calculate the hash and size. $hash = sha1($options['Body']); - $size = mb_strlen($options['Body']); + $size = strlen($options['Body']); } if (!isset($options['FileLastModified'])) { From a558389fca56af1b723fd9b97862d5e1ffcb1453 Mon Sep 17 00:00:00 2001 From: Brian Mix Date: Fri, 30 Nov 2018 13:01:25 -0600 Subject: [PATCH 02/12] Added functionality for uploading large files used b2 process for uploading large files... https://www.backblaze.com/b2/docs/large_files.html --- src/Client.php | 167 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/src/Client.php b/src/Client.php index 15e1281..d2379c8 100755 --- a/src/Client.php +++ b/src/Client.php @@ -476,4 +476,171 @@ protected function getFileIdFromBucketAndFileName($bucketName, $fileName) } } } + + /** + * Uploads a large file using b2 large file proceedure + * + * @param $fileName + * @param $filePath + * @param $contentType + * @return \BackblazeB2\File + */ + public function uploadLargeFile($fileName, $filePath, $contentType) + { + // 1) b2_start_large_file, (returns fileId) + $start = $this->startLargeFile($fileName,$contentType); + + // 2) b2_get_upload_part_url for each thread uploading (takes fileId) + $url = $this->getUploadPartUrl($start['fileId']); + + //if last char of path is not a "/" then add a "/" + if(substr($filePath, -1) != '/') { + $filePath = $filePath.'/'; + } + + // 3) b2_upload_part for each part of the file + $parts = $this->uploadParts($filePath.$fileName,$url['uploadUrl'],$url['authorizationToken']); + + $sha1s = []; + + foreach($parts as $part) { + $sha1s[] = $part['contentSha1']; + } + + // 4) b2_finish_large_file. + return $this->finishLargeFile($start['fileId'],$sha1s); + } + + /** + * starts the large file upload process + * + * @param $fileName + * @param $contentType + * @return array + */ + protected function startLargeFile($fileName, $contentType) + { + $response = $this->client->request('POST', $this->apiUrl.'/b2_start_large_file', [ + 'headers' => [ + 'Authorization' => $this->authToken, + ], + 'json' => [ + 'fileName' => $fileName, + 'contentType' => $contentType, + 'bucketId' => $this->getBucketIdFromName(config('filesystems.disks.backblaze.bucketName')), + ] + ]); + + return $response; + } + + /** + * gets the url for the next large file part upload + * + * @param $fileId + * @return array + */ + protected function getUploadPartUrl($fileId) + { + $response = $this->client->request('POST', $this->apiUrl.'/b2_get_upload_part_url', [ + 'headers' => [ + 'Authorization' => $this->authToken, + ], + 'json' => [ + 'fileId' => $fileId, + ], + ]); + + return $response; + } + + /** + * uploads the file as "parts" of 100MB each + * + * @param $filePath + * @param $uploadUrl + * @param $largeFileAuthToken + * @return array + */ + protected function uploadParts($filePath, $uploadUrl, $largeFileAuthToken) + { + $return = []; + + $minimum_part_size = 100 * (1000 * 1000); + + $local_file_size = filesize($filePath); + $total_bytes_sent = 0; + //$bytes_sent_for_part = 0; + $bytes_sent_for_part = $minimum_part_size; + $sha1_of_parts = Array(); + $part_no = 1; + $file_handle = fopen($filePath, "r"); + + while($total_bytes_sent < $local_file_size) { + + // Determine the number of bytes to send based on the minimum part size + if (($local_file_size - $total_bytes_sent) < $minimum_part_size) { + $bytes_sent_for_part = ($local_file_size - $total_bytes_sent); + } + + // Get a sha1 of the part we are going to send + fseek($file_handle, $total_bytes_sent); + $data_part = fread($file_handle, $bytes_sent_for_part); + array_push($sha1_of_parts, sha1($data_part)); + fseek($file_handle, $total_bytes_sent); + + $response = $this->client->request('POST', $uploadUrl, [ + 'headers' => [ + 'Authorization' => $largeFileAuthToken, + 'Content-Length' => $bytes_sent_for_part, + 'X-Bz-Part-Number' => $part_no, + 'X-Bz-Content-Sha1' => $sha1_of_parts[$part_no - 1], + ], + 'body' => $data_part, + ]); + + $return[] = $response; + + // Prepare for the next iteration of the loop + $part_no++; + $total_bytes_sent = $bytes_sent_for_part + $total_bytes_sent; + //$read_file_bytes_read = 0; + } + + fclose($file_handle); + + return $return; + } + + /** + * finishes the large file upload proceedure + * + * @param $fileId + * @param array $sha1s + * @return File + */ + protected function finishLargeFile($fileId, Array $sha1s) + { + $response = $this->client->request('POST', $this->apiUrl.'/b2_finish_large_file', [ + 'headers' => [ + 'Authorization' => $this->authToken, + ], + 'json' => [ + 'fileId' => $fileId, + 'partSha1Array' => $sha1s, + ], + ]); + + return new File( + $response['fileId'], + $response['fileName'], + $response['contentSha1'], + $response['contentLength'], + $response['contentType'], + $response['fileInfo'], + $response['bucketId'], + $response['action'], + $response['uploadTimestamp'] + ); + } } From d286c09c548043b20582b10f3c1621b0c9fe72b7 Mon Sep 17 00:00:00 2001 From: Brian Mix Date: Fri, 30 Nov 2018 13:03:11 -0600 Subject: [PATCH 03/12] removed some comments --- src/Client.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Client.php b/src/Client.php index d2379c8..15c47f4 100755 --- a/src/Client.php +++ b/src/Client.php @@ -570,7 +570,6 @@ protected function uploadParts($filePath, $uploadUrl, $largeFileAuthToken) $local_file_size = filesize($filePath); $total_bytes_sent = 0; - //$bytes_sent_for_part = 0; $bytes_sent_for_part = $minimum_part_size; $sha1_of_parts = Array(); $part_no = 1; @@ -604,7 +603,6 @@ protected function uploadParts($filePath, $uploadUrl, $largeFileAuthToken) // Prepare for the next iteration of the loop $part_no++; $total_bytes_sent = $bytes_sent_for_part + $total_bytes_sent; - //$read_file_bytes_read = 0; } fclose($file_handle); From f549bdd51f6e42bcfc143b9d5f4141f25c230a98 Mon Sep 17 00:00:00 2001 From: Brian Mix Date: Fri, 30 Nov 2018 13:10:24 -0600 Subject: [PATCH 04/12] styleCI --- src/Client.php | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/Client.php b/src/Client.php index 15c47f4..7ba7677 100755 --- a/src/Client.php +++ b/src/Client.php @@ -478,7 +478,7 @@ protected function getFileIdFromBucketAndFileName($bucketName, $fileName) } /** - * Uploads a large file using b2 large file proceedure + * Uploads a large file using b2 large file proceedure. * * @param $fileName * @param $filePath @@ -488,34 +488,35 @@ protected function getFileIdFromBucketAndFileName($bucketName, $fileName) public function uploadLargeFile($fileName, $filePath, $contentType) { // 1) b2_start_large_file, (returns fileId) - $start = $this->startLargeFile($fileName,$contentType); + $start = $this->startLargeFile($fileName, $contentType); // 2) b2_get_upload_part_url for each thread uploading (takes fileId) $url = $this->getUploadPartUrl($start['fileId']); //if last char of path is not a "/" then add a "/" - if(substr($filePath, -1) != '/') { + if (substr($filePath, -1) != '/') { $filePath = $filePath.'/'; } // 3) b2_upload_part for each part of the file - $parts = $this->uploadParts($filePath.$fileName,$url['uploadUrl'],$url['authorizationToken']); + $parts = $this->uploadParts($filePath.$fileName, $url['uploadUrl'], $url['authorizationToken']); $sha1s = []; - foreach($parts as $part) { + foreach ($parts as $part) { $sha1s[] = $part['contentSha1']; } // 4) b2_finish_large_file. - return $this->finishLargeFile($start['fileId'],$sha1s); + return $this->finishLargeFile($start['fileId'], $sha1s); } /** - * starts the large file upload process + * starts the large file upload process. * * @param $fileName * @param $contentType + * * @return array */ protected function startLargeFile($fileName, $contentType) @@ -525,9 +526,9 @@ protected function startLargeFile($fileName, $contentType) 'Authorization' => $this->authToken, ], 'json' => [ - 'fileName' => $fileName, - 'contentType' => $contentType, - 'bucketId' => $this->getBucketIdFromName(config('filesystems.disks.backblaze.bucketName')), + 'fileName' => $fileName, + 'contentType' => $contentType, + 'bucketId' => $this->getBucketIdFromName(config('filesystems.disks.backblaze.bucketName')), ] ]); @@ -535,9 +536,10 @@ protected function startLargeFile($fileName, $contentType) } /** - * gets the url for the next large file part upload + * gets the url for the next large file part upload. * * @param $fileId + * * @return array */ protected function getUploadPartUrl($fileId) @@ -555,11 +557,12 @@ protected function getUploadPartUrl($fileId) } /** - * uploads the file as "parts" of 100MB each + * uploads the file as "parts" of 100MB each. * * @param $filePath * @param $uploadUrl * @param $largeFileAuthToken + * * @return array */ protected function uploadParts($filePath, $uploadUrl, $largeFileAuthToken) @@ -571,11 +574,11 @@ protected function uploadParts($filePath, $uploadUrl, $largeFileAuthToken) $local_file_size = filesize($filePath); $total_bytes_sent = 0; $bytes_sent_for_part = $minimum_part_size; - $sha1_of_parts = Array(); + $sha1_of_parts = []; $part_no = 1; - $file_handle = fopen($filePath, "r"); + $file_handle = fopen($filePath, 'r'); - while($total_bytes_sent < $local_file_size) { + while ($total_bytes_sent < $local_file_size) { // Determine the number of bytes to send based on the minimum part size if (($local_file_size - $total_bytes_sent) < $minimum_part_size) { @@ -611,20 +614,21 @@ protected function uploadParts($filePath, $uploadUrl, $largeFileAuthToken) } /** - * finishes the large file upload proceedure + * finishes the large file upload proceedure. * * @param $fileId * @param array $sha1s + * * @return File */ - protected function finishLargeFile($fileId, Array $sha1s) + protected function finishLargeFile($fileId, array $sha1s) { $response = $this->client->request('POST', $this->apiUrl.'/b2_finish_large_file', [ 'headers' => [ 'Authorization' => $this->authToken, ], 'json' => [ - 'fileId' => $fileId, + 'fileId' => $fileId, 'partSha1Array' => $sha1s, ], ]); From 891d5df4f334f91e94f3c85153ba75de84afbef5 Mon Sep 17 00:00:00 2001 From: Brian Mix Date: Fri, 30 Nov 2018 13:13:25 -0600 Subject: [PATCH 05/12] more styleCI --- src/Client.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Client.php b/src/Client.php index 7ba7677..eee824d 100755 --- a/src/Client.php +++ b/src/Client.php @@ -476,13 +476,14 @@ protected function getFileIdFromBucketAndFileName($bucketName, $fileName) } } } - + /** * Uploads a large file using b2 large file proceedure. * * @param $fileName * @param $filePath * @param $contentType + * * @return \BackblazeB2\File */ public function uploadLargeFile($fileName, $filePath, $contentType) @@ -529,7 +530,7 @@ protected function startLargeFile($fileName, $contentType) 'fileName' => $fileName, 'contentType' => $contentType, 'bucketId' => $this->getBucketIdFromName(config('filesystems.disks.backblaze.bucketName')), - ] + ], ]); return $response; @@ -615,7 +616,7 @@ protected function uploadParts($filePath, $uploadUrl, $largeFileAuthToken) /** * finishes the large file upload proceedure. - * + * * @param $fileId * @param array $sha1s * From 959af50e130088fdfb05b8e6cb5e5e479ca660f9 Mon Sep 17 00:00:00 2001 From: Brian Mix Date: Fri, 30 Nov 2018 13:57:55 -0600 Subject: [PATCH 06/12] refactored public function to use options array - removed laravel config value for bucketName - refactored public method to accept options array like other public methods --- src/Client.php | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/Client.php b/src/Client.php index eee824d..60314ac 100755 --- a/src/Client.php +++ b/src/Client.php @@ -480,31 +480,42 @@ protected function getFileIdFromBucketAndFileName($bucketName, $fileName) /** * Uploads a large file using b2 large file proceedure. * - * @param $fileName - * @param $filePath - * @param $contentType + * @param array $options * * @return \BackblazeB2\File */ - public function uploadLargeFile($fileName, $filePath, $contentType) + public function uploadLargeFile(array $options) { - // 1) b2_start_large_file, (returns fileId) - $start = $this->startLargeFile($fileName, $contentType); - // 2) b2_get_upload_part_url for each thread uploading (takes fileId) - $url = $this->getUploadPartUrl($start['fileId']); + if (substr($options['FileName'], 0, 1) === '/') { + $options['FileName'] = ltrim($options['FileName'], '/'); + } //if last char of path is not a "/" then add a "/" - if (substr($filePath, -1) != '/') { - $filePath = $filePath.'/'; + if (substr($options['FilePath'], -1) != '/') { + $options['FilePath'] = $options['FilePath'].'/'; } + if (!isset($options['BucketId']) && isset($options['BucketName'])) { + $options['BucketId'] = $this->getBucketIdFromName($options['BucketName']); + } + + if (!isset($options['FileContentType'])) { + $options['FileContentType'] = 'b2/x-auto'; + } + + // 1) b2_start_large_file, (returns fileId) + $start = $this->startLargeFile($options['FileName'], $options['FileContentType'], $options['BucketId']); + + // 2) b2_get_upload_part_url for each thread uploading (takes fileId) + $url = $this->getUploadPartUrl($start['fileId']); + // 3) b2_upload_part for each part of the file - $parts = $this->uploadParts($filePath.$fileName, $url['uploadUrl'], $url['authorizationToken']); + $parts = $this->uploadParts($options['FilePath'].$options['FileName'], $url['uploadUrl'], $url['authorizationToken']); $sha1s = []; - foreach ($parts as $part) { + foreach($parts as $part) { $sha1s[] = $part['contentSha1']; } @@ -517,10 +528,11 @@ public function uploadLargeFile($fileName, $filePath, $contentType) * * @param $fileName * @param $contentType + * @param $bucketId * * @return array */ - protected function startLargeFile($fileName, $contentType) + protected function startLargeFile($fileName, $contentType, $bucketId) { $response = $this->client->request('POST', $this->apiUrl.'/b2_start_large_file', [ 'headers' => [ @@ -529,7 +541,7 @@ protected function startLargeFile($fileName, $contentType) 'json' => [ 'fileName' => $fileName, 'contentType' => $contentType, - 'bucketId' => $this->getBucketIdFromName(config('filesystems.disks.backblaze.bucketName')), + 'bucketId' => $bucketId, ], ]); From 1ef26c881ef2f7207222276e030747be30142c2d Mon Sep 17 00:00:00 2001 From: Brian Mix Date: Fri, 30 Nov 2018 13:58:45 -0600 Subject: [PATCH 07/12] style CLI --- src/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 60314ac..3409cef 100755 --- a/src/Client.php +++ b/src/Client.php @@ -515,7 +515,7 @@ public function uploadLargeFile(array $options) $sha1s = []; - foreach($parts as $part) { + foreach ($parts as $part) { $sha1s[] = $part['contentSha1']; } From 82f94a95ada52c747eb8c0b2fe958876125ce82d Mon Sep 17 00:00:00 2001 From: Brian Mix Date: Fri, 30 Nov 2018 13:59:32 -0600 Subject: [PATCH 08/12] another styleCI update --- src/Client.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 3409cef..cd6d4ba 100755 --- a/src/Client.php +++ b/src/Client.php @@ -486,7 +486,6 @@ protected function getFileIdFromBucketAndFileName($bucketName, $fileName) */ public function uploadLargeFile(array $options) { - if (substr($options['FileName'], 0, 1) === '/') { $options['FileName'] = ltrim($options['FileName'], '/'); } From 06ee8a2905b6e19234271bf0152991ad2aad8e14 Mon Sep 17 00:00:00 2001 From: kenrowland Date: Fri, 11 Jan 2019 09:29:38 -0500 Subject: [PATCH 09/12] Add support for reauthorization after a timeout period Signed-off-by: kenrowland --- README.md | 6 +++++- composer.json | 3 ++- src/Client.php | 49 ++++++++++++++++++++++++++++++++++++++------ tests/ClientTest.php | 33 +++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 480319b..3700f6f 100755 --- a/README.md +++ b/README.md @@ -24,8 +24,12 @@ $ composer require gliterd/backblaze-b2 use BackblazeB2\Client; use BackblazeB2\Bucket; -$client = new Client('accountId', 'applicationKey'); +$options = ['auth_timeout_seconds' => seconds]; + +$client = new Client('accountId', 'applicationKey', $options); ``` +_$options_ is optional. If omitted, the default timeout is 12 hours. The timeout allows for a long lived Client object +so that the authorization token does not expire. ## *ApplicationKey is not supported yet, please use MasterKey only* #### Returns a bucket details diff --git a/composer.json b/composer.json index ecb1946..7ab51a0 100755 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ ], "require": { "php": ">=5.5.0", - "guzzlehttp/guzzle": "^6.1" + "guzzlehttp/guzzle": "^6.1", + "nesbot/carbon": "^2.10" }, "require-dev": { "phpunit/phpunit": "4.8.*", diff --git a/src/Client.php b/src/Client.php index a8ffb48..31d36c3 100755 --- a/src/Client.php +++ b/src/Client.php @@ -5,6 +5,7 @@ use BackblazeB2\Exceptions\NotFoundException; use BackblazeB2\Exceptions\ValidationException; use BackblazeB2\Http\Client as HttpClient; +use Carbon\Carbon; class Client { @@ -17,6 +18,9 @@ class Client protected $client; + protected $reauthTime; + protected $authTimeoutSeconds; + /** * Client constructor. Accepts the account ID, application key and an optional array of options. * @@ -29,6 +33,15 @@ public function __construct($accountId, $applicationKey, array $options = []) $this->accountId = $accountId; $this->applicationKey = $applicationKey; + if (isset($options['auth_timeout_seconds'])) { + $this->authTimeoutSeconds = $options['auth_timeout_seconds']; + } else { + $this->authTimeoutSeconds = 12 * 60 * 60; // 12 hour default + } + + // set reauthorize time to force an authentication to take place + $this->reauthTime = Carbon::now('UTC')->subSeconds($this->authTimeoutSeconds * 2); + if (isset($options['client'])) { $this->client = $options['client']; } else { @@ -55,6 +68,8 @@ public function createBucket(array $options) ); } + $this->authorizeAccount(); + $response = $this->client->request('POST', $this->apiUrl.'/b2_create_bucket', [ 'headers' => [ 'Authorization' => $this->authToken, @@ -90,6 +105,8 @@ public function updateBucket(array $options) $options['BucketId'] = $this->getBucketIdFromName($options['BucketName']); } + $this->authorizeAccount(); + $response = $this->client->request('POST', $this->apiUrl.'/b2_update_bucket', [ 'headers' => [ 'Authorization' => $this->authToken, @@ -113,6 +130,8 @@ public function listBuckets() { $buckets = []; + $this->authorizeAccount(); + $response = $this->client->request('POST', $this->apiUrl.'/b2_list_buckets', [ 'headers' => [ 'Authorization' => $this->authToken, @@ -142,6 +161,8 @@ public function deleteBucket(array $options) $options['BucketId'] = $this->getBucketIdFromName($options['BucketName']); } + $this->authorizeAccount(); + $this->client->request('POST', $this->apiUrl.'/b2_delete_bucket', [ 'headers' => [ 'Authorization' => $this->authToken, @@ -173,6 +194,8 @@ public function upload(array $options) $options['BucketId'] = $this->getBucketIdFromName($options['BucketName']); } + $this->authorizeAccount(); + // Retrieve the URL that we should be uploading to. $response = $this->client->request('POST', $this->apiUrl.'/b2_get_upload_url', [ 'headers' => [ @@ -261,6 +284,8 @@ public function download(array $options) $requestUrl = sprintf('%s/file/%s/%s', $this->downloadUrl, $options['BucketName'], $options['FileName']); } + $this->authorizeAccount(); + $response = $this->client->request('GET', $requestUrl, $requestOptions, false); return isset($options['SaveAs']) ? true : $response; @@ -291,6 +316,8 @@ public function listFiles(array $options) $maxFileCount = 1; } + $this->authorizeAccount(); + // B2 returns, at most, 1000 files per "page". Loop through the pages and compile an array of File objects. while (true) { $response = $this->client->request('POST', $this->apiUrl.'/b2_list_file_names', [ @@ -355,6 +382,8 @@ public function getFile(array $options) } } + $this->authorizeAccount(); + $response = $this->client->request('POST', $this->apiUrl.'/b2_get_file_info', [ 'headers' => [ 'Authorization' => $this->authToken, @@ -398,6 +427,8 @@ public function deleteFile(array $options) $options['FileId'] = $file->getId(); } + $this->authorizeAccount(); + $this->client->request('POST', $this->apiUrl.'/b2_delete_file_version', [ 'headers' => [ 'Authorization' => $this->authToken, @@ -418,13 +449,17 @@ public function deleteFile(array $options) */ protected function authorizeAccount() { - $response = $this->client->request('GET', 'https://api.backblazeb2.com/b2api/v1/b2_authorize_account', [ - 'auth' => [$this->accountId, $this->applicationKey], - ]); + if (Carbon::now('UTC')->timestamp > $this->reauthTime->timestamp) { + $response = $this->client->request('GET', 'https://api.backblazeb2.com/b2api/v1/b2_authorize_account', [ + 'auth' => [$this->accountId, $this->applicationKey], + ]); - $this->authToken = $response['authorizationToken']; - $this->apiUrl = $response['apiUrl'].'/b2api/v1'; - $this->downloadUrl = $response['downloadUrl']; + $this->authToken = $response['authorizationToken']; + $this->apiUrl = $response['apiUrl'].'/b2api/v1'; + $this->downloadUrl = $response['downloadUrl']; + $this->reauthTime = Carbon::now('UTC'); + $this->reauthTime->addSeconds($this->authTimeoutSeconds); + } } /** @@ -503,6 +538,8 @@ public function uploadLargeFile(array $options) $options['FileContentType'] = 'b2/x-auto'; } + $this->authorizeAccount(); + // 1) b2_start_large_file, (returns fileId) $start = $this->startLargeFile($options['FileName'], $options['FileContentType'], $options['BucketId']); diff --git a/tests/ClientTest.php b/tests/ClientTest.php index e0499cb..12ab830 100755 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -13,6 +13,8 @@ use BackblazeB2\File; use GuzzleHttp\Middleware; use GuzzleHttp\Psr7\Stream; +use Carbon\Carbon; +use ReflectionClass; class ClientTest extends \PHPUnit_Framework_TestCase { @@ -526,4 +528,35 @@ public function testDeletingNonExistentFileThrowsException() 'FileName' => 'fileName', ])); } + + public function testAuthenticationTimeout() + { + $reflectionClass = new ReflectionClass('BackblazeB2\Client'); + $reflectionProperty = $reflectionClass->getProperty('reauthTime'); + $reflectionProperty->setAccessible(true); + + $guzzle = $this->buildGuzzleFromResponses([ + $this->buildResponseFromStub(200, [], 'authorize_account.json'), + $this->buildResponseFromStub(200, [], 'authorize_account.json'), + $this->buildResponseFromStub(200, [], 'create_bucket_public.json'), + ]); + + $client = new Client('testId', 'testKey', + [ + 'client' => $guzzle, + 'auth_timeout_seconds' => 3, + ]); + + $curTime = $reflectionProperty->getValue($client); + sleep(10); // let the token timeout + + // Something that will reaturhorize + $bucket = $client->createBucket([ + 'BucketName' => 'Test bucket', + 'BucketType' => Bucket::TYPE_PUBLIC, + ]); + + $newTime = $reflectionProperty->getValue($client); + $this->assertTrue($curTime->timestamp != $newTime->timestamp); + } } From 720745176ff0d9313535847c876571b76d201101 Mon Sep 17 00:00:00 2001 From: Ramesh Mhetre Date: Fri, 11 Jan 2019 22:16:11 +0000 Subject: [PATCH 10/12] Apply fixes from StyleCI --- tests/ClientTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 12ab830..96d23ea 100755 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -13,7 +13,6 @@ use BackblazeB2\File; use GuzzleHttp\Middleware; use GuzzleHttp\Psr7\Stream; -use Carbon\Carbon; use ReflectionClass; class ClientTest extends \PHPUnit_Framework_TestCase From 6f622e8cb35cf6d015c2f8166b70907937f2816e Mon Sep 17 00:00:00 2001 From: Ramesh Mhetre Date: Fri, 11 Jan 2019 23:24:33 +0100 Subject: [PATCH 11/12] Restricted to min php version 7.1.8 Signed-off-by: Ramesh Mhetre --- .travis.yml | 1 - composer.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7ac9872..4d27a8d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - '5.6' - '7.0' - '7.1' - nightly diff --git a/composer.json b/composer.json index 7ab51a0..7104e78 100755 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": ">=5.5.0", + "php": "^7.1.8", "guzzlehttp/guzzle": "^6.1", "nesbot/carbon": "^2.10" }, From be91bdf6cca2c2b3c3b449ea2bc8a44fdfeeb0e8 Mon Sep 17 00:00:00 2001 From: Ramesh Mhetre Date: Fri, 11 Jan 2019 23:30:37 +0100 Subject: [PATCH 12/12] Removed php 7.0 Signed-off-by: Ramesh Mhetre --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4d27a8d..841c04f 100755 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - '7.0' - '7.1' - nightly