File indexing completed on 2025-01-26 05:29:13

0001 <?php
0002 namespace GuzzleHttp\Psr7;
0003 
0004 use Psr\Http\Message\StreamInterface;
0005 
0006 /**
0007  * Trait implementing functionality common to requests and responses.
0008  */
0009 trait MessageTrait
0010 {
0011     /** @var array Map of all registered headers, as original name => array of values */
0012     private $headers = [];
0013 
0014     /** @var array Map of lowercase header name => original name at registration */
0015     private $headerNames  = [];
0016 
0017     /** @var string */
0018     private $protocol = '1.1';
0019 
0020     /** @var StreamInterface */
0021     private $stream;
0022 
0023     public function getProtocolVersion()
0024     {
0025         return $this->protocol;
0026     }
0027 
0028     public function withProtocolVersion($version)
0029     {
0030         if ($this->protocol === $version) {
0031             return $this;
0032         }
0033 
0034         $new = clone $this;
0035         $new->protocol = $version;
0036         return $new;
0037     }
0038 
0039     public function getHeaders()
0040     {
0041         return $this->headers;
0042     }
0043 
0044     public function hasHeader($header)
0045     {
0046         return isset($this->headerNames[strtolower($header)]);
0047     }
0048 
0049     public function getHeader($header)
0050     {
0051         $header = strtolower($header);
0052 
0053         if (!isset($this->headerNames[$header])) {
0054             return [];
0055         }
0056 
0057         $header = $this->headerNames[$header];
0058 
0059         return $this->headers[$header];
0060     }
0061 
0062     public function getHeaderLine($header)
0063     {
0064         return implode(', ', $this->getHeader($header));
0065     }
0066 
0067     public function withHeader($header, $value)
0068     {
0069         if (!is_array($value)) {
0070             $value = [$value];
0071         }
0072 
0073         $value = $this->trimHeaderValues($value);
0074         $normalized = strtolower($header);
0075 
0076         $new = clone $this;
0077         if (isset($new->headerNames[$normalized])) {
0078             unset($new->headers[$new->headerNames[$normalized]]);
0079         }
0080         $new->headerNames[$normalized] = $header;
0081         $new->headers[$header] = $value;
0082 
0083         return $new;
0084     }
0085 
0086     public function withAddedHeader($header, $value)
0087     {
0088         if (!is_array($value)) {
0089             $value = [$value];
0090         }
0091 
0092         $value = $this->trimHeaderValues($value);
0093         $normalized = strtolower($header);
0094 
0095         $new = clone $this;
0096         if (isset($new->headerNames[$normalized])) {
0097             $header = $this->headerNames[$normalized];
0098             $new->headers[$header] = array_merge($this->headers[$header], $value);
0099         } else {
0100             $new->headerNames[$normalized] = $header;
0101             $new->headers[$header] = $value;
0102         }
0103 
0104         return $new;
0105     }
0106 
0107     public function withoutHeader($header)
0108     {
0109         $normalized = strtolower($header);
0110 
0111         if (!isset($this->headerNames[$normalized])) {
0112             return $this;
0113         }
0114 
0115         $header = $this->headerNames[$normalized];
0116 
0117         $new = clone $this;
0118         unset($new->headers[$header], $new->headerNames[$normalized]);
0119 
0120         return $new;
0121     }
0122 
0123     public function getBody()
0124     {
0125         if (!$this->stream) {
0126             $this->stream = stream_for('');
0127         }
0128 
0129         return $this->stream;
0130     }
0131 
0132     public function withBody(StreamInterface $body)
0133     {
0134         if ($body === $this->stream) {
0135             return $this;
0136         }
0137 
0138         $new = clone $this;
0139         $new->stream = $body;
0140         return $new;
0141     }
0142 
0143     private function setHeaders(array $headers)
0144     {
0145         $this->headerNames = $this->headers = [];
0146         foreach ($headers as $header => $value) {
0147             if (!is_array($value)) {
0148                 $value = [$value];
0149             }
0150 
0151             $value = $this->trimHeaderValues($value);
0152             $normalized = strtolower($header);
0153             if (isset($this->headerNames[$normalized])) {
0154                 $header = $this->headerNames[$normalized];
0155                 $this->headers[$header] = array_merge($this->headers[$header], $value);
0156             } else {
0157                 $this->headerNames[$normalized] = $header;
0158                 $this->headers[$header] = $value;
0159             }
0160         }
0161     }
0162 
0163     /**
0164      * Trims whitespace from the header values.
0165      *
0166      * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
0167      *
0168      * header-field = field-name ":" OWS field-value OWS
0169      * OWS          = *( SP / HTAB )
0170      *
0171      * @param string[] $values Header values
0172      *
0173      * @return string[] Trimmed header values
0174      *
0175      * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
0176      */
0177     private function trimHeaderValues(array $values)
0178     {
0179         return array_map(function ($value) {
0180             return trim($value, " \t");
0181         }, $values);
0182     }
0183 }