mirror of
https://github.com/guzzle/guzzle.git
synced 2025-02-25 10:33:18 +01:00
This commit updates the MultiAdapter to account for connecitons being closed unexpectedly and then retried. When this occurs, curl attempts to rewind the stream before sending. Because we use a callback function to stream large payloads, curl fails to rewind the stream and fails the transaction without associating the correct error code. This commit checks if a transaction has a response before processing. If a transaction doesn't have a response, then we attempt to retry the request transparently (without emitting another set of before events, essentially doing exactly what curl would have done if it was possible to rewind the stream). If the request did not have a body, then an error event is emitted as it is a very weird error. If the request had a body but wasn't rewindable, then an error event is emitted. If the request had a body and a rewindable stream, then it is rewound and retried. This change also updates the MultiAdapter and BatchContext to transfer until the number of open handles in the BatchContext reaches 0. This removes some complexity from the main transfer loop that had to account for pending transactions. Closes #710
96 lines
3.0 KiB
PHP
96 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace GuzzleHttp\Tests\Adapter\Curl;
|
|
|
|
use GuzzleHttp\Adapter\Curl\BatchContext;
|
|
use GuzzleHttp\Adapter\Transaction;
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Message\Request;
|
|
|
|
/**
|
|
* @covers GuzzleHttp\Adapter\Curl\BatchContext
|
|
*/
|
|
class BatchContextTest extends \PHPUnit_Framework_TestCase
|
|
{
|
|
public function testProvidesGetters()
|
|
{
|
|
$m = curl_multi_init();
|
|
$b = new BatchContext($m, true);
|
|
$this->assertTrue($b->throwsExceptions());
|
|
$this->assertSame($m, $b->getMultiHandle());
|
|
$this->assertFalse($b->hasPending());
|
|
curl_multi_close($m);
|
|
}
|
|
|
|
public function testValidatesTransactionsAreNotAddedTwice()
|
|
{
|
|
$m = curl_multi_init();
|
|
$b = new BatchContext($m, true);
|
|
$h = curl_init();
|
|
$t = new Transaction(
|
|
new Client(),
|
|
new Request('GET', 'http://httbin.org')
|
|
);
|
|
$b->addTransaction($t, $h);
|
|
try {
|
|
$b->addTransaction($t, $h);
|
|
$this->fail('Did not throw');
|
|
} catch (\RuntimeException $e) {
|
|
curl_close($h);
|
|
curl_multi_close($m);
|
|
}
|
|
}
|
|
|
|
public function testManagesHandles()
|
|
{
|
|
$m = curl_multi_init();
|
|
$b = new BatchContext($m, true);
|
|
$h = curl_init();
|
|
$t = new Transaction(
|
|
new Client(),
|
|
new Request('GET', 'http://httbin.org')
|
|
);
|
|
$b->addTransaction($t, $h);
|
|
$this->assertTrue($b->isActive());
|
|
$this->assertSame($t, $b->findTransaction($h));
|
|
$b->removeTransaction($t);
|
|
$this->assertFalse($b->isActive());
|
|
try {
|
|
$this->assertEquals([], $b->findTransaction($h));
|
|
$this->fail('Did not throw');
|
|
} catch (\RuntimeException $e) {}
|
|
curl_multi_close($m);
|
|
}
|
|
|
|
/**
|
|
* @expectedException \RuntimeException
|
|
* @expectedExceptionMessage Transaction not registered
|
|
*/
|
|
public function testThrowsWhenRemovingNonExistentTransaction()
|
|
{
|
|
$b = new BatchContext('foo', false);
|
|
$t = new Transaction(
|
|
new Client(),
|
|
new Request('GET', 'http://httbin.org')
|
|
);
|
|
$b->removeTransaction($t);
|
|
}
|
|
|
|
public function testReturnsPendingAsIteratorTypeObject()
|
|
{
|
|
$t1 = new Transaction(new Client(), new Request('GET', 'http://t.com'));
|
|
$t2 = new Transaction(new Client(), new Request('GET', 'http://t.com'));
|
|
$t3 = new Transaction(new Client(), new Request('GET', 'http://t.com'));
|
|
$iter = new \ArrayIterator([$t1, $t2, $t3]);
|
|
$b = new BatchContext('foo', false, $iter);
|
|
$this->assertTrue($b->hasPending());
|
|
$this->assertSame($t1, $b->nextPending());
|
|
$this->assertTrue($b->hasPending());
|
|
$this->assertSame($t2, $b->nextPending());
|
|
$this->assertTrue($b->hasPending());
|
|
$this->assertSame($t3, $b->nextPending());
|
|
$this->assertFalse($b->hasPending());
|
|
$this->assertNull($b->nextPending());
|
|
}
|
|
}
|