PluginProbe
Media Cloud Sync / 1.4.2
Media Cloud Sync v1.4.2
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 / google / guzzlehttp / psr7 / src / MessageTrait.php

MessageTrait.php in Media Cloud Sync 1.4.2, at includes/sdk/google/guzzlehttp/psr7/src/MessageTrait.php

225 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare (strict_types=1);
4 namespace Dudlewebs\WPMCS\GCP\GuzzleHttp\Psr7;
5
6 use Dudlewebs\WPMCS\GCP\Psr\Http\Message\MessageInterface;
7 use Dudlewebs\WPMCS\GCP\Psr\Http\Message\StreamInterface;
8 /**
9 * Trait implementing functionality common to requests and responses.
10 */
11 trait MessageTrait
12 {
13 /** @var string[][] Map of all registered headers, as original name => array of values */
14 private $headers = [];
15 /** @var string[] Map of lowercase header name => original name at registration */
16 private $headerNames = [];
17 /** @var string */
18 private $protocol = '1.1';
19 /** @var StreamInterface|null */
20 private $stream;
21 public function getProtocolVersion() : string
22 {
23 return $this->protocol;
24 }
25 /**
26 * @return static
27 */
28 public function withProtocolVersion($version) : MessageInterface
29 {
30 if ($this->protocol === $version) {
31 return $this;
32 }
33 $new = clone $this;
34 $new->protocol = $version;
35 return $new;
36 }
37 public function getHeaders() : array
38 {
39 return $this->headers;
40 }
41 public function hasHeader($header) : bool
42 {
43 return isset($this->headerNames[\strtolower($header)]);
44 }
45 public function getHeader($header) : array
46 {
47 $header = \strtolower($header);
48 if (!isset($this->headerNames[$header])) {
49 return [];
50 }
51 $header = $this->headerNames[$header];
52 return $this->headers[$header];
53 }
54 public function getHeaderLine($header) : string
55 {
56 return \implode(', ', $this->getHeader($header));
57 }
58 /**
59 * @return static
60 */
61 public function withHeader($header, $value) : MessageInterface
62 {
63 $this->assertHeader($header);
64 $value = $this->normalizeHeaderValue($value);
65 $normalized = \strtolower($header);
66 $new = clone $this;
67 if (isset($new->headerNames[$normalized])) {
68 unset($new->headers[$new->headerNames[$normalized]]);
69 }
70 $new->headerNames[$normalized] = $header;
71 $new->headers[$header] = $value;
72 return $new;
73 }
74 /**
75 * @return static
76 */
77 public function withAddedHeader($header, $value) : MessageInterface
78 {
79 $this->assertHeader($header);
80 $value = $this->normalizeHeaderValue($value);
81 $normalized = \strtolower($header);
82 $new = clone $this;
83 if (isset($new->headerNames[$normalized])) {
84 $header = $this->headerNames[$normalized];
85 $new->headers[$header] = \array_merge($this->headers[$header], $value);
86 } else {
87 $new->headerNames[$normalized] = $header;
88 $new->headers[$header] = $value;
89 }
90 return $new;
91 }
92 /**
93 * @return static
94 */
95 public function withoutHeader($header) : MessageInterface
96 {
97 $normalized = \strtolower($header);
98 if (!isset($this->headerNames[$normalized])) {
99 return $this;
100 }
101 $header = $this->headerNames[$normalized];
102 $new = clone $this;
103 unset($new->headers[$header], $new->headerNames[$normalized]);
104 return $new;
105 }
106 public function getBody() : StreamInterface
107 {
108 if (!$this->stream) {
109 $this->stream = Utils::streamFor('');
110 }
111 return $this->stream;
112 }
113 /**
114 * @return static
115 */
116 public function withBody(StreamInterface $body) : MessageInterface
117 {
118 if ($body === $this->stream) {
119 return $this;
120 }
121 $new = clone $this;
122 $new->stream = $body;
123 return $new;
124 }
125 /**
126 * @param (string|string[])[] $headers
127 */
128 private function setHeaders(array $headers) : void
129 {
130 $this->headerNames = $this->headers = [];
131 foreach ($headers as $header => $value) {
132 // Numeric array keys are converted to int by PHP.
133 $header = (string) $header;
134 $this->assertHeader($header);
135 $value = $this->normalizeHeaderValue($value);
136 $normalized = \strtolower($header);
137 if (isset($this->headerNames[$normalized])) {
138 $header = $this->headerNames[$normalized];
139 $this->headers[$header] = \array_merge($this->headers[$header], $value);
140 } else {
141 $this->headerNames[$normalized] = $header;
142 $this->headers[$header] = $value;
143 }
144 }
145 }
146 /**
147 * @param mixed $value
148 *
149 * @return string[]
150 */
151 private function normalizeHeaderValue($value) : array
152 {
153 if (!\is_array($value)) {
154 return $this->trimAndValidateHeaderValues([$value]);
155 }
156 return $this->trimAndValidateHeaderValues($value);
157 }
158 /**
159 * Trims whitespace from the header values.
160 *
161 * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
162 *
163 * header-field = field-name ":" OWS field-value OWS
164 * OWS = *( SP / HTAB )
165 *
166 * @param mixed[] $values Header values
167 *
168 * @return string[] Trimmed header values
169 *
170 * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4
171 */
172 private function trimAndValidateHeaderValues(array $values) : array
173 {
174 return \array_map(function ($value) {
175 if (!\is_scalar($value) && null !== $value) {
176 throw new \InvalidArgumentException(\sprintf('Header value must be scalar or null but %s provided.', \is_object($value) ? \get_class($value) : \gettype($value)));
177 }
178 $trimmed = \trim((string) $value, " \t");
179 $this->assertValue($trimmed);
180 return $trimmed;
181 }, \array_values($values));
182 }
183 /**
184 * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
185 *
186 * @param mixed $header
187 */
188 private function assertHeader($header) : void
189 {
190 if (!\is_string($header)) {
191 throw new \InvalidArgumentException(\sprintf('Header name must be a string but %s provided.', \is_object($header) ? \get_class($header) : \gettype($header)));
192 }
193 if (!\preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) {
194 throw new \InvalidArgumentException(\sprintf('"%s" is not valid header name.', $header));
195 }
196 }
197 /**
198 * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
199 *
200 * field-value = *( field-content / obs-fold )
201 * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
202 * field-vchar = VCHAR / obs-text
203 * VCHAR = %x21-7E
204 * obs-text = %x80-FF
205 * obs-fold = CRLF 1*( SP / HTAB )
206 */
207 private function assertValue(string $value) : void
208 {
209 // The regular expression intentionally does not support the obs-fold production, because as
210 // per RFC 7230#3.2.4:
211 //
212 // A sender MUST NOT generate a message that includes
213 // line folding (i.e., that has any field-value that contains a match to
214 // the obs-fold rule) unless the message is intended for packaging
215 // within the message/http media type.
216 //
217 // Clients must not send a request with line folding and a server sending folded headers is
218 // likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
219 // folding is not likely to break any legitimate use case.
220 if (!\preg_match('/^[\\x20\\x09\\x21-\\x7E\\x80-\\xFF]*$/D', $value)) {
221 throw new \InvalidArgumentException(\sprintf('"%s" is not valid header value.', $value));
222 }
223 }
224 }
225