Skip to content

Commit

Permalink
Ensure connection reset errors are retried. Resolves aws#767
Browse files Browse the repository at this point in the history
  • Loading branch information
jeskew committed Sep 19, 2015
1 parent cef4687 commit 2f985ba
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 17 deletions.
14 changes: 12 additions & 2 deletions src/S3/S3Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,21 @@ public static function _applyRetryConfig($value, $_, HandlerList $list)
} elseif ($error instanceof AwsException
&& $retries < $maxRetries
) {
return $error->getResponse()
&& strpos(
if ($error->getResponse()) {
return strpos(
$error->getResponse()->getBody(),
'Your socket connection to the server'
) !== false;
} elseif ($error->getPrevious() instanceof RequestException
&& defined('CURLE_RECV_ERROR')
) {
$context = $error->getPrevious()->getHandlerContext();
if (isset($context['errno'])
&& $context['errno'] === CURLE_RECV_ERROR
) {
return true;
}
}
}
return false;
};
Expand Down
56 changes: 41 additions & 15 deletions tests/S3/S3ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
namespace Aws\Test\S3;

use Aws\Result;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use Aws\Test\UsesServiceTrait;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise;
Expand Down Expand Up @@ -366,10 +366,7 @@ public function testRetriesConnectionErrors()
'version' => 'latest',
'region' => 'us-west-2',
'retries' => $retries,
'http_handler' => function (
RequestInterface $request,
array $options
) use (&$retries) {
'http_handler' => function () use (&$retries) {
if (0 === --$retries) {
return new FulfilledPromise(new Response);
}
Expand Down Expand Up @@ -408,10 +405,7 @@ public function testRetries200Errors(
'version' => 'latest',
'region' => 'us-west-2',
'retries' => $retries,
'http_handler' => function (
RequestInterface $request,
array $options
) use (&$retries, $failingSuccess) {
'http_handler' => function () use (&$retries, $failingSuccess) {
if (0 === --$retries) {
return new FulfilledPromise(new Response(
200,
Expand Down Expand Up @@ -519,10 +513,7 @@ public function testClientSocketTimeoutErrorsAreNotRetriedIndefinitely()
'version' => 'latest',
'region' => 'us-west-2',
'retries' => $retries,
'http_handler' => function (
RequestInterface $request,
array $options
) {
'http_handler' => function () {
return new RejectedPromise([
'connection_error' => false,
'exception' => $this->getMockBuilder(RequestException::class)
Expand All @@ -538,8 +529,6 @@ public function testClientSocketTimeoutErrorsAreNotRetriedIndefinitely()
'Key' => 'key',
'Body' => Psr7\stream_for('x'),
]);

$this->assertEquals(0, $retries);
}

private function getSocketTimeoutResponse()
Expand All @@ -554,4 +543,41 @@ private function getSocketTimeoutResponse()
</Error>
EOXML;
}

public function testConnectionResetErrorsAreRetried()
{
$resetError = $this->getMockBuilder(RequestException::class)
->disableOriginalConstructor()
->setMethods(['getHandlerContext'])
->getMock();
$resetError->expects($this->any())
->method('getHandlerContext')
->willReturn(['errno' => CURLE_RECV_ERROR]);

$retries = 11;
$client = new S3Client([
'version' => 'latest',
'region' => 'us-west-2',
'retries' => $retries,
'http_handler' => function () use (&$retries, $resetError) {
if (0 === --$retries) {
return new FulfilledPromise(new Response);
}

return new RejectedPromise([
'connection_error' => false,
'exception' => $resetError,
'response' => null,
]);
},
]);

$client->putObject([
'Bucket' => 'bucket',
'Key' => 'key',
'Body' => Psr7\stream_for('x'),
]);

$this->assertEquals(0, $retries);
}
}

0 comments on commit 2f985ba

Please sign in to comment.