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 | /** |
||
4 | * |
||
5 | * This file is part of the Apix Project. |
||
6 | * |
||
7 | * (c) Franck Cassedanne <franck at ouarz.net> |
||
8 | * |
||
9 | * @license http://opensource.org/licenses/BSD-3-Clause New BSD License |
||
10 | * |
||
11 | */ |
||
12 | |||
13 | namespace Apix; |
||
14 | |||
15 | /** |
||
16 | * Represents a response. |
||
17 | */ |
||
18 | class Response extends Listener |
||
19 | { |
||
20 | |||
21 | /** |
||
22 | * List of supported response formats. |
||
23 | * @var array |
||
24 | */ |
||
25 | protected $formats = array('json', 'xml', 'html'); |
||
26 | |||
27 | /** |
||
28 | * Holds the current output format. |
||
29 | * Also use to set the default value. |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $format = 'html'; |
||
33 | |||
34 | /** |
||
35 | * Character encoding. |
||
36 | * @var string |
||
37 | */ |
||
38 | protected $encoding = 'UTF-8'; |
||
39 | |||
40 | /** |
||
41 | * Holds the arrays of HTTP headers. |
||
42 | * @var array |
||
43 | */ |
||
44 | protected $headers = array(); |
||
45 | |||
46 | /** |
||
47 | * Holds the current HTTP Code. |
||
48 | * @var string |
||
49 | */ |
||
50 | protected $http_code = 200; |
||
51 | |||
52 | /** |
||
53 | * Holds the current output. |
||
54 | * @var string |
||
55 | */ |
||
56 | public $output = null; |
||
57 | |||
58 | /** |
||
59 | * Associative array of HTTP phrases. |
||
60 | * |
||
61 | * @var array |
||
62 | * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html |
||
63 | * @link http://tools.ietf.org/html/rfc2616#section-10 |
||
64 | */ |
||
65 | protected static $http_phrases = array( |
||
66 | |||
67 | // 1xx: Informational - Request received, continuing process |
||
68 | 100 => 'Continue', |
||
69 | 101 => 'Switching Protocols', |
||
70 | |||
71 | // 2xx: Success - The action was successfully received, understood and |
||
72 | // accepted |
||
73 | 200 => 'OK', |
||
74 | 201 => 'Created', |
||
75 | 202 => 'Accepted', |
||
76 | 203 => 'Non-Authoritative Information', |
||
77 | 204 => 'No Content', |
||
78 | 205 => 'Reset Content', |
||
79 | 206 => 'Partial Content', |
||
80 | 207 => 'Multi-Status', |
||
81 | |||
82 | // 3xx: Redirection - Further action must be taken in order to complete |
||
83 | // the request |
||
84 | 300 => 'Multiple Choices', |
||
85 | 301 => 'Moved Permanently', |
||
86 | 302 => 'Found', // 1.1 |
||
87 | 303 => 'See Other', |
||
88 | 304 => 'Not Modified', |
||
89 | 305 => 'Use Proxy', |
||
90 | 307 => 'Temporary Redirect', |
||
91 | |||
92 | // 4xx: Client Error - The request contains bad syntax or cannot be |
||
93 | // fulfilled |
||
94 | 400 => 'Bad Request', |
||
95 | 401 => 'Unauthorized', |
||
96 | 402 => 'Payment Required', |
||
97 | 403 => 'Forbidden', |
||
98 | 404 => 'Not Found', |
||
99 | 405 => 'Method Not Allowed', |
||
100 | 406 => 'Not Acceptable', |
||
101 | 407 => 'Proxy Authentication Required', |
||
102 | 408 => 'Request Timeout', |
||
103 | 409 => 'Conflict', |
||
104 | 410 => 'Gone', |
||
105 | 411 => 'Length Required', |
||
106 | 412 => 'Precondition Failed', |
||
107 | 413 => 'Request Entity Too Large', |
||
108 | 414 => 'Request-URI Too Long', |
||
109 | 415 => 'Unsupported Media Type', |
||
110 | 416 => 'Requested Range Not Satisfiable', |
||
111 | 417 => 'Expectation Failed', |
||
112 | 422 => 'Unprocessable Entity', |
||
113 | 423 => 'Locked', |
||
114 | 424 => 'Failed Dependency', |
||
115 | 426 => 'Upgrade Required', |
||
116 | |||
117 | // 5xx: Server Error - The server failed to fulfill an apparently |
||
118 | // valid request |
||
119 | 500 => 'Internal Server Error', |
||
120 | 501 => 'Not Implemented', |
||
121 | 502 => 'Bad Gateway', |
||
122 | 503 => 'Service Unavailable', |
||
123 | 504 => 'Gateway Timeout', |
||
124 | 505 => 'HTTP Version Not Supported', |
||
125 | 506 => 'Variant Also Negotiates', |
||
126 | 507 => 'Insufficient Storage', |
||
127 | 509 => 'Bandwidth Limit Exceeded', |
||
128 | 510 => 'Not Extended' |
||
129 | ); |
||
130 | |||
131 | /** |
||
132 | * Associative array of long HTTP phrases. |
||
133 | * |
||
134 | * @var array |
||
135 | */ |
||
136 | protected static $long_http_phrases = array( |
||
137 | |||
138 | 200 => 'The request has succeeded.', |
||
139 | 201 => 'The request has been fulfilled and resulted in a new resource being created.', |
||
140 | |||
141 | // Resulting from a POST, requires to use ->setHeader("Location", "/resource/action/id") |
||
142 | 202 => 'The request has been accepted for processing, but the processing has not been completed.', |
||
143 | |||
144 | // DELETE |
||
145 | 204 => 'Request fulfilled successfully.', |
||
146 | |||
147 | // Errors |
||
148 | 400 => 'Request is malformed.', |
||
149 | 401 => 'Not Authenticated.', |
||
150 | 403 => 'Access to this ressource has been denied.', |
||
151 | 404 => 'No ressource found at the Request-URI.', |
||
152 | 501 => 'This resource entity is not (yet) implemented. Try again later.', |
||
153 | 503 => 'The service is currently unable to handle the request due to a temporary overloading or maintenance of the server. Try again later.' |
||
154 | ); |
||
155 | |||
156 | /** |
||
157 | * @var Apix\Request |
||
158 | */ |
||
159 | protected $request; |
||
160 | |||
161 | /** |
||
162 | * Returns the request object. |
||
163 | * |
||
164 | * @return Request |
||
165 | */ |
||
166 | public function getRequest() |
||
167 | { |
||
168 | return $this->request; |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * @var Apix\Router |
||
173 | */ |
||
174 | protected $route; |
||
175 | |||
176 | /** |
||
177 | * Sets the route object. |
||
178 | */ |
||
179 | public function setRoute(Router $route) |
||
180 | { |
||
181 | $this->route = $route; |
||
0 ignored issues
–
show
|
|||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Returns the route object. |
||
186 | * |
||
187 | * @return Router |
||
188 | */ |
||
189 | public function getRoute() |
||
190 | { |
||
191 | return $this->route; |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * Constructor. |
||
196 | * |
||
197 | * @param Request $request |
||
198 | */ |
||
199 | public function __construct(Request $request) |
||
200 | { |
||
201 | $this->request = $request; |
||
0 ignored issues
–
show
It seems like
$request of type object<Apix\Request> is incompatible with the declared type object<Apix\Apix\Request> of property $request .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
202 | } |
||
203 | |||
204 | /** |
||
205 | * Sets the output format. |
||
206 | * |
||
207 | * @param string $format |
||
208 | * @param string $default |
||
209 | * @throws \DomainException 406 |
||
210 | */ |
||
211 | public function setFormat($format, $default=null) |
||
212 | { |
||
213 | $format = strtolower($format); |
||
214 | if (!in_array($format, $this->getFormats())) { |
||
215 | $this->format = strtolower($default); |
||
216 | throw new \DomainException( |
||
217 | sprintf('Format (%s) not supported.', $format), |
||
218 | 406 // maybe 404? |
||
219 | ); |
||
220 | } |
||
221 | $this->format = $format; |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Returns the output format. |
||
226 | * |
||
227 | * @return string |
||
228 | */ |
||
229 | public function getFormat() |
||
230 | { |
||
231 | return $this->format; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Sets all the response formats available. |
||
236 | * |
||
237 | * @return void |
||
238 | */ |
||
239 | public function setFormats(array $formats) |
||
240 | { |
||
241 | $this->formats = $formats; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Returns all the response formats available. |
||
246 | * |
||
247 | * @return array |
||
248 | */ |
||
249 | public function getFormats() |
||
250 | { |
||
251 | return $this->formats; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Sets a response header. |
||
256 | * |
||
257 | * @param string $key |
||
258 | * @param string $value |
||
259 | * @param boolean $overwrite Wether to overwrite an existing header. |
||
260 | */ |
||
261 | public function setHeader($key, $value, $overwrite=true) |
||
262 | { |
||
263 | if (!$overwrite && isset($this->headers[$key])) { |
||
264 | return; |
||
265 | } |
||
266 | $this->headers[$key] = $value; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Gets the specified response header. |
||
271 | * |
||
272 | * @param string $key |
||
273 | * @return string |
||
274 | */ |
||
275 | public function getHeader($key) |
||
276 | { |
||
277 | return isset($this->headers[$key]) ? $this->headers[$key] : null; |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Returns the header array. |
||
282 | * |
||
283 | * @return array |
||
284 | */ |
||
285 | public function getHeaders() |
||
286 | { |
||
287 | return $this->headers; |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * Sends the headers thru HTTP. |
||
292 | * |
||
293 | * header('Cache-Control: no-cache, must-revalidate'); // HTTP/1.1 |
||
294 | * header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past |
||
295 | * // upload example |
||
296 | * header('Content-Disposition: attachment; filename="downloaded.pdf"'); |
||
297 | * readfile('original.pdf'); |
||
298 | * |
||
299 | * @param integer $http_code |
||
300 | * @param string $version |
||
301 | */ |
||
302 | public function sendAllHttpHeaders($http_code, $version) |
||
303 | { |
||
304 | // PHP bug? TODO: |
||
305 | // $out = $this->sendheader("Status: $http_code " . static::getStatusPrases($http_code)); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
58% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
306 | // //$out = $this->sendheader("HTTP/1.0 $http_code " . static::getStatusPrases($http_code), true); |
||
307 | // $out[] = array( $this->sendHeader('X-Powered-By: ' . $version_string) ); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
57% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
308 | |||
309 | $out = array( |
||
310 | $this->sendHeader('X-Powered-By: ' . $version, true, $http_code) |
||
311 | ); |
||
312 | |||
313 | foreach ($this->headers as $key => $value) { |
||
314 | $out[] = $this->sendheader($key . ': ' . $value); |
||
315 | } |
||
316 | |||
317 | return $out; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * Sends one header thru HTTP |
||
322 | * @param vary |
||
323 | */ |
||
324 | public function sendHeader() |
||
325 | { |
||
326 | $args = func_get_args(); |
||
327 | |||
328 | return isset($this->unit_test) |
||
329 | ? $args |
||
330 | : call_user_func_array('header', $args); |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * Sets the current HTTP code. |
||
335 | * |
||
336 | * @param integer $int |
||
337 | * @return void |
||
338 | */ |
||
339 | public function setHttpCode($int) |
||
340 | { |
||
341 | $this->http_code = (int) $int; |
||
0 ignored issues
–
show
The property
$http_code was declared of type string , but (int) $int is of type integer . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
342 | } |
||
343 | |||
344 | /** |
||
345 | * Gets the current HTTP code. |
||
346 | * |
||
347 | * @return intger |
||
348 | */ |
||
349 | public function getHttpCode() |
||
350 | { |
||
351 | return $this->http_code; |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * Returns an HTTP status phrase. |
||
356 | * |
||
357 | * @param integer $http_code |
||
358 | * @param boolean $long |
||
359 | * @return string |
||
360 | */ |
||
361 | public static function getStatusPrases($http_code=null, $long=false) |
||
362 | { |
||
363 | //$http_code = is_null($http_code) ? $this->http_code : $http_code; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
53% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
364 | $type = $long === true ? self::$long_http_phrases : self::$http_phrases; |
||
365 | $status = self::$http_phrases[$http_code]; |
||
366 | |||
367 | return $long === true |
||
368 | ? isset($type[$http_code]) ? $type[$http_code] : $http_code . ' ' . $status |
||
369 | : $status; |
||
370 | } |
||
371 | |||
372 | /** |
||
373 | * Returns sucessful or failed string. |
||
374 | * |
||
375 | * @param integer $http_code |
||
376 | * @return string |
||
377 | */ |
||
378 | public static function getStatusAdjective($http_code) |
||
379 | { |
||
380 | return floor($http_code/100)<=3 ? 'successful' : 'failed'; |
||
381 | } |
||
382 | |||
383 | /** |
||
384 | * Returns a collated array representation of the output. |
||
385 | * |
||
386 | * @return array |
||
387 | */ |
||
388 | public function collate(array $results) |
||
389 | { |
||
390 | $top = is_object($this->route) |
||
391 | && $this->route->getController() |
||
392 | ? $this->route->getController() |
||
393 | : 'index'; |
||
394 | |||
395 | return array($top => $results); |
||
396 | } |
||
397 | |||
398 | /** |
||
399 | * Generates the response & send the headers... |
||
400 | * |
||
401 | * @param array $results |
||
402 | * @param string $version_string |
||
403 | * @param string $rootNode |
||
404 | * @return string |
||
405 | */ |
||
406 | public function generate(array $results, $version_string='ouarz', $rootNode='root') |
||
407 | { |
||
408 | $this->results = $this->collate($results); |
||
0 ignored issues
–
show
The property
results does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
409 | // var_dump( $results );echo __METHOD__;exit; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
65% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
410 | |||
411 | // early listeners @ post-response |
||
412 | $this->hook('response', 'early'); |
||
413 | |||
414 | $renderer = __NAMESPACE__ . '\Output\\' . ucfirst($this->getFormat()); |
||
415 | $view = new $renderer($this->encoding); |
||
416 | |||
417 | $this->setHeader('Content-Type', $view->getContentType()); |
||
418 | $this->sendAllHttpHeaders($this->getHttpCode(), $version_string); |
||
419 | |||
420 | if (null === $this->output) { |
||
421 | $this->output = $view->encode( |
||
422 | $this->results, |
||
423 | $rootNode |
||
424 | ); |
||
425 | } |
||
426 | |||
427 | // late listeners @ post-response |
||
428 | $this->hook('response', 'late'); |
||
429 | } |
||
430 | |||
431 | /** |
||
432 | * Returns the response output. |
||
433 | * |
||
434 | * @return string |
||
435 | */ |
||
436 | public function getOutput() |
||
437 | { |
||
438 | return $this->output; |
||
439 | } |
||
440 | |||
441 | /** |
||
442 | * Sets the response output. |
||
443 | * |
||
444 | * @param string $string |
||
445 | */ |
||
446 | public function setOutput($string) |
||
447 | { |
||
448 | $this->output = $string; |
||
449 | } |
||
450 | |||
451 | } |
||
452 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..