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

namespace GuzzleHttpCookie;

use 
PsrHttpMessageRequestInterface;
use 
PsrHttpMessageResponseInterface;

/**
 * Cookie jar that stores cookies as an array
 */
class CookieJar implements CookieJarInterface
{
    
/**
     * @var SetCookie[] Loaded cookie data
     */
    
private $cookies = [];

    
/**
     * @var bool
     */
    
private $strictMode;

    
/**
     * @param bool  $strictMode  Set to true to throw exceptions when invalid
     *                           cookies are added to the cookie jar.
     * @param array $cookieArray Array of SetCookie objects or a hash of
     *                           arrays that can be used with the SetCookie
     *                           constructor
     */
    
public function __construct(bool $strictMode false, array $cookieArray = [])
    {
        
$this->strictMode $strictMode;

        foreach (
$cookieArray as $cookie) {
            if (!(
$cookie instanceof SetCookie)) {
                
$cookie = new SetCookie($cookie);
            }
            
$this->setCookie($cookie);
        }
    }

    
/**
     * Create a new Cookie jar from an associative array and domain.
     *
     * @param array  $cookies Cookies to create the jar from
     * @param string $domain  Domain to set the cookies to
     */
    
public static function fromArray(array $cookiesstring $domain): self
    
{
        
$cookieJar = new self();
        foreach (
$cookies as $name => $value) {
            
$cookieJar->setCookie(new SetCookie([
                
'Domain'  => $domain,
                
'Name'    => $name,
                
'Value'   => $value,
                
'Discard' => true
            
]));
        }

        return 
$cookieJar;
    }

    
/**
     * Evaluate if this cookie should be persisted to storage
     * that survives between requests.
     *
     * @param SetCookie $cookie              Being evaluated.
     * @param bool      $allowSessionCookies If we should persist session cookies
     */
    
public static function shouldPersist(SetCookie $cookiebool $allowSessionCookies false): bool
    
{
        if (
$cookie->getExpires() || $allowSessionCookies) {
            if (!
$cookie->getDiscard()) {
                return 
true;
            }
        }

        return 
false;
    }

    
/**
     * Finds and returns the cookie based on the name
     *
     * @param string $name cookie name to search for
     *
     * @return SetCookie|null cookie that was found or null if not found
     */
    
public function getCookieByName(string $name): ?SetCookie
    
{
        foreach (
$this->cookies as $cookie) {
            if (
$cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
                return 
$cookie;
            }
        }

        return 
null;
    }

    
/**
     * @inheritDoc
     */
    
public function toArray(): array
    {
        return 
array_map(static function (SetCookie $cookie): array {
            return 
$cookie->toArray();
        }, 
$this->getIterator()->getArrayCopy());
    }

    
/**
     * @inheritDoc
     */
    
public function clear(?string $domain null, ?string $path null, ?string $name null): void
    
{
        if (!
$domain) {
            
$this->cookies = [];
            return;
        } elseif (!
$path) {
            
$this->cookies array_filter(
                
$this->cookies,
                static function (
SetCookie $cookie) use ($domain): bool {
                    return !
$cookie->matchesDomain($domain);
                }
            );
        } elseif (!
$name) {
            
$this->cookies array_filter(
                
$this->cookies,
                static function (
SetCookie $cookie) use ($path$domain): bool {
                    return !(
$cookie->matchesPath($path) &&
                        
$cookie->matchesDomain($domain));
                }
            );
        } else {
            
$this->cookies array_filter(
                
$this->cookies,
                static function (
SetCookie $cookie) use ($path$domain$name) {
                    return !(
$cookie->getName() == $name &&
                        
$cookie->matchesPath($path) &&
                        
$cookie->matchesDomain($domain));
                }
            );
        }
    }

    
/**
     * @inheritDoc
     */
    
public function clearSessionCookies(): void
    
{
        
$this->cookies array_filter(
            
$this->cookies,
            static function (
SetCookie $cookie): bool {
                return !
$cookie->getDiscard() && $cookie->getExpires();
            }
        );
    }

    
/**
     * @inheritDoc
     */
    
public function setCookie(SetCookie $cookie): bool
    
{
        
// If the name string is empty (but not 0), ignore the set-cookie
        // string entirely.
        
$name $cookie->getName();
        if (!
$name && $name !== '0') {
            return 
false;
        }

        
// Only allow cookies with set and valid domain, name, value
        
$result $cookie->validate();
        if (
$result !== true) {
            if (
$this->strictMode) {
                throw new 
RuntimeException('Invalid cookie: ' $result);
            }
            
$this->removeCookieIfEmpty($cookie);
            return 
false;
        }

        
// Resolve conflicts with previously set cookies
        
foreach ($this->cookies as $i => $c) {
            
// Two cookies are identical, when their path, and domain are
            // identical.
            
if ($c->getPath() != $cookie->getPath() ||
                
$c->getDomain() != $cookie->getDomain() ||
                
$c->getName() != $cookie->getName()
            ) {
                continue;
            }

            
// The previously set cookie is a discard cookie and this one is
            // not so allow the new cookie to be set
            
if (!$cookie->getDiscard() && $c->getDiscard()) {
                unset(
$this->cookies[$i]);
                continue;
            }

            
// If the new cookie's expiration is further into the future, then
            // replace the old cookie
            
if ($cookie->getExpires() > $c->getExpires()) {
                unset(
$this->cookies[$i]);
                continue;
            }

            
// If the value has changed, we better change it
            
if ($cookie->getValue() !== $c->getValue()) {
                unset(
$this->cookies[$i]);
                continue;
            }

            
// The cookie exists, so no need to continue
            
return false;
        }

        
$this->cookies[] = $cookie;

        return 
true;
    }

