| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 | 
							- <?php
 
- namespace GuzzleHttp\Cookie;
 
- use Psr\Http\Message\RequestInterface;
 
- use Psr\Http\Message\ResponseInterface;
 
- /**
 
-  * 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 $cookies, string $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 $cookie, bool $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;
 
-     }
 
-     public function toArray(): array
 
-     {
 
-         return \array_map(static function (SetCookie $cookie): array {
 
-             return $cookie->toArray();
 
-         }, $this->getIterator()->getArrayCopy());
 
-     }
 
-     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));
 
-                 }
 
-             );
 
-         }
 
-     }
 
-     public function clearSessionCookies(): void
 
-     {
 
-         $this->cookies = \array_filter(
 
-             $this->cookies,
 
-             static function (SetCookie $cookie): bool {
 
-                 return !$cookie->getDiscard() && $cookie->getExpires();
 
-             }
 
-         );
 
-     }
 
-     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 $request, ResponseInterface $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 (0 !== \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
 
-      *
 
-      * @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
 
-      */
 
-     private function getCookiePathFromRequest(RequestInterface $request): string
 
-     {
 
-         $uriPath = $request->getUri()->getPath();
 
-         if ('' === $uriPath) {
 
-             return '/';
 
-         }
 
-         if (0 !== \strpos($uriPath, '/')) {
 
-             return '/';
 
-         }
 
-         if ('/' === $uriPath) {
 
-             return '/';
 
-         }
 
-         $lastSlashPos = \strrpos($uriPath, '/');
 
-         if (0 === $lastSlashPos || false === $lastSlashPos) {
 
-             return '/';
 
-         }
 
-         return \substr($uriPath, 0, $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()
 
-             );
 
-         }
 
-     }
 
- }
 
 
  |