Вход Регистрация
Файл: vendor/guzzlehttp/guzzle/src/Handler/CurlShareHandleState.php
Строк: 261
<?php

namespace GuzzleHttpHandler;

use 
GuzzleHttpTransportSharing;

/**
 * @internal
 */
final class CurlShareHandleState
{
    
/**
     * @var resource|CurlShareHandle|null
     */
    
public $handle;

    
/**
     * @var string
     */
    
public $mode;

    
/**
     * @param resource|CurlShareHandle|null $handle
     */
    
private function __construct(string $mode$handle)
    {
        
$this->mode $mode;
        
$this->handle $handle;
    }

    
/**
     * @param mixed $sharing
     */
    
public static function fromOption($sharing): ?self
    
{
        if (
$sharing instanceof self) {
            return 
$sharing;
        }

        
$mode self::normalizeMode($sharing'transport_sharing');
        if (
$mode === TransportSharing::NONE) {
            return 
null;
        }

        if (
$mode === TransportSharing::HANDLER_PREFER) {
            return 
self::createHandlerShareOrNull($mode);
        }

        return 
self::createHandlerShare($mode);
    }

    
/**
     * @param mixed $sharing
     */
    
public static function normalizeMode($sharingstring $option): string
    
{
        if (
$sharing instanceof self) {
            return 
$sharing->mode;
        }

        if (
$sharing === null || $sharing === TransportSharing::NONE) {
            return 
TransportSharing::NONE;
        }

        if (
$sharing === TransportSharing::HANDLER_PREFER || $sharing === TransportSharing::HANDLER_REQUIRE) {
            return 
$sharing;
        }

        throw new 
InvalidArgumentException(sprintf(
            
'The "%s" option must be null or a GuzzleHttp\TransportSharing::* constant; received %s.',
            
$option,
            
get_debug_type($sharing)
        ));
    }

    public static function 
assertNoRequiredSharingCustomFactoryConflict(array $optionsstring $handlerName): void
    
{
        if (!
array_key_exists('handle_factory'$options) || $options['handle_factory'] === null) {
            return;
        }

        
$mode self::normalizeMode($options['transport_sharing'] ?? null'transport_sharing');
        if (
$mode !== TransportSharing::HANDLER_REQUIRE) {
            return;
        }

        throw new 
InvalidArgumentException(sprintf(
            
'The "transport_sharing" %s option cannot require sharing with a custom "handle_factory" because Guzzle cannot ensure that the custom factory applies CURLOPT_SHARE.',
            
$handlerName
        
));
    }

    private static function 
createHandlerShareOrNull(string $mode): ?self
    
{
        try {
            return 
self::createHandlerShare($mode);
        } catch (
Throwable $e) {
            return 
null;
        }
    }

    private static function 
createHandlerShare(string $mode): self
    
{
        if (!
function_exists('curl_share_init') || !function_exists('curl_share_setopt')) {
            throw new 
InvalidArgumentException('The "transport_sharing" option requires cURL share support.');
        }

        
self::requireCurlConstant('CURLOPT_SHARE');
        
$shareOption self::requireCurlConstant('CURLSHOPT_SHARE');
        
$locks self::handlerLocks($mode);
        
$handle curl_share_init();

        try {
            foreach (
$locks as $lock) {
                try {
                    
$success curl_share_setopt($handle$shareOption$lock);
                } catch (
Throwable $e) {
                    throw new 
InvalidArgumentException('Unable to configure cURL share handle: '.$e->getMessage(), 0$e);
                }

                if (!
$success) {
                    throw new 
InvalidArgumentException(sprintf('Unable to configure cURL share handle with lock data %d.'$lock));
                }
            }
        } catch (
Throwable $e) {
            
self::closeHandlerShareHandleOnPhp7($handle);

            throw 
$e;
        }

        return new 
self($mode$handle);
    }

    
/**
     * @return int[]
     */
    
private static function handlerLocks(string $mode): array
    {
        
CurlVersion::ensureHandlerSharingSupported();

        if (
$mode === TransportSharing::HANDLER_REQUIRE) {
            
CurlVersion::ensureSslSessionSharingSupported();
        }

        
$locks = [
            
self::requireCurlConstant('CURL_LOCK_DATA_DNS'),
        ];

        if (
CurlVersion::supportsSslSessionSharing()) {
            
$locks[] = self::requireCurlConstant('CURL_LOCK_DATA_SSL_SESSION');
        }

        return 
$locks;
    }

    private static function 
requireCurlConstant(string $constant): int
    
{
        if (!
defined($constant)) {
            throw new 
InvalidArgumentException(sprintf(
                
'The "transport_sharing" option requires %s, but it is not available in the installed PHP cURL extension.',
                
$constant
            
));
        }

        
$value constant($constant);
        if (!
is_int($value)) {
            throw new 
InvalidArgumentException(sprintf('The cURL constant %s must resolve to an integer.'$constant));
        }

        return 
$value;
    }

    
/**
     * @param resource|CurlShareHandle $handle
     */
    
private static function closeHandlerShareHandleOnPhp7($handle): void
    
{
        if (
PHP_VERSION_ID 80000 && is_resource($handle)) {
            
curl_share_close($handle);
        }
    }
}
Онлайн: 1
Реклама