    public function 
count(): int
    
{
        return 
count($this->cookies);
    }

    
/**
     * @return ArrayIterator<int, SetCookie>
     */
    
public function getIterator(): ArrayIterator
    
{
        return new 
ArrayIterator(array_values($this->cookies));
    }

    public function 
extractCookies(RequestInterface $requestResponseInterface $response): void
    
{
        if (
$cookieHeader $response->getHeader('Set-Cookie')) {
            foreach (
$cookieHeader as $cookie) {
                
$sc SetCookie::fromString($cookie);
                if (!
$sc->getDomain()) {
                    
$sc->setDomain($request->getUri()->getHost());
                }
                if (
!== strpos($sc->getPath(), '/')) {
                    
$sc->setPath($this->getCookiePathFromRequest($request));
                }
                if (!
$sc->matchesDomain($request->getUri()->getHost())) {
                    continue;
                }
                
// Note: At this point `$sc->getDomain()` being a public suffix should
                // be rejected, but we don't want to pull in the full PSL dependency.
                
$this->setCookie($sc);
            }
        }
    }

    
/**
     * Computes cookie path following RFC 6265 section 5.1.4
     *
     * @link https://tools.ietf.org/html/rfc6265#section-5.1.4
     */
    
private function getCookiePathFromRequest(RequestInterface $request): string
    
{
        
$uriPath $request->getUri()->getPath();
        if (
'' === $uriPath) {
            return 
'/';
        }
        if (
!== strpos($uriPath'/')) {
            return 
'/';
        }
        if (
'/' === $uriPath) {
            return 
'/';
        }
        
$lastSlashPos strrpos($uriPath'/');
        if (
=== $lastSlashPos || false === $lastSlashPos) {
            return 
'/';
        }

        return 
substr($uriPath0$lastSlashPos);
    }

    public function 
withCookieHeader(RequestInterface $request): RequestInterface
    
{
        
$values = [];
        
$uri $request->getUri();
        
$scheme $uri->getScheme();
        
$host $uri->getHost();
        
$path $uri->getPath() ?: '/';

        foreach (
$this->cookies as $cookie) {
            if (
$cookie->matchesPath($path) &&
                
$cookie->matchesDomain($host) &&
                !
$cookie->isExpired() &&
                (!
$cookie->getSecure() || $scheme === 'https')
            ) {
                
$values[] = $cookie->getName() . '='
                    
$cookie->getValue();
            }
        }

        return 
$values
            
$request->withHeader('Cookie'implode('; '$values))
            : 
$request;
    }

    
/**
     * If a cookie already exists and the server asks to set it again with a
     * null value, the cookie must be deleted.
     */
    
private function removeCookieIfEmpty(SetCookie $cookie): void
    
{
        
$cookieValue $cookie->getValue();
        if (
$cookieValue === null || $cookieValue === '') {
            
$this->clear(
                
$cookie->getDomain(),
                
$cookie->getPath(),
                
$cookie->getName()
            );
        }
    }
}
Онлайн: 0
Реклама