[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/guzzlehttp/psr7/src/ -> MessageTrait.php (source)

   1  <?php
   2  
   3  namespace GuzzleHttp\Psr7;
   4  
   5  use Psr\Http\Message\StreamInterface;
   6  
   7  /**
   8   * Trait implementing functionality common to requests and responses.
   9   */
  10  trait MessageTrait
  11  {
  12      /** @var array Map of all registered headers, as original name => array of values */
  13      private $headers = [];
  14  
  15      /** @var array Map of lowercase header name => original name at registration */
  16      private $headerNames  = [];
  17  
  18      /** @var string */
  19      private $protocol = '1.1';
  20  
  21      /** @var StreamInterface|null */
  22      private $stream;
  23  
  24      public function getProtocolVersion()
  25      {
  26          return $this->protocol;
  27      }
  28  
  29      public function withProtocolVersion($version)
  30      {
  31          if ($this->protocol === $version) {
  32              return $this;
  33          }
  34  
  35          $new = clone $this;
  36          $new->protocol = $version;
  37          return $new;
  38      }
  39  
  40      public function getHeaders()
  41      {
  42          return $this->headers;
  43      }
  44  
  45      public function hasHeader($header)
  46      {
  47          return isset($this->headerNames[strtolower($header)]);
  48      }
  49  
  50      public function getHeader($header)
  51      {
  52          $header = strtolower($header);
  53  
  54          if (!isset($this->headerNames[$header])) {
  55              return [];
  56          }
  57  
  58          $header = $this->headerNames[$header];
  59  
  60          return $this->headers[$header];
  61      }
  62  
  63      public function getHeaderLine($header)
  64      {
  65          return implode(', ', $this->getHeader($header));
  66      }
  67  
  68      public function withHeader($header, $value)
  69      {
  70          $this->assertHeader($header);
  71          $value = $this->normalizeHeaderValue($value);
  72          $normalized = strtolower($header);
  73  
  74          $new = clone $this;
  75          if (isset($new->headerNames[$normalized])) {
  76              unset($new->headers[$new->headerNames[$normalized]]);
  77          }
  78          $new->headerNames[$normalized] = $header;
  79          $new->headers[$header] = $value;
  80  
  81          return $new;
  82      }
  83  
  84      public function withAddedHeader($header, $value)
  85      {
  86          $this->assertHeader($header);
  87          $value = $this->normalizeHeaderValue($value);
  88          $normalized = strtolower($header);
  89  
  90          $new = clone $this;
  91          if (isset($new->headerNames[$normalized])) {
  92              $header = $this->headerNames[$normalized];
  93              $new->headers[$header] = array_merge($this->headers[$header], $value);
  94          } else {
  95              $new->headerNames[$normalized] = $header;
  96              $new->headers[$header] = $value;
  97          }
  98  
  99          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  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1