Fixed issue where request was not created on-demand, removed code that is

not 32bit PHP compatible, modified the options for request when method is
'HEAD'. Also updated README.md & CHANGELOG.md
This commit is contained in:
Tank Tang 2016-11-08 15:22:03 +08:00
Родитель 9c79381470
Коммит a71aa6f89f
6 изменённых файлов: 46 добавлений и 117 удалений

Просмотреть файл

@ -1,4 +1,4 @@
2016.09 - version 0.11.0
2016.11 - version 0.11.0
ALL
* Fix error string when an error occurs while parsing a connection string and is passed to _createException in `MicrosoftAzure\Storage\Common\Internal\ConnectionStringParser`.

Просмотреть файл

@ -25,7 +25,14 @@ This project provides a set of PHP client libraries that make it easy to access
* PHP 5.5 or above
* See [composer.json](composer.json) for dependencies
* Required extension for PHP:
php_fileinfo.dll
php_mbstring.dll
php_openssl.dll
php_xsl.dll
* Recommanded extension for PHP:
php_curl.dll
## Download Source Code

Просмотреть файл

@ -1310,7 +1310,6 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$headers = array();
$postParams = array();
$queryParams = array();
$bodySize = null;
$path = $this->_createPath($container, $blob);
$statusCode = Resources::STATUS_CREATED;
@ -1628,9 +1627,6 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
);
};
//generate the decider.
$decider = Utilities::generateIsSeekableStreamEndDecider($contentStream);
//add number of concurrency if specified int options.
$clientOptions = $options->getNumberOfConcurrency() == null?
array() : array($options->getNumberOfConcurrency);
@ -1641,7 +1637,7 @@ class BlobRestProxy extends ServiceRestProxy implements IBlob
$this->sendConcurrent(
array(),
$generator,
$decider,
Resources::STATUS_CREATED,
$clientOptions
);

Просмотреть файл

@ -36,7 +36,7 @@ use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Pool;
use GuzzleHttp\Promise\EachPromise;
/**
* Base class for all services rest proxies.
@ -161,7 +161,8 @@ class ServiceRestProxy extends RestProxy
$this->_options['http'],
array(
"defaults" => array(
"allow_redirects" => true, "exceptions" => true,
"allow_redirects" => true,
"exceptions" => true,
"decode_content" => true,
),
'cookies' => true,
@ -185,8 +186,8 @@ class ServiceRestProxy extends RestProxy
* using the generator.
* @param callable $generator the generator function to
* generate request upon fullfilment
* @param callable $decider decide if the generator
* continues to append.
* @param int $expectedStatusCode The expected status code for each
* of the request.
* @param array $clientOptions an array of additional options
* for the client.
*
@ -195,7 +196,7 @@ class ServiceRestProxy extends RestProxy
protected function sendConcurrent(
$requests,
$generator,
$decider,
$expectedStatusCode,
$clientOptions = []
) {
//set the number of concurrency to default value if not defined
@ -208,41 +209,41 @@ class ServiceRestProxy extends RestProxy
//create the client
$client = $this->createClient($clientOptions);
//generate the first batch if requests are empty.
if (empty($requests) && is_callable($generator)) {
$requests = array();
for ($index = 0;
$index < $numberOfConcurrency && !$decider();
++$index) {
$requests[] = $generator();
}
}
$requestsIterator = new \ArrayIterator($requests);
$pool = new Pool($client, $requestsIterator, [
'concurrency' => $numberOfConcurrency,
'fulfilled' => function (
$response,
$index
) use (
$requestsIterator,
$generator,
$decider
) {
//append new request using the generator.
if (is_callable($generator) && !$decider()) {
$requestsIterator->append($generator());
$promises = \call_user_func(
function () use ($requests, $generator, $client) {
$sendAsync = function ($request) use ($client) {
$options = $request->getMethod() == 'HEAD'?
array('decode_content' => false) : array();
return $client->sendAsync($request, $options);
};
foreach ($requests as $request) {
yield $sendAsync($request);
}
while (is_callable($generator) && ($request = $generator())) {
yield $sendAsync($request);
}
}
);
$eachPromise = new EachPromise($promises, [
'concurrency' => $numberOfConcurrency,
'fulfilled' => function ($response, $index) use ($expectedStatusCode) {
//the promise is fulfilled, evaluate the response
self::throwIfError(
$response->getStatusCode(),
$response->getReasonPhrase(),
$response->getBody(),
$expectedStatusCode
);
},
'rejected' => function ($reason, $index) {
//Still rejected even if the retry logic has been applied.
//Throwing exception.
throw $reason;
},
}
]);
return $pool->promise()->wait();
return $eachPromise->promise()->wait();
}
/**
@ -338,7 +339,9 @@ class ServiceRestProxy extends RestProxy
$client = $this->createClient($clientOptions);
try {
$response = $client->send($request);
$options = $request->getMethod() == 'HEAD'?
array('decode_content' => false) : array();
$response = $client->send($request, $options);
self::throwIfError(
$response->getStatusCode(),
$response->getReasonPhrase(),

Просмотреть файл

@ -778,33 +778,4 @@ class Utilities
}
return $result;
}
/**
* Generate a decider that returns false if a given stream is not ended.
*
* @param StreamInterface $contentStream The stream to be decided on.
*
* @return callable A callable that returns true
* if the stream reaches its end.
*/
public static function generateIsSeekableStreamEndDecider($contentStream)
{
return function () use ($contentStream) {
$isEnd = false;
if ($contentStream->eof()) {
$isEnd = true;
} else {
//if the content stream is read to exactly the end of file
//the content stream will still not return true for eof()
//Have to read another byte, then see if it is null.
$str = $contentStream->read(1);
if ($str != '') {
$contentStream->seek(-1, SEEK_CUR);
} else {
$isEnd = true;
}
}
return $isEnd;
};
}
}

Просмотреть файл

@ -769,52 +769,4 @@ class UtilitiesTest extends \PHPUnit_Framework_TestCase
// Delete file after assertion.
unlink($path);
}
/**
* @covers MicrosoftAzure\Storage\Common\Internal\Utilities::generateIsSeekableStreamEndDecider
*/
public function testGenerateIsSeekableStreamEndDecider()
{
//prepare a file
$cwd = getcwd();
$uuid = uniqid('test-file-', true);
$path = $cwd.DIRECTORY_SEPARATOR.$uuid.'.txt';
$resource = fopen($path, 'w+');
$count = 2;
for ($index = 0; $index < $count; ++$index) {
fwrite($resource, openssl_random_pseudo_bytes(4194304));
}
rewind($resource);
$stream = Psr7\stream_for($resource);
$decider = Utilities::generateIsSeekableStreamEndDecider($stream);
$result_0 = $decider();
$stream->read(4194304 * $count - 1);
$result_1 = $decider();
$stream->read(1);
$result_2 = $decider();
//prepare a string
$count = 2;
$testStr = openssl_random_pseudo_bytes(4194304 * $count);
$stream = Psr7\stream_for($testStr);
$decider = Utilities::generateIsSeekableStreamEndDecider($stream);
$result_3 = $decider();
$stream->read(4194304 * $count - 1);
$result_4 = $decider();
$stream->read(1);
$result_5 = $decider();
$this->assertFalse($result_0);
$this->assertFalse($result_1);
$this->assertFalse($result_3);
$this->assertFalse($result_4);
$this->assertTrue($result_2);
$this->assertTrue($result_5);
if (is_resource($resource)) {
fclose($resource);
}
// Delete file after assertion.
unlink($path);
}
}