This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Veto. |
||
4 | * PHP Microframework. |
||
5 | * |
||
6 | * @author Damien Walsh <[email protected]> |
||
7 | * @copyright Damien Walsh 2013-2014 |
||
8 | * @version 0.1 |
||
9 | * @package veto |
||
10 | */ |
||
11 | namespace Veto\Http; |
||
12 | |||
13 | use Psr\Http\Message\ResponseInterface; |
||
14 | use Psr\Http\Message\StreamInterface; |
||
15 | use Veto\Collection\Bag; |
||
16 | |||
17 | /** |
||
18 | * Response |
||
19 | * |
||
20 | * @since 0.1 |
||
21 | */ |
||
22 | class Response implements ResponseInterface |
||
23 | { |
||
24 | /** |
||
25 | * The response HTTP protocol version |
||
26 | * |
||
27 | * @var string |
||
28 | */ |
||
29 | protected $protocolVersion = '1.1'; |
||
30 | |||
31 | /** |
||
32 | * The response HTTP status code |
||
33 | * |
||
34 | * @var int |
||
35 | */ |
||
36 | protected $status = 200; |
||
37 | |||
38 | /** |
||
39 | * The response reason phrase |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | protected $reasonPhrase; |
||
44 | |||
45 | /** |
||
46 | * The response HTTP headers |
||
47 | * |
||
48 | * @var HeaderBag |
||
49 | */ |
||
50 | protected $headers; |
||
51 | |||
52 | /** |
||
53 | * The response cookies |
||
54 | * |
||
55 | * @var Bag |
||
56 | */ |
||
57 | protected $cookies; |
||
58 | |||
59 | /** |
||
60 | * The response body |
||
61 | * |
||
62 | * @var StreamInterface |
||
63 | */ |
||
64 | protected $body; |
||
65 | |||
66 | /** |
||
67 | * Create new HTTP response |
||
68 | * |
||
69 | * @param StreamInterface|string|null $body The response body |
||
70 | * @param int $status The response HTTP status code |
||
71 | * @param Bag|null $headers The response HTTP headers |
||
72 | * @param Bag|null $cookies The response cookies |
||
73 | */ |
||
74 | public function __construct($body = null, $status = 200, Bag $headers = null, Bag $cookies = null) |
||
75 | { |
||
76 | // If we're passed a StreamInterface, use it as the response body |
||
77 | if ($body instanceof StreamInterface) { |
||
78 | $this->body = $body; |
||
79 | } else { |
||
80 | |||
81 | // Otherwise, create one |
||
82 | $this->body = new MessageBody(fopen('php://temp', 'r+')); |
||
83 | |||
84 | // Optionally, writing the provided string to it |
||
85 | if (is_string($body)) { |
||
86 | $this->body->write($body); |
||
87 | } |
||
88 | } |
||
89 | |||
90 | $this->status = $status; |
||
91 | $this->headers = $headers ? $headers : new HeaderBag(); |
||
0 ignored issues
–
show
|
|||
92 | $this->cookies = $cookies ? $cookies : new Bag(); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Deep-copy any associated objects when cloning. |
||
97 | */ |
||
98 | public function __clone() |
||
99 | { |
||
100 | $this->headers = clone $this->headers; |
||
101 | $this->cookies = clone $this->cookies; |
||
102 | $this->body = clone $this->body; |
||
103 | } |
||
104 | |||
105 | /** |
||
106 | * Send both headers and content. |
||
107 | */ |
||
108 | public function send() |
||
109 | { |
||
110 | $this->sendHeaders(); |
||
111 | $this->sendBody(); |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * Send the HTTP headers for this response. |
||
116 | */ |
||
117 | public function sendHeaders() |
||
118 | { |
||
119 | if (false === headers_sent()) { |
||
120 | |||
121 | // Send the initial line compliant with the current SAPI |
||
122 | if (strpos(PHP_SAPI, 'cgi') === 0) { |
||
123 | header(sprintf( |
||
124 | 'Status: %s %s', |
||
125 | $this->getStatusCode(), |
||
126 | $this->getReasonPhrase() |
||
127 | )); |
||
128 | } else { |
||
129 | header(sprintf( |
||
130 | 'HTTP/%s %s %s', |
||
131 | $this->getProtocolVersion(), |
||
132 | $this->getStatusCode(), |
||
133 | $this->getReasonPhrase() |
||
134 | )); |
||
135 | } |
||
136 | |||
137 | // Send each header |
||
138 | foreach ($this->getHeaders() as $name => $values) { |
||
139 | foreach ($values as $value) { |
||
140 | header(sprintf('%s: %s', $name, $value), false); |
||
141 | } |
||
142 | } |
||
143 | } |
||
144 | |||
145 | return $this; |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * Send the body for this response. |
||
150 | * |
||
151 | * @param int $bufferSize The size of the chunks to read from the body into the output stream |
||
152 | * @return $this |
||
153 | */ |
||
154 | public function sendBody($bufferSize = 1024) |
||
155 | { |
||
156 | $body = $this->getBody(); |
||
157 | |||
158 | if ($body instanceof MessageBody) { |
||
159 | if ($body->isAttached()) { |
||
160 | $body->rewind(); |
||
161 | while (false === $body->eof()) { |
||
162 | print $body->read($bufferSize); |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | |||
167 | return $this; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * Retrieves the HTTP protocol version as a string. |
||
172 | * |
||
173 | * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0"). |
||
174 | * |
||
175 | * @return string HTTP protocol version. |
||
176 | */ |
||
177 | public function getProtocolVersion() |
||
178 | { |
||
179 | return $this->protocolVersion; |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * Create a new instance with the specified HTTP protocol version. |
||
184 | * |
||
185 | * The version string MUST contain only the HTTP version number (e.g., |
||
186 | * "1.1", "1.0"). |
||
187 | * |
||
188 | * This method MUST be implemented in such a way as to retain the |
||
189 | * immutability of the message, and MUST return a new instance that has the |
||
190 | * new protocol version. |
||
191 | * |
||
192 | * @param string $version HTTP protocol version |
||
193 | * @return self |
||
194 | */ |
||
195 | public function withProtocolVersion($version) |
||
196 | { |
||
197 | $clone = clone $this; |
||
198 | $clone->protocolVersion = $version; |
||
199 | |||
200 | return $clone; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Retrieves all message headers. |
||
205 | * |
||
206 | * The keys represent the header name as it will be sent over the wire, and |
||
207 | * each value is an array of strings associated with the header. |
||
208 | * |
||
209 | * // Represent the headers as a string |
||
210 | * foreach ($message->getHeaders() as $name => $values) { |
||
211 | * echo $name . ": " . implode(", ", $values); |
||
212 | * } |
||
213 | * |
||
214 | * // Emit headers iteratively: |
||
215 | * foreach ($message->getHeaders() as $name => $values) { |
||
216 | * foreach ($values as $value) { |
||
217 | * header(sprintf('%s: %s', $name, $value), false); |
||
218 | * } |
||
219 | * } |
||
220 | * |
||
221 | * While header names are not case-sensitive, getHeaders() will preserve the |
||
222 | * exact case in which headers were originally specified. |
||
223 | * |
||
224 | * @return array Returns an associative array of the message's headers. Each |
||
225 | * key MUST be a header name, and each value MUST be an array of strings. |
||
226 | */ |
||
227 | public function getHeaders() |
||
228 | { |
||
229 | return $this->headers; |
||
0 ignored issues
–
show
The return type of
return $this->headers; (Veto\Http\HeaderBag ) is incompatible with the return type declared by the interface Psr\Http\Message\MessageInterface::getHeaders of type array .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Checks if a header exists by the given case-insensitive name. |
||
234 | * |
||
235 | * @param string $name Case-insensitive header field name. |
||
236 | * @return bool Returns true if any header names match the given header |
||
237 | * name using a case-insensitive string comparison. Returns false if |
||
238 | * no matching header name is found in the message. |
||
239 | */ |
||
240 | public function hasHeader($name) |
||
241 | { |
||
242 | return $this->headers->has($name); |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * Retrieves a message header value by the given case-insensitive name. |
||
247 | * |
||
248 | * This method returns an array of all the header values of the given |
||
249 | * case-insensitive header name. |
||
250 | * |
||
251 | * If the header does not appear in the message, this method MUST return an |
||
252 | * empty array. |
||
253 | * |
||
254 | * @param string $name Case-insensitive header field name. |
||
255 | * @return string[] An array of string values as provided for the given |
||
256 | * header. If the header does not appear in the message, this method MUST |
||
257 | * return an empty array. |
||
258 | */ |
||
259 | public function getHeader($name) |
||
260 | { |
||
261 | return $this->headers->get($name); |
||
262 | } |
||
263 | |||
264 | /** |
||
265 | * Retrieves the line for a single header, with the header values as a |
||
266 | * comma-separated string. |
||
267 | * |
||
268 | * This method returns all of the header values of the given |
||
269 | * case-insensitive header name as a string concatenated together using |
||
270 | * a comma. |
||
271 | * |
||
272 | * NOTE: Not all header values may be appropriately represented using |
||
273 | * comma concatenation. For such headers, use getHeader() instead |
||
274 | * and supply your own delimiter when concatenating. |
||
275 | * |
||
276 | * If the header does not appear in the message, this method MUST return |
||
277 | * a null value. |
||
278 | * |
||
279 | * @param string $name Case-insensitive header field name. |
||
280 | * @return string|null A string of values as provided for the given header |
||
281 | * concatenated together using a comma. If the header does not appear in |
||
282 | * the message, this method MUST return a null value. |
||
283 | */ |
||
284 | public function getHeaderLine($name) |
||
285 | { |
||
286 | return implode(',', $this->headers->get($name)); |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * Create a new instance with the provided header, replacing any existing |
||
291 | * values of any headers with the same case-insensitive name. |
||
292 | * |
||
293 | * While header names are case-insensitive, the casing of the header will |
||
294 | * be preserved by this function, and returned from getHeaders(). |
||
295 | * |
||
296 | * This method MUST be implemented in such a way as to retain the |
||
297 | * immutability of the message, and MUST return a new instance that has the |
||
298 | * new and/or updated header and value. |
||
299 | * |
||
300 | * @param string $name Case-insensitive header field name. |
||
301 | * @param string|string[] $value Header value(s). |
||
302 | * @return self |
||
303 | * @throws \InvalidArgumentException for invalid header names or values. |
||
304 | */ |
||
305 | View Code Duplication | public function withHeader($name, $value) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
306 | { |
||
307 | $clone = clone $this; |
||
308 | $clone->headers = new HeaderBag(); |
||
309 | $clone->headers->add($name, $value); |
||
310 | |||
311 | return $clone; |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * Creates a new instance, with the specified header appended with the |
||
316 | * given value. |
||
317 | * |
||
318 | * Existing values for the specified header will be maintained. The new |
||
319 | * value(s) will be appended to the existing list. If the header did not |
||
320 | * exist previously, it will be added. |
||
321 | * |
||
322 | * This method MUST be implemented in such a way as to retain the |
||
323 | * immutability of the message, and MUST return a new instance that has the |
||
324 | * new header and/or value. |
||
325 | * |
||
326 | * @param string $name Case-insensitive header field name to add. |
||
327 | * @param string|string[] $value Header value(s). |
||
328 | * @return self |
||
329 | * @throws \InvalidArgumentException for invalid header names or values. |
||
330 | */ |
||
331 | public function withAddedHeader($name, $value) |
||
332 | { |
||
333 | $clone = clone $this; |
||
334 | $clone->headers->add($name, $value); |
||
335 | |||
336 | return $clone; |
||
337 | } |
||
338 | |||
339 | /** |
||
340 | * Creates a new instance, without the specified header. |
||
341 | * |
||
342 | * Header resolution MUST be done without case-sensitivity. |
||
343 | * |
||
344 | * This method MUST be implemented in such a way as to retain the |
||
345 | * immutability of the message, and MUST return a new instance that removes |
||
346 | * the named header. |
||
347 | * |
||
348 | * @param string $name Case-insensitive header field name to remove. |
||
349 | * @return self |
||
350 | */ |
||
351 | public function withoutHeader($name) |
||
352 | { |
||
353 | $clone = clone $this; |
||
354 | $clone->headers = new HeaderBag(); |
||
355 | $clone->headers->remove($name); |
||
356 | |||
357 | return $clone; |
||
358 | } |
||
359 | |||
360 | /** |
||
361 | * Gets the body of the message. |
||
362 | * |
||
363 | * @return StreamInterface Returns the body as a stream. |
||
364 | */ |
||
365 | public function getBody() |
||
366 | { |
||
367 | return $this->body; |
||
368 | } |
||
369 | |||
370 | /** |
||
371 | * Create a new instance, with the specified message body. |
||
372 | * |
||
373 | * The body MUST be a StreamInterface object. |
||
374 | * |
||
375 | * This method MUST be implemented in such a way as to retain the |
||
376 | * immutability of the message, and MUST return a new instance that has the |
||
377 | * new body stream. |
||
378 | * |
||
379 | * @param StreamInterface $body Body. |
||
380 | * @return self |
||
381 | * @throws \InvalidArgumentException When the body is not valid. |
||
382 | */ |
||
383 | public function withBody(StreamInterface $body) |
||
384 | { |
||
385 | $clone = clone $this; |
||
386 | $clone->body = $body; |
||
387 | |||
388 | return $clone; |
||
389 | } |
||
390 | |||
391 | /** |
||
392 | * Gets the response Status-Code. |
||
393 | * |
||
394 | * The Status-Code is a 3-digit integer result code of the server's attempt |
||
395 | * to understand and satisfy the request. |
||
396 | * |
||
397 | * @return integer Status code. |
||
398 | */ |
||
399 | public function getStatusCode() |
||
400 | { |
||
401 | return $this->status; |
||
402 | } |
||
403 | |||
404 | /** |
||
405 | * Create a new instance with the specified status code, and optionally |
||
406 | * reason phrase, for the response. |
||
407 | * |
||
408 | * If no Reason-Phrase is specified, implementations MAY choose to default |
||
409 | * to the RFC 7231 or IANA recommended reason phrase for the response's |
||
410 | * Status-Code. |
||
411 | * |
||
412 | * This method MUST be implemented in such a way as to retain the |
||
413 | * immutability of the message, and MUST return a new instance that has the |
||
414 | * updated status and reason phrase. |
||
415 | * |
||
416 | * @link http://tools.ietf.org/html/rfc7231#section-6 |
||
417 | * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml |
||
418 | * @param integer $code The 3-digit integer result code to set. |
||
419 | * @param null|string $reasonPhrase The reason phrase to use with the |
||
420 | * provided status code; if none is provided, implementations MAY |
||
421 | * use the defaults as suggested in the HTTP specification. |
||
422 | * @return self |
||
423 | * @throws \InvalidArgumentException For invalid status code arguments. |
||
424 | */ |
||
425 | public function withStatus($code, $reasonPhrase = null) |
||
426 | { |
||
427 | $clone = clone $this; |
||
428 | $clone->status = $code; |
||
429 | $clone->reasonPhrase = $reasonPhrase; |
||
430 | |||
431 | return $clone; |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * Gets the response Reason-Phrase, a short textual description of the Status-Code. |
||
436 | * |
||
437 | * Because a Reason-Phrase is not a required element in a response |
||
438 | * Status-Line, the Reason-Phrase value MAY be null. Implementations MAY |
||
439 | * choose to return the default RFC 7231 recommended reason phrase (or those |
||
440 | * listed in the IANA HTTP Status Code Registry) for the response's |
||
441 | * Status-Code. |
||
442 | * |
||
443 | * @link http://tools.ietf.org/html/rfc7231#section-6 |
||
444 | * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml |
||
445 | * @return string|null Reason phrase, or null if unknown. |
||
446 | */ |
||
447 | public function getReasonPhrase() |
||
448 | { |
||
449 | return $this->reasonPhrase; |
||
450 | } |
||
451 | } |
||
452 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.
Either this assignment is in error or an instanceof check should be added for that assignment.