Merge branch '5.4' into 6.0
* 5.4: [HttpClient] fix resetting DNS/etc when calling CurlHttpClient::reset() Fix invalid guess with enumType [HttpClient] Remove deprecated usage of GuzzleHttp\Promise\promise_for
This commit is contained in:
commit
adc8a55bad
@ -135,14 +135,17 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE
|
||||
}
|
||||
|
||||
if ($metadata->hasField($property)) {
|
||||
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
|
||||
if (null !== $enumClass = $metadata->getFieldMapping($property)['enumType'] ?? null) {
|
||||
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $enumClass)];
|
||||
}
|
||||
|
||||
$typeOfField = $metadata->getTypeOfField($property);
|
||||
|
||||
if (!$builtinType = $this->getPhpType($typeOfField)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
|
||||
|
||||
switch ($builtinType) {
|
||||
case Type::BUILTIN_TYPE_OBJECT:
|
||||
switch ($typeOfField) {
|
||||
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Doctrine\Tests\Fixtures;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class DoctrineLoaderEnum
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\Column
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString", length=1)
|
||||
*/
|
||||
public $enumString;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
|
||||
*/
|
||||
public $enumInt;
|
||||
}
|
@ -14,12 +14,16 @@ namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Type as DBALType;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use Doctrine\ORM\Tools\Setup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
|
||||
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy;
|
||||
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineEnum;
|
||||
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineGeneratedValue;
|
||||
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation;
|
||||
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt;
|
||||
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString;
|
||||
use Symfony\Component\PropertyInfo\Type;
|
||||
|
||||
/**
|
||||
@ -124,6 +128,18 @@ class DoctrineExtractorTest extends TestCase
|
||||
$this->assertEquals($expectedTypes, $actualTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8.1
|
||||
*/
|
||||
public function testExtractEnum()
|
||||
{
|
||||
if (!property_exists(Column::class, 'enumType')) {
|
||||
$this->markTestSkipped('The "enumType" requires doctrine/orm 2.11.');
|
||||
}
|
||||
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumString::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumString', []));
|
||||
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumInt', []));
|
||||
}
|
||||
|
||||
public function typesProvider()
|
||||
{
|
||||
$provider = [
|
||||
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
|
||||
|
||||
use Doctrine\ORM\Mapping\Id;
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DoctrineEnum
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="smallint")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString")
|
||||
*/
|
||||
protected $enumString;
|
||||
|
||||
/**
|
||||
* @Column(type="integer", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
|
||||
*/
|
||||
protected $enumInt;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
|
||||
|
||||
enum EnumInt: int
|
||||
{
|
||||
case Foo = 0;
|
||||
case Bar = 1;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
|
||||
|
||||
enum EnumString: string
|
||||
{
|
||||
case Foo = 'f';
|
||||
case Bar = 'b';
|
||||
}
|
@ -11,11 +11,13 @@
|
||||
|
||||
namespace Symfony\Bridge\Doctrine\Tests\Validator;
|
||||
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bridge\Doctrine\Tests\DoctrineTestHelper;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\BaseUser;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEmbed;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEntity;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEnum;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderNestedEmbed;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderNoAutoMappingEntity;
|
||||
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderParentEntity;
|
||||
@ -149,6 +151,31 @@ class DoctrineLoaderTest extends TestCase
|
||||
$this->assertSame(AutoMappingStrategy::DISABLED, $noAutoMappingMetadata[0]->getAutoMappingStrategy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8.1
|
||||
*/
|
||||
public function testExtractEnum()
|
||||
{
|
||||
if (!property_exists(Column::class, 'enumType')) {
|
||||
$this->markTestSkipped('The "enumType" requires doctrine/orm 2.11.');
|
||||
}
|
||||
|
||||
$validator = Validation::createValidatorBuilder()
|
||||
->addMethodMapping('loadValidatorMetadata')
|
||||
->enableAnnotationMapping()
|
||||
->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}'))
|
||||
->getValidator()
|
||||
;
|
||||
|
||||
$classMetadata = $validator->getMetadataFor(new DoctrineLoaderEnum());
|
||||
|
||||
$enumStringMetadata = $classMetadata->getPropertyMetadata('enumString');
|
||||
$this->assertCount(0, $enumStringMetadata); // asserts the length constraint is not added to an enum
|
||||
|
||||
$enumStringMetadata = $classMetadata->getPropertyMetadata('enumInt');
|
||||
$this->assertCount(0, $enumStringMetadata); // asserts the length constraint is not added to an enum
|
||||
}
|
||||
|
||||
public function testFieldMappingsConfiguration()
|
||||
{
|
||||
$validator = Validation::createValidatorBuilder()
|
||||
|
@ -16,6 +16,7 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\ORM\Mapping\MappingException as OrmMappingException;
|
||||
use Doctrine\Persistence\Mapping\MappingException;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\PropertyInfo\Type;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use Symfony\Component\Validator\Constraints\Valid;
|
||||
use Symfony\Component\Validator\Mapping\AutoMappingStrategy;
|
||||
@ -99,7 +100,7 @@ final class DoctrineLoader implements LoaderInterface
|
||||
$loaded = true;
|
||||
}
|
||||
|
||||
if (null === ($mapping['length'] ?? null) || !\in_array($mapping['type'], ['string', 'text'], true)) {
|
||||
if (null === ($mapping['length'] ?? null) || null !== ($mapping['enumType'] ?? null) || !\in_array($mapping['type'], ['string', 'text'], true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,6 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
|
||||
|
||||
if ($resolve && 0x072A00 > CurlClientState::$curlVersion['version_number']) {
|
||||
// DNS cache removals require curl 7.42 or higher
|
||||
// On lower versions, we have to create a new multi handle
|
||||
$this->multi->reset();
|
||||
}
|
||||
|
||||
@ -283,6 +282,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
|
||||
if (!$pushedResponse) {
|
||||
$ch = curl_init();
|
||||
$this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url));
|
||||
$curlopts += [\CURLOPT_SHARE => $this->multi->share];
|
||||
}
|
||||
|
||||
foreach ($curlopts as $opt => $value) {
|
||||
@ -304,9 +304,9 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
|
||||
$responses = [$responses];
|
||||
}
|
||||
|
||||
if (($mh = $this->multi->handles[0] ?? null) instanceof \CurlMultiHandle) {
|
||||
if ($this->multi->handle instanceof \CurlMultiHandle) {
|
||||
$active = 0;
|
||||
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($mh, $active)) {
|
||||
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active)) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,11 @@ use Symfony\Component\HttpClient\Response\CurlResponse;
|
||||
*/
|
||||
final class CurlClientState extends ClientState
|
||||
{
|
||||
/** @var array<\CurlMultiHandle> */
|
||||
public array $handles = [];
|
||||
public \CurlMultiHandle $handle;
|
||||
public \CurlShareHandle $share;
|
||||
/** @var PushedResponse[] */
|
||||
public array $pushedResponses = [];
|
||||
public $dnsCache;
|
||||
public DnsCache $dnsCache;
|
||||
/** @var float[] */
|
||||
public array $pauseExpiries = [];
|
||||
public int $execCounter = \PHP_INT_MIN;
|
||||
@ -35,27 +35,23 @@ final class CurlClientState extends ClientState
|
||||
|
||||
public static array $curlVersion;
|
||||
|
||||
private int $maxHostConnections;
|
||||
private int $maxPendingPushes;
|
||||
|
||||
public function __construct(int $maxHostConnections, int $maxPendingPushes)
|
||||
{
|
||||
self::$curlVersion = self::$curlVersion ?? curl_version();
|
||||
|
||||
array_unshift($this->handles, $mh = curl_multi_init());
|
||||
$this->handle = curl_multi_init();
|
||||
$this->dnsCache = new DnsCache();
|
||||
$this->maxHostConnections = $maxHostConnections;
|
||||
$this->maxPendingPushes = $maxPendingPushes;
|
||||
$this->reset();
|
||||
|
||||
// Don't enable HTTP/1.1 pipelining: it forces responses to be sent in order
|
||||
if (\defined('CURLPIPE_MULTIPLEX')) {
|
||||
curl_multi_setopt($mh, \CURLMOPT_PIPELINING, \CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt($this->handle, \CURLMOPT_PIPELINING, \CURLPIPE_MULTIPLEX);
|
||||
}
|
||||
if (\defined('CURLMOPT_MAX_HOST_CONNECTIONS')) {
|
||||
$maxHostConnections = curl_multi_setopt($mh, \CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX) ? 0 : $maxHostConnections;
|
||||
$maxHostConnections = curl_multi_setopt($this->handle, \CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX) ? 0 : $maxHostConnections;
|
||||
}
|
||||
if (\defined('CURLMOPT_MAXCONNECTS') && 0 < $maxHostConnections) {
|
||||
curl_multi_setopt($mh, \CURLMOPT_MAXCONNECTS, $maxHostConnections);
|
||||
curl_multi_setopt($this->handle, \CURLMOPT_MAXCONNECTS, $maxHostConnections);
|
||||
}
|
||||
|
||||
// Skip configuring HTTP/2 push when it's unsupported or buggy, see https://bugs.php.net/77535
|
||||
@ -68,17 +64,8 @@ final class CurlClientState extends ClientState
|
||||
return;
|
||||
}
|
||||
|
||||
// Clone to prevent a circular reference
|
||||
$multi = clone $this;
|
||||
$multi->handles = [$mh];
|
||||
$multi->pushedResponses = &$this->pushedResponses;
|
||||
$multi->logger = &$this->logger;
|
||||
$multi->handlesActivity = &$this->handlesActivity;
|
||||
$multi->openHandles = &$this->openHandles;
|
||||
$multi->lastTimeout = &$this->lastTimeout;
|
||||
|
||||
curl_multi_setopt($mh, \CURLMOPT_PUSHFUNCTION, static function ($parent, $pushed, array $requestHeaders) use ($multi, $maxPendingPushes) {
|
||||
return $multi->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes);
|
||||
curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION, function ($parent, $pushed, array $requestHeaders) use ($maxPendingPushes) {
|
||||
return $this->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes);
|
||||
});
|
||||
}
|
||||
|
||||
@ -86,10 +73,7 @@ final class CurlClientState extends ClientState
|
||||
{
|
||||
foreach ($this->pushedResponses as $url => $response) {
|
||||
$this->logger && $this->logger->debug(sprintf('Unused pushed response: "%s"', $url));
|
||||
|
||||
foreach ($this->handles as $mh) {
|
||||
curl_multi_remove_handle($mh, $response->handle);
|
||||
}
|
||||
curl_multi_remove_handle($this->handle, $response->handle);
|
||||
curl_close($response->handle);
|
||||
}
|
||||
|
||||
@ -97,11 +81,14 @@ final class CurlClientState extends ClientState
|
||||
$this->dnsCache->evictions = $this->dnsCache->evictions ?: $this->dnsCache->removals;
|
||||
$this->dnsCache->removals = $this->dnsCache->hostnames = [];
|
||||
|
||||
if (\defined('CURLMOPT_PUSHFUNCTION')) {
|
||||
curl_multi_setopt($this->handles[0], \CURLMOPT_PUSHFUNCTION, null);
|
||||
}
|
||||
$this->share = curl_share_init();
|
||||
|
||||
$this->__construct($this->maxHostConnections, $this->maxPendingPushes);
|
||||
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_DNS);
|
||||
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_SSL_SESSION);
|
||||
|
||||
if (\defined('CURL_LOCK_DATA_CONNECT')) {
|
||||
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_CONNECT);
|
||||
}
|
||||
}
|
||||
|
||||
private function handlePush($parent, $pushed, array $requestHeaders, int $maxPendingPushes): int
|
||||
|
@ -108,9 +108,7 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
if (0 < $duration) {
|
||||
if ($execCounter === $multi->execCounter) {
|
||||
$multi->execCounter = !\is_float($execCounter) ? 1 + $execCounter : \PHP_INT_MIN;
|
||||
foreach ($multi->handles as $mh) {
|
||||
curl_multi_remove_handle($mh, $ch);
|
||||
}
|
||||
curl_multi_remove_handle($multi->handle, $ch);
|
||||
}
|
||||
|
||||
$lastExpiry = end($multi->pauseExpiries);
|
||||
@ -122,7 +120,7 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
} else {
|
||||
unset($multi->pauseExpiries[(int) $ch]);
|
||||
curl_pause($ch, \CURLPAUSE_CONT);
|
||||
curl_multi_add_handle($multi->handles[0], $ch);
|
||||
curl_multi_add_handle($multi->handle, $ch);
|
||||
}
|
||||
};
|
||||
|
||||
@ -176,7 +174,7 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
// Schedule the request in a non-blocking way
|
||||
$multi->lastTimeout = null;
|
||||
$multi->openHandles[$id] = [$ch, $options];
|
||||
curl_multi_add_handle($multi->handles[0], $ch);
|
||||
curl_multi_add_handle($multi->handle, $ch);
|
||||
|
||||
$this->canary = new Canary(static function () use ($ch, $multi, $id) {
|
||||
unset($multi->pauseExpiries[$id], $multi->openHandles[$id], $multi->handlesActivity[$id]);
|
||||
@ -186,9 +184,7 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($multi->handles as $mh) {
|
||||
curl_multi_remove_handle($mh, $ch);
|
||||
}
|
||||
curl_multi_remove_handle($multi->handle, $ch);
|
||||
curl_setopt_array($ch, [
|
||||
\CURLOPT_NOPROGRESS => true,
|
||||
\CURLOPT_PROGRESSFUNCTION => null,
|
||||
@ -270,7 +266,7 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
*/
|
||||
private static function schedule(self $response, array &$runningResponses): void
|
||||
{
|
||||
if (isset($runningResponses[$i = (int) $response->multi->handles[0]])) {
|
||||
if (isset($runningResponses[$i = (int) $response->multi->handle])) {
|
||||
$runningResponses[$i][1][$response->id] = $response;
|
||||
} else {
|
||||
$runningResponses[$i] = [$response->multi, [$response->id => $response]];
|
||||
@ -303,17 +299,15 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
try {
|
||||
self::$performing = true;
|
||||
++$multi->execCounter;
|
||||
|
||||
foreach ($multi->handles as $i => $mh) {
|
||||
$active = 0;
|
||||
while (\CURLM_CALL_MULTI_PERFORM === ($err = curl_multi_exec($mh, $active))) {
|
||||
while (\CURLM_CALL_MULTI_PERFORM === ($err = curl_multi_exec($multi->handle, $active))) {
|
||||
}
|
||||
|
||||
if (\CURLM_OK !== $err) {
|
||||
throw new TransportException(curl_multi_strerror($err));
|
||||
}
|
||||
|
||||
while ($info = curl_multi_info_read($mh)) {
|
||||
while ($info = curl_multi_info_read($multi->handle)) {
|
||||
if (\CURLMSG_DONE !== $info['msg']) {
|
||||
continue;
|
||||
}
|
||||
@ -322,12 +316,12 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
$waitFor = @curl_getinfo($ch, \CURLINFO_PRIVATE) ?: '_0';
|
||||
|
||||
if (\in_array($result, [\CURLE_SEND_ERROR, \CURLE_RECV_ERROR, /*CURLE_HTTP2*/ 16, /*CURLE_HTTP2_STREAM*/ 92], true) && $waitFor[1] && 'C' !== $waitFor[0]) {
|
||||
curl_multi_remove_handle($mh, $ch);
|
||||
curl_multi_remove_handle($multi->handle, $ch);
|
||||
$waitFor[1] = (string) ((int) $waitFor[1] - 1); // decrement the retry counter
|
||||
curl_setopt($ch, \CURLOPT_PRIVATE, $waitFor);
|
||||
curl_setopt($ch, \CURLOPT_FORBID_REUSE, true);
|
||||
|
||||
if (0 === curl_multi_add_handle($mh, $ch)) {
|
||||
if (0 === curl_multi_add_handle($multi->handle, $ch)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -339,12 +333,6 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
$multi->handlesActivity[$id][] = null;
|
||||
$multi->handlesActivity[$id][] = \in_array($result, [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || '_0' === $waitFor || curl_getinfo($ch, \CURLINFO_SIZE_DOWNLOAD) === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL)));
|
||||
}
|
||||
|
||||
if (!$active && 0 < $i) {
|
||||
curl_multi_close($mh);
|
||||
unset($multi->handles[$i]);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
self::$performing = false;
|
||||
}
|
||||
@ -368,11 +356,11 @@ final class CurlResponse implements ResponseInterface, StreamableInterface
|
||||
|
||||
unset($multi->pauseExpiries[$id]);
|
||||
curl_pause($multi->openHandles[$id][0], \CURLPAUSE_CONT);
|
||||
curl_multi_add_handle($multi->handles[0], $multi->openHandles[$id][0]);
|
||||
curl_multi_add_handle($multi->handle, $multi->openHandles[$id][0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 !== $selected = curl_multi_select($multi->handles[array_key_last($multi->handles)], $timeout)) {
|
||||
if (0 !== $selected = curl_multi_select($multi->handle, $timeout)) {
|
||||
return $selected;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\HttpClient\Response;
|
||||
|
||||
use function GuzzleHttp\Promise\promise_for;
|
||||
use GuzzleHttp\Promise\Create;
|
||||
use GuzzleHttp\Promise\PromiseInterface as GuzzlePromiseInterface;
|
||||
use Http\Promise\Promise as HttplugPromiseInterface;
|
||||
use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface;
|
||||
@ -74,7 +74,7 @@ final class HttplugPromise implements HttplugPromiseInterface
|
||||
}
|
||||
|
||||
return static function ($value) use ($callback) {
|
||||
return promise_for($callback($value));
|
||||
return Create::promiseFor($callback($value));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -62,9 +62,9 @@ class CurlHttpClientTest extends HttpClientTestCase
|
||||
$r = new \ReflectionProperty($httpClient, 'multi');
|
||||
$r->setAccessible(true);
|
||||
$clientState = $r->getValue($httpClient);
|
||||
$initialHandleId = (int) $clientState->handles[0];
|
||||
$initialShareId = $clientState->share;
|
||||
$httpClient->reset();
|
||||
self::assertNotSame($initialHandleId, (int) $clientState->handles[0]);
|
||||
self::assertNotSame($initialShareId, $clientState->share);
|
||||
}
|
||||
|
||||
public function testProcessAfterReset()
|
||||
|
Reference in New Issue
Block a user