Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
MessageTrait.php
001 <?php
002
003 namespace GuzzleHttp\Psr7;
004
005 use Psr\Http\Message\StreamInterface;
006
007 /**
008 * Trait implementing functionality common to requests and responses.
009 */
010 trait MessageTrait
011 {
012 /** @var array Map of all registered headers, as original name => array of values */
013 private $headers = [];
014
015 /** @var array Map of lowercase header name => original name at registration */
016 private $headerNames = [];
017
018 /** @var string */
019 private $protocol = '1.1';
020
021 /** @var StreamInterface|null */
022 private $stream;
023
024 public function getProtocolVersion()
025 {
026 return $this->protocol;
027 }
028
029 public function withProtocolVersion($version)
030 {
031 if ($this->protocol === $version) {
032 return $this;
033 }
034
035 $new = clone $this;
036 $new->protocol = $version;
037 return $new;
038 }
039
040 public function getHeaders()
041 {
042 return $this->headers;
043 }
044
045 public function hasHeader($header)
046 {
047 return isset($this->headerNames[strtolower($header)]);
048 }
049
050 public function getHeader($header)
051 {
052 $header = strtolower($header);
053
054 if (!isset($this->headerNames[$header])) {
055 return [];
056 }
057
058 $header = $this->headerNames[$header];
059
060 return $this->headers[$header];
061 }
062
063 public function getHeaderLine($header)
064 {
065 return implode(', ', $this->getHeader($header));
066 }
067
068 public function withHeader($header, $value)
069 {
070 $this->assertHeader($header);
071 $value = $this->normalizeHeaderValue($value);
072 $normalized = strtolower($header);
073
074 $new = clone $this;
075 if (isset($new->headerNames[$normalized])) {
076 unset($new->headers[$new->headerNames[$normalized]]);
077 }
078 $new->headerNames[$normalized] = $header;
079 $new->headers[$header] = $value;
080
081 return $new;
082 }
083
084 public function withAddedHeader($header, $value)
085 {
086 $this->assertHeader($header);
087 $value = $this->normalizeHeaderValue($value);
088 $normalized = strtolower($header);
089
090 $new = clone $this;
091 if (isset($new->headerNames[$normalized])) {
092 $header = $this->headerNames[$normalized];
093 $new->headers[$header] = array_merge($this->headers[$header], $value);
094 } else {
095 $new->headerNames[$normalized] = $header;
096 $new->headers[$header] = $value;
097 }
098
099 return $new;
100 }
101
102 public function withoutHeader($header)
103 {
104 $normalized = strtolower($header);
105
106 if (!isset($this->headerNames[$normalized])) {
107 return $this;
108 }
109
110 $header = $this->headerNames[$normalized];
111
112 $new = clone $this;
113 unset($new->headers[$header], $new->headerNames[$normalized]);
114
115 return $new;
116 }
117
118 public function getBody()
119 {
120 if (!$this->stream) {
121 $this->stream = Utils::streamFor('');
122 }
123
124 return $this->stream;
125 }
126
127 public function withBody(StreamInterface $body)
128 {
129 if ($body === $this->stream) {
130 return $this;
131 }
132
133 $new = clone $this;
134 $new->stream = $body;
135 return $new;
136 }
137
138 private function setHeaders(array $headers)
139 {
140 $this->headerNames = $this->headers = [];
141 foreach ($headers as $header => $value) {
142 if (is_int($header)) {
143 // Numeric array keys are converted to int by PHP but having a header name '123' is not forbidden by the spec
144 // and also allowed in withHeader(). So we need to cast it to string again for the following assertion to pass.
145 $header = (string) $header;
146 }
147 $this->assertHeader($header);
148 $value = $this->normalizeHeaderValue($value);
149 $normalized = strtolower($header);
150 if (isset($this->headerNames[$normalized])) {
151 $header = $this->headerNames[$normalized];
152 $this->headers[$header] = array_merge($this->headers[$header], $value);
153 } else {
154 $this->headerNames[$normalized] = $header;
155 $this->headers[$header] = $value;
156 }
157 }
158 }
159
160 /**
161 * @param mixed $value
162 *
163 * @return string[]
164 */
165 private function normalizeHeaderValue($value)
166 {
167 if (!is_array($value)) {
168 return $this->trimAndValidateHeaderValues([$value]);
169 }
170
171 if (count($value) === 0) {
172 throw new \InvalidArgumentException('Header value can not be an empty array.');
173 }
174
175 return $this->trimAndValidateHeaderValues($value);
176 }
177
178 /**
179 * Trims whitespace from the header values.
180 *
181 * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
182 *
183 * header-field = field-name ":" OWS field-value OWS
184 * OWS = *( SP / HTAB )
185 *
186 * @param mixed[] $values Header values
187 *
188 * @return string[] Trimmed header values
189 *
190 * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
191 */
192 private function trimAndValidateHeaderValues(array $values)
193 {
194 return array_map(function ($value) {
195 if (!is_scalar($value) && null !== $value) {
196 throw new \InvalidArgumentException(sprintf(
197 'Header value must be scalar or null but %s provided.',
198 is_object($value) ? get_class($value) : gettype($value)
199 ));
200 }
201
202 $trimmed = trim((string) $value, " \t");
203 $this->assertValue($trimmed);
204
205 return $trimmed;
206 }, array_values($values));
207 }
208
209 /**
210 * @see https://tools.ietf.org/html/rfc7230#section-3.2
211 *
212 * @param mixed $header
213 *
214 * @return void
215 */
216 private function assertHeader($header)
217 {
218 if (!is_string($header)) {
219 throw new \InvalidArgumentException(sprintf(
220 'Header name must be a string but %s provided.',
221 is_object($header) ? get_class($header) : gettype($header)
222 ));
223 }
224
225 if ($header === '') {
226 throw new \InvalidArgumentException('Header name can not be empty.');
227 }
228
229 if (! preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) {
230 throw new \InvalidArgumentException(
231 sprintf('"%s" is not valid header name.', $header)
232 );
233 }
234 }
235
236 /**
237 * @param string $value
238 *
239 * @return void
240 *
241 * @see https://tools.ietf.org/html/rfc7230#section-3.2
242 *
243 * field-value = *( field-content / obs-fold )
244 * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
245 * field-vchar = VCHAR / obs-text
246 * VCHAR = %x21-7E
247 * obs-text = %x80-FF
248 * obs-fold = CRLF 1*( SP / HTAB )
249 */
250 private function assertValue($value)
251 {
252 // The regular expression intentionally does not support the obs-fold production, because as
253 // per RFC 7230#3.2.4:
254 //
255 // A sender MUST NOT generate a message that includes
256 // line folding (i.e., that has any field-value that contains a match to
257 // the obs-fold rule) unless the message is intended for packaging
258 // within the message/http media type.
259 //
260 // Clients must not send a request with line folding and a server sending folded headers is
261 // likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting
262 // folding is not likely to break any legitimate use case.
263 if (! preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value)) {
264 throw new \InvalidArgumentException(
265 sprintf('"%s" is not valid header value.', $value)
266 );
267 }
268 }
269 }
270