PluginProbe
Media Cloud Sync / 1.3.0
Media Cloud Sync v1.3.0
1.4.2 1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 All 36 releases
media-cloud-sync / includes / sdk / s3 / GuzzleHttp / Cookie / CookieJar.php

CookieJar.php in Media Cloud Sync 1.3.0, at includes/sdk/s3/GuzzleHttp/Cookie/CookieJar.php

241 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS\s3\GuzzleHttp\Cookie;
4
5 use Dudlewebs\WPMCS\s3\Psr\Http\Message\RequestInterface;
6 use Dudlewebs\WPMCS\s3\Psr\Http\Message\ResponseInterface;
7 /**
8 * Cookie jar that stores cookies as an array
9 */
10 class CookieJar implements CookieJarInterface
11 {
12 /**
13 * @var SetCookie[] Loaded cookie data
14 */
15 private $cookies = [];
16 /**
17 * @var bool
18 */
19 private $strictMode;
20 /**
21 * @param bool $strictMode Set to true to throw exceptions when invalid
22 * cookies are added to the cookie jar.
23 * @param array $cookieArray Array of SetCookie objects or a hash of
24 * arrays that can be used with the SetCookie
25 * constructor
26 */
27 public function __construct(bool $strictMode = \false, array $cookieArray = [])
28 {
29 $this->strictMode = $strictMode;
30 foreach ($cookieArray as $cookie) {
31 if (!$cookie instanceof SetCookie) {
32 $cookie = new SetCookie($cookie);
33 }
34 $this->setCookie($cookie);
35 }
36 }
37 /**
38 * Create a new Cookie jar from an associative array and domain.
39 *
40 * @param array $cookies Cookies to create the jar from
41 * @param string $domain Domain to set the cookies to
42 */
43 public static function fromArray(array $cookies, string $domain) : self
44 {
45 $cookieJar = new self();
46 foreach ($cookies as $name => $value) {
47 $cookieJar->setCookie(new SetCookie(['Domain' => $domain, 'Name' => $name, 'Value' => $value, 'Discard' => \true]));
48 }
49 return $cookieJar;
50 }
51 /**
52 * Evaluate if this cookie should be persisted to storage
53 * that survives between requests.
54 *
55 * @param SetCookie $cookie Being evaluated.
56 * @param bool $allowSessionCookies If we should persist session cookies
57 */
58 public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = \false) : bool
59 {
60 if ($cookie->getExpires() || $allowSessionCookies) {
61 if (!$cookie->getDiscard()) {
62 return \true;
63 }
64 }
65 return \false;
66 }
67 /**
68 * Finds and returns the cookie based on the name
69 *
70 * @param string $name cookie name to search for
71 *
72 * @return SetCookie|null cookie that was found or null if not found
73 */
74 public function getCookieByName(string $name) : ?SetCookie
75 {
76 foreach ($this->cookies as $cookie) {
77 if ($cookie->getName() !== null && \strcasecmp($cookie->getName(), $name) === 0) {
78 return $cookie;
79 }
80 }
81 return null;
82 }
83 public function toArray() : array
84 {
85 return \array_map(static function (SetCookie $cookie) : array {
86 return $cookie->toArray();
87 }, $this->getIterator()->getArrayCopy());
88 }
89 public function clear(?string $domain = null, ?string $path = null, ?string $name = null) : void
90 {
91 if (!$domain) {
92 $this->cookies = [];
93 return;
94 } elseif (!$path) {
95 $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) use($domain) : bool {
96 return !$cookie->matchesDomain($domain);
97 });
98 } elseif (!$name) {
99 $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) use($path, $domain) : bool {
100 return !($cookie->matchesPath($path) && $cookie->matchesDomain($domain));
101 });
102 } else {
103 $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) use($path, $domain, $name) {
104 return !($cookie->getName() == $name && $cookie->matchesPath($path) && $cookie->matchesDomain($domain));
105 });
106 }
107 }
108 public function clearSessionCookies() : void
109 {
110 $this->cookies = \array_filter($this->cookies, static function (SetCookie $cookie) : bool {
111 return !$cookie->getDiscard() && $cookie->getExpires();
112 });
113 }
114 public function setCookie(SetCookie $cookie) : bool
115 {
116 // If the name string is empty (but not 0), ignore the set-cookie
117 // string entirely.
118 $name = $cookie->getName();
119 if (!$name && $name !== '0') {
120 return \false;
121 }
122 // Only allow cookies with set and valid domain, name, value
123 $result = $cookie->validate();
124 if ($result !== \true) {
125 if ($this->strictMode) {
126 throw new \RuntimeException('Invalid cookie: ' . $result);
127 }
128 $this->removeCookieIfEmpty($cookie);
129 return \false;
130 }
131 // Resolve conflicts with previously set cookies
132 foreach ($this->cookies as $i => $c) {
133 // Two cookies are identical, when their path, and domain are
134 // identical.
135 if ($c->getPath() != $cookie->getPath() || $c->getDomain() != $cookie->getDomain() || $c->getName() != $cookie->getName()) {
136 continue;
137 }
138 // The previously set cookie is a discard cookie and this one is
139 // not so allow the new cookie to be set
140 if (!$cookie->getDiscard() && $c->getDiscard()) {
141 unset($this->cookies[$i]);
142 continue;
143 }
144 // If the new cookie's expiration is further into the future, then
145 // replace the old cookie
146 if ($cookie->getExpires() > $c->getExpires()) {
147 unset($this->cookies[$i]);
148 continue;
149 }
150 // If the value has changed, we better change it
151 if ($cookie->getValue() !== $c->getValue()) {
152 unset($this->cookies[$i]);
153 continue;
154 }
155 // The cookie exists, so no need to continue
156 return \false;
157 }
158 $this->cookies[] = $cookie;
159 return \true;
160 }
161 public function count() : int
162 {
163 return \count($this->cookies);
164 }
165 /**
166 * @return \ArrayIterator<int, SetCookie>
167 */
168 public function getIterator() : \ArrayIterator
169 {
170 return new \ArrayIterator(\array_values($this->cookies));
171 }
172 public function extractCookies(RequestInterface $request, ResponseInterface $response) : void
173 {
174 if ($cookieHeader = $response->getHeader('Set-Cookie')) {
175 foreach ($cookieHeader as $cookie) {
176 $sc = SetCookie::fromString($cookie);
177 if (!$sc->getDomain()) {
178 $sc->setDomain($request->getUri()->getHost());
179 }
180 if (0 !== \strpos($sc->getPath(), '/')) {
181 $sc->setPath($this->getCookiePathFromRequest($request));
182 }
183 if (!$sc->matchesDomain($request->getUri()->getHost())) {
184 continue;
185 }
186 // Note: At this point `$sc->getDomain()` being a public suffix should
187 // be rejected, but we don't want to pull in the full PSL dependency.
188 $this->setCookie($sc);
189 }
190 }
191 }
192 /**
193 * Computes cookie path following RFC 6265 section 5.1.4
194 *
195 * @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
196 */
197 private function getCookiePathFromRequest(RequestInterface $request) : string
198 {
199 $uriPath = $request->getUri()->getPath();
200 if ('' === $uriPath) {
201 return '/';
202 }
203 if (0 !== \strpos($uriPath, '/')) {
204 return '/';
205 }
206 if ('/' === $uriPath) {
207 return '/';
208 }
209 $lastSlashPos = \strrpos($uriPath, '/');
210 if (0 === $lastSlashPos || \false === $lastSlashPos) {
211 return '/';
212 }
213 return \substr($uriPath, 0, $lastSlashPos);
214 }
215 public function withCookieHeader(RequestInterface $request) : RequestInterface
216 {
217 $values = [];
218 $uri = $request->getUri();
219 $scheme = $uri->getScheme();
220 $host = $uri->getHost();
221 $path = $uri->getPath() ?: '/';
222 foreach ($this->cookies as $cookie) {
223 if ($cookie->matchesPath($path) && $cookie->matchesDomain($host) && !$cookie->isExpired() && (!$cookie->getSecure() || $scheme === 'https')) {
224 $values[] = $cookie->getName() . '=' . $cookie->getValue();
225 }
226 }
227 return $values ? $request->withHeader('Cookie', \implode('; ', $values)) : $request;
228 }
229 /**
230 * If a cookie already exists and the server asks to set it again with a
231 * null value, the cookie must be deleted.
232 */
233 private function removeCookieIfEmpty(SetCookie $cookie) : void
234 {
235 $cookieValue = $cookie->getValue();
236 if ($cookieValue === null || $cookieValue === '') {
237 $this->clear($cookie->getDomain(), $cookie->getPath(), $cookie->getName());
238 }
239 }
240 }
241