Chris@0
|
1 <?php
|
Chris@0
|
2 namespace GuzzleHttp\Psr7;
|
Chris@0
|
3
|
Chris@0
|
4 use Psr\Http\Message\StreamInterface;
|
Chris@0
|
5
|
Chris@0
|
6 /**
|
Chris@0
|
7 * Trait implementing functionality common to requests and responses.
|
Chris@0
|
8 */
|
Chris@0
|
9 trait MessageTrait
|
Chris@0
|
10 {
|
Chris@0
|
11 /** @var array Map of all registered headers, as original name => array of values */
|
Chris@0
|
12 private $headers = [];
|
Chris@0
|
13
|
Chris@0
|
14 /** @var array Map of lowercase header name => original name at registration */
|
Chris@0
|
15 private $headerNames = [];
|
Chris@0
|
16
|
Chris@0
|
17 /** @var string */
|
Chris@0
|
18 private $protocol = '1.1';
|
Chris@0
|
19
|
Chris@0
|
20 /** @var StreamInterface */
|
Chris@0
|
21 private $stream;
|
Chris@0
|
22
|
Chris@0
|
23 public function getProtocolVersion()
|
Chris@0
|
24 {
|
Chris@0
|
25 return $this->protocol;
|
Chris@0
|
26 }
|
Chris@0
|
27
|
Chris@0
|
28 public function withProtocolVersion($version)
|
Chris@0
|
29 {
|
Chris@0
|
30 if ($this->protocol === $version) {
|
Chris@0
|
31 return $this;
|
Chris@0
|
32 }
|
Chris@0
|
33
|
Chris@0
|
34 $new = clone $this;
|
Chris@0
|
35 $new->protocol = $version;
|
Chris@0
|
36 return $new;
|
Chris@0
|
37 }
|
Chris@0
|
38
|
Chris@0
|
39 public function getHeaders()
|
Chris@0
|
40 {
|
Chris@0
|
41 return $this->headers;
|
Chris@0
|
42 }
|
Chris@0
|
43
|
Chris@0
|
44 public function hasHeader($header)
|
Chris@0
|
45 {
|
Chris@0
|
46 return isset($this->headerNames[strtolower($header)]);
|
Chris@0
|
47 }
|
Chris@0
|
48
|
Chris@0
|
49 public function getHeader($header)
|
Chris@0
|
50 {
|
Chris@0
|
51 $header = strtolower($header);
|
Chris@0
|
52
|
Chris@0
|
53 if (!isset($this->headerNames[$header])) {
|
Chris@0
|
54 return [];
|
Chris@0
|
55 }
|
Chris@0
|
56
|
Chris@0
|
57 $header = $this->headerNames[$header];
|
Chris@0
|
58
|
Chris@0
|
59 return $this->headers[$header];
|
Chris@0
|
60 }
|
Chris@0
|
61
|
Chris@0
|
62 public function getHeaderLine($header)
|
Chris@0
|
63 {
|
Chris@0
|
64 return implode(', ', $this->getHeader($header));
|
Chris@0
|
65 }
|
Chris@0
|
66
|
Chris@0
|
67 public function withHeader($header, $value)
|
Chris@0
|
68 {
|
Chris@0
|
69 if (!is_array($value)) {
|
Chris@0
|
70 $value = [$value];
|
Chris@0
|
71 }
|
Chris@0
|
72
|
Chris@0
|
73 $value = $this->trimHeaderValues($value);
|
Chris@0
|
74 $normalized = strtolower($header);
|
Chris@0
|
75
|
Chris@0
|
76 $new = clone $this;
|
Chris@0
|
77 if (isset($new->headerNames[$normalized])) {
|
Chris@0
|
78 unset($new->headers[$new->headerNames[$normalized]]);
|
Chris@0
|
79 }
|
Chris@0
|
80 $new->headerNames[$normalized] = $header;
|
Chris@0
|
81 $new->headers[$header] = $value;
|
Chris@0
|
82
|
Chris@0
|
83 return $new;
|
Chris@0
|
84 }
|
Chris@0
|
85
|
Chris@0
|
86 public function withAddedHeader($header, $value)
|
Chris@0
|
87 {
|
Chris@0
|
88 if (!is_array($value)) {
|
Chris@0
|
89 $value = [$value];
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 $value = $this->trimHeaderValues($value);
|
Chris@0
|
93 $normalized = strtolower($header);
|
Chris@0
|
94
|
Chris@0
|
95 $new = clone $this;
|
Chris@0
|
96 if (isset($new->headerNames[$normalized])) {
|
Chris@0
|
97 $header = $this->headerNames[$normalized];
|
Chris@0
|
98 $new->headers[$header] = array_merge($this->headers[$header], $value);
|
Chris@0
|
99 } else {
|
Chris@0
|
100 $new->headerNames[$normalized] = $header;
|
Chris@0
|
101 $new->headers[$header] = $value;
|
Chris@0
|
102 }
|
Chris@0
|
103
|
Chris@0
|
104 return $new;
|
Chris@0
|
105 }
|
Chris@0
|
106
|
Chris@0
|
107 public function withoutHeader($header)
|
Chris@0
|
108 {
|
Chris@0
|
109 $normalized = strtolower($header);
|
Chris@0
|
110
|
Chris@0
|
111 if (!isset($this->headerNames[$normalized])) {
|
Chris@0
|
112 return $this;
|
Chris@0
|
113 }
|
Chris@0
|
114
|
Chris@0
|
115 $header = $this->headerNames[$normalized];
|
Chris@0
|
116
|
Chris@0
|
117 $new = clone $this;
|
Chris@0
|
118 unset($new->headers[$header], $new->headerNames[$normalized]);
|
Chris@0
|
119
|
Chris@0
|
120 return $new;
|
Chris@0
|
121 }
|
Chris@0
|
122
|
Chris@0
|
123 public function getBody()
|
Chris@0
|
124 {
|
Chris@0
|
125 if (!$this->stream) {
|
Chris@0
|
126 $this->stream = stream_for('');
|
Chris@0
|
127 }
|
Chris@0
|
128
|
Chris@0
|
129 return $this->stream;
|
Chris@0
|
130 }
|
Chris@0
|
131
|
Chris@0
|
132 public function withBody(StreamInterface $body)
|
Chris@0
|
133 {
|
Chris@0
|
134 if ($body === $this->stream) {
|
Chris@0
|
135 return $this;
|
Chris@0
|
136 }
|
Chris@0
|
137
|
Chris@0
|
138 $new = clone $this;
|
Chris@0
|
139 $new->stream = $body;
|
Chris@0
|
140 return $new;
|
Chris@0
|
141 }
|
Chris@0
|
142
|
Chris@0
|
143 private function setHeaders(array $headers)
|
Chris@0
|
144 {
|
Chris@0
|
145 $this->headerNames = $this->headers = [];
|
Chris@0
|
146 foreach ($headers as $header => $value) {
|
Chris@0
|
147 if (!is_array($value)) {
|
Chris@0
|
148 $value = [$value];
|
Chris@0
|
149 }
|
Chris@0
|
150
|
Chris@0
|
151 $value = $this->trimHeaderValues($value);
|
Chris@0
|
152 $normalized = strtolower($header);
|
Chris@0
|
153 if (isset($this->headerNames[$normalized])) {
|
Chris@0
|
154 $header = $this->headerNames[$normalized];
|
Chris@0
|
155 $this->headers[$header] = array_merge($this->headers[$header], $value);
|
Chris@0
|
156 } else {
|
Chris@0
|
157 $this->headerNames[$normalized] = $header;
|
Chris@0
|
158 $this->headers[$header] = $value;
|
Chris@0
|
159 }
|
Chris@0
|
160 }
|
Chris@0
|
161 }
|
Chris@0
|
162
|
Chris@0
|
163 /**
|
Chris@0
|
164 * Trims whitespace from the header values.
|
Chris@0
|
165 *
|
Chris@0
|
166 * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field.
|
Chris@0
|
167 *
|
Chris@0
|
168 * header-field = field-name ":" OWS field-value OWS
|
Chris@0
|
169 * OWS = *( SP / HTAB )
|
Chris@0
|
170 *
|
Chris@0
|
171 * @param string[] $values Header values
|
Chris@0
|
172 *
|
Chris@0
|
173 * @return string[] Trimmed header values
|
Chris@0
|
174 *
|
Chris@0
|
175 * @see https://tools.ietf.org/html/rfc7230#section-3.2.4
|
Chris@0
|
176 */
|
Chris@0
|
177 private function trimHeaderValues(array $values)
|
Chris@0
|
178 {
|
Chris@0
|
179 return array_map(function ($value) {
|
Chris@0
|
180 return trim($value, " \t");
|
Chris@0
|
181 }, $values);
|
Chris@0
|
182 }
|
Chris@0
|
183 }
|