Failed Conditions
Pull Request — master (#30)
by Maximo
04:14 queued 12s
created

SwooleRequest::getUploadedFiles()   B

Complexity

Conditions 9
Paths 2

Size

Total Lines 40
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
cc 9
eloc 25
nc 2
nop 1
dl 0
loc 40
ccs 0
cts 35
cp 0
crap 90
rs 8.0555
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
3
// | SwooleRequest.php [ WE CAN DO IT JUST THINK IT ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2016-2017 limingxinleo All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Author: limx <[email protected]> <https://github.com/limingxinleo>
8
// +----------------------------------------------------------------------
9
10
namespace Gewaer\Http;
11
12
use Phalcon\DiInterface;
13
use Phalcon\Events\Manager;
14
use Phalcon\FilterInterface;
15
use Phalcon\Http\RequestInterface;
16
use Phalcon\Di\InjectionAwareInterface;
17
use Phalcon\Http\Request\File;
18
use Phalcon\Text;
19
use swoole_http_request;
0 ignored issues
show
Bug introduced by
The type swoole_http_request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Exception;
21
use Phalcon\Di\FactoryDefault;
22
use function Gewaer\Core\isJson;
23
24
class SwooleRequest implements RequestInterface, InjectionAwareInterface
25
{
26
    protected $_dependencyInjector;
27
28
    protected $_httpMethodParameterOverride = false;
29
30
    protected $_filter;
31
32
    protected $_putCache;
33
34
    protected $_strictHostCheck = false;
35
36
    protected $_files;
37
38
    protected $headers;
39
40
    protected $server;
41
42
    protected $get;
43
44
    protected $post;
45
46
    protected $cookies;
47
48
    protected $files;
49
50
    protected $swooleRequest;
51
52
    public function init(swoole_http_request $request)
53
    {
54
        $this->swooleRequest = $request;
55
        $this->headers = [];
56
        $this->server = [];
57
58
        $this->get = isset($request->get) ? $request->get : [];
59
        $this->post = isset($request->post) ? $request->post : [];
60
        $this->cookies = isset($request->cookie) ? $request->cookie : [];
61
        $this->files = isset($request->files) ? $request->files : [];
62
        $this->_rawBody = $request->rawContent();
0 ignored issues
show
Bug Best Practice introduced by
The property _rawBody does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
63
64
        foreach ($request->header as $key => $val) {
65
            $key = strtoupper(str_replace(['-'], '_', $key));
66
            $this->headers[$key] = $val;
67
            $this->server[$key] = $val;
68
        }
69
        foreach ($request->server as $key => $val) {
70
            $key = strtoupper(str_replace(['-'], '_', $key));
71
            $this->server[$key] = $val;
72
        }
73
74
        /** @var Cookies $cookies */
75
        //$cookies = FactoryDefault::getDefault()->getCookies();
76
        //  $cookies->setSwooleCookies($this->cookies);
77
    }
78
79
    public function setDI(DiInterface $dependencyInjector)
80
    {
81
        $this->_dependencyInjector = $dependencyInjector;
82
    }
83
84
    public function getDI()
85
    {
86
        return $this->_dependencyInjector;
87
    }
88
89
    public function get($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
90
    {
91
        $source = array_merge($this->get, $this->post);
92
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
93
    }
94
95
    public function getPost($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
96
    {
97
        $source = $this->post;
98
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
99
    }
100
101
    public function getQuery($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
102
    {
103
        $source = $this->get;
104
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
105
    }
106
107
    public function getServer($name)
108
    {
109
        $name = strtoupper(str_replace(['-'], '_', $name));
110
        if (isset($this->server[$name])) {
111
            return $this->server[$name];
112
        }
113
        return null;
114
    }
115
116
    public function getPut($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
117
    {
118
        $put = $this->_putCache;
119
120
        if (empty($put)) {
121
            if (!isJson($this->getRawBody())) {
122
                parse_str($this->getRawBody(), $put);
123
            } else {
124
                $put = $this->getJsonRawBody(true);
125
            }
126
            $this->_putCache = $put;
127
        }
128
129
        return $this->getHelper($put, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
130
    }
131
132
    public function has($name)
133
    {
134
        $source = array_merge($this->get, $this->post);
135
        return isset($source[$name]);
136
    }
137
138
    public function hasPost($name)
139
    {
140
        return isset($this->post[$name]);
141
    }
142
143
    public function hasPut($name)
144
    {
145
        $put = $this->getPut();
146
147
        return isset($put[$name]);
148
    }
149
150
    public function hasQuery($name)
151
    {
152
        return isset($this->get[$name]);
153
    }
154
155
    public function hasServer($name)
156
    {
157
        $name = strtoupper(str_replace(['-'], '_', $name));
158
159
        return isset($this->server[$name]);
160
    }
161
162
    public function hasHeader($header)
163
    {
164
        if ($this->hasServer($header)) {
165
            return true;
166
        }
167
        if ($this->hasServer('HTTP_' . $header)) {
168
            return true;
169
        }
170
        return false;
171
    }
172
173
    public function getHeader($header)
174
    {
175
        $header = $this->getServer($header);
176
        if (isset($header)) {
177
            return $header;
178
        }
179
180
        $header = $this->getServer('HTTP_' . $header);
181
        if (isset($header)) {
182
            return $header;
183
        }
184
185
        return '';
186
    }
187
188
    public function getScheme()
189
    {
190
        $https = $this->getServer('HTTPS');
191
        if ($https && $https != 'off') {
192
            return 'https';
193
        }
194
195
        return 'http';
196
    }
197
198
    public function isAjax()
199
    {
200
        return $this->getServer('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest';
201
    }
202
203
    public function isSoap()
204
    {
205
        if ($this->hasServer('HTTP_SOAPACTION')) {
206
            return true;
207
        }
208
209
        $contentType = $this->getContentType();
210
        if (!empty($contentType)) {
211
            return memstr($contentType, 'application/soap+xml');
0 ignored issues
show
Bug introduced by
The function memstr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

211
            return /** @scrutinizer ignore-call */ memstr($contentType, 'application/soap+xml');
Loading history...
212
        }
213
214
        return false;
215
    }
216
217
    public function isSoapRequested()
218
    {
219
        return $this->isSoap();
220
    }
221
222
    public function isSecure()
223
    {
224
        return $this->getScheme() === 'https';
225
    }
226
227
    public function isSecureRequest()
228
    {
229
        return $this->isSecure();
230
    }
231
232
    public function getRawBody()
233
    {
234
        return $this->_rawBody;
235
    }
236
237
    public function getJsonRawBody($associative = false)
238
    {
239
        $rawBody = $this->getRawBody();
240
        if (!is_string($rawBody)) {
1 ignored issue
show
introduced by
The condition is_string($rawBody) is always true.
Loading history...
241
            return false;
242
        }
243
244
        return json_decode($rawBody, $associative);
245
    }
246
247
    public function getServerAddress()
248
    {
249
        $serverAddr = $this->getServer('SERVER_ADDR');
250
        if ($serverAddr) {
251
            return $serverAddr;
252
        }
253
254
        return gethostbyname('localhost');
255
    }
256
257
    public function getServerName()
258
    {
259
        $serverName = $this->getServer('SERVER_NAME');
260
        if ($serverName) {
261
            return $serverName;
262
        }
263
264
        return 'localhost';
265
    }
266
267
    public function getHttpHost()
268
    {
269
        $strict = $this->_strictHostCheck;
270
271
        /**
272
         * Get the server name from $_SERVER["HTTP_HOST"]
273
         */
274
        $host = $this->getServer('HTTP_HOST');
275
        if (!$host) {
276
            /**
277
             * Get the server name from $_SERVER["SERVER_NAME"]
278
             */
279
            $host = $this->getServer('SERVER_NAME');
280
            if (!host) {
0 ignored issues
show
Bug introduced by
The constant Gewaer\Http\host was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
281
                /**
282
                 * Get the server address from $_SERVER["SERVER_ADDR"]
283
                 */
284
                $host = $this->getServer('SERVER_ADDR');
285
            }
286
        }
287
288
        if ($host && $strict) {
289
            /**
290
             * Cleanup. Force lowercase as per RFC 952/2181
291
             */
292
            $host = strtolower(trim($host));
293
            if (memstr(host, ':')) {
0 ignored issues
show
Bug introduced by
The function memstr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

293
            if (/** @scrutinizer ignore-call */ memstr(host, ':')) {
Loading history...
294
                $host = preg_replace('/:[[:digit:]]+$/', '', $host);
295
            }
296
297
            /**
298
             * Host may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner),
299
             * the digits '0' through '9', and the hyphen ('-') as per RFC 952/2181
300
             */
301
            if ('' !== preg_replace("/[a-z0-9-]+\.?/", '', $host)) {
302
                throw new \UnexpectedValueException('Invalid host ' . host);
303
            }
304
        }
305
306
        return (string)host;
307
    }
308
309
    /**
310
     * Sets if the `Request::getHttpHost` method must be use strict validation of host name or not
311
     */
312
    public function setStrictHostCheck($flag = true)
313
    {
314
        $this->_strictHostCheck = $flag;
315
316
        return $this;
317
    }
318
319
    /**
320
     * Checks if the `Request::getHttpHost` method will be use strict validation of host name or not
321
     */
322
    public function isStrictHostCheck()
323
    {
324
        return $this->_strictHostCheck;
325
    }
326
327
    public function getPort()
328
    {
329
        /**
330
         * Get the server name from $_SERVER["HTTP_HOST"]
331
         */
332
        $host = $this->getServer('HTTP_HOST');
333
        if ($host) {
334
            if (memstr($host, ':')) {
0 ignored issues
show
Bug introduced by
The function memstr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

334
            if (/** @scrutinizer ignore-call */ memstr($host, ':')) {
Loading history...
335
                $pos = strrpos($host, ':');
336
337
                if (false !== $pos) {
338
                    return (int)substr($host, $pos + 1);
339
                }
340
341
                return 'https' === $this->getScheme() ? 443 : 80;
342
            }
343
        }
344
        return (int)$this->getServer('SERVER_PORT');
345
    }
346
347
    /**
348
     * Gets HTTP URI which request has been made
349
     */
350
    public function getURI()
351
    {
352
        $requestURI = $this->getServer('request_uri'); //$this->getServer('REQUEST_URI') == $this->getQuery('_url') ? $this->getServer('REQUEST_URI') : $this->getQuery('_url');
353
        if ($requestURI) {
354
            return $requestURI;
355
        }
356
357
        return '';
358
    }
359
360
    public function getClientAddress($trustForwardedHeader = true)
361
    {
362
        $address = null;
363
364
        /**
365
         * Proxies uses this IP
366
         */
367
        if ($trustForwardedHeader) {
368
            $address = $this->getServer('X_FORWARDED_FOR');
369
            if ($address === null) {
370
                $address = $this->getServer('X_REAL_IP');
371
            }
372
        }
373
374
        if ($address === null) {
375
            $address = $this->getServer('REMOTE_ADDR');
376
        }
377
378
        if (is_string($address)) {
379
            if (strpos($address, ',') !== false) {
380
                /**
381
                 * The client address has multiples parts, only return the first part
382
                 */
383
                return explode(',', $address)[0];
384
            }
385
            return $address;
386
        }
387
388
        return false;
389
    }
390
391
    public function getMethod()
392
    {
393
        $returnMethod = $this->getServer('REQUEST_METHOD');
394
        if (!isset($returnMethod)) {
395
            return 'GET';
396
        }
397
398
        $returnMethod = strtoupper($returnMethod);
399
        if ($returnMethod === 'POST') {
400
            $overridedMethod = $this->getHeader('X-HTTP-METHOD-OVERRIDE');
401
            if (!empty($overridedMethod)) {
402
                $returnMethod = strtoupper($overridedMethod);
403
            } elseif ($this->_httpMethodParameterOverride) {
404
                if ($spoofedMethod = $this->get('_method')) {
405
                    $returnMethod = strtoupper($spoofedMethod);
406
                }
407
            }
408
        }
409
410
        if (!$this->isValidHttpMethod($returnMethod)) {
411
            return 'GET';
412
        }
413
414
        return $returnMethod;
415
    }
416
417
    public function getUserAgent()
418
    {
419
        $userAgent = $this->getServer('HTTP_USER_AGENT');
420
        if ($userAgent) {
421
            return $userAgent;
422
        }
423
        return '';
424
    }
425
426
    public function isMethod($methods, $strict = false)
427
    {
428
        $httpMethod = $this->getMethod();
429
430
        if (is_string($methods)) {
431
            if ($strict && !$this->isValidHttpMethod($methods)) {
432
                throw new Exception('Invalid HTTP method: ' . methods);
0 ignored issues
show
Bug introduced by
The constant Gewaer\Http\methods was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
433
            }
434
            return $methods == $httpMethod;
435
        }
436
437
        if (is_array($methods)) {
438
            foreach ($methods as $method) {
439
                if ($this->isMethod($method, $strict)) {
440
                    return true;
441
                }
442
            }
443
444
            return false;
445
        }
446
447
        if ($strict) {
448
            throw new Exception('Invalid HTTP method: non-string');
449
        }
450
451
        return false;
452
    }
453
454
    public function isPost()
455
    {
456
        return $this->getMethod() === 'POST';
457
    }
458
459
    public function isGet()
460
    {
461
        return $this->getMethod() === 'GET';
462
    }
463
464
    public function isPut()
465
    {
466
        return $this->getMethod() === 'PUT';
467
    }
468
469
    public function isPatch()
470
    {
471
        return $this->getMethod() === 'PATCH';
472
    }
473
474
    public function isHead()
475
    {
476
        return $this->getMethod() === 'HEAD';
477
    }
478
479
    public function isDelete()
480
    {
481
        return $this->getMethod() === 'DELETE';
482
    }
483
484
    public function isOptions()
485
    {
486
        return $this->getMethod() === 'OPTIONS';
487
    }
488
489
    public function isPurge()
490
    {
491
        return $this->getMethod() === 'PURGE';
492
    }
493
494
    public function isTrace()
495
    {
496
        return $this->getMethod() === 'TRACE';
497
    }
498
499
    public function isConnect()
500
    {
501
        return $this->getMethod() === 'CONNECT';
502
    }
503
504
    public function hasFiles($onlySuccessful = false)
505
    {
506
        $numberFiles = 0;
507
508
        $files = $this->files;
509
510
        if (empty($files)) {
511
            return $numberFiles;
512
        }
513
514
        foreach ($files as $file) {
515
            $error = $file['error'];
516
            if ($error) {
517
                if (!is_array($error)) {
518
                    if (!$error || !$onlySuccessful) {
519
                        $numberFiles++;
520
                    }
521
                } else {
522
                    $numberFiles += $this->hasFileHelper($error, $onlySuccessful);
523
                }
524
            }
525
        }
526
527
        return $numberFiles;
528
    }
529
530
    /**
531
     * Recursively counts file in an array of files
532
     */
533
    protected function hasFileHelper($data, $onlySuccessful)
534
    {
535
        $numberFiles = 0;
536
537
        if (!is_array($data)) {
538
            return 1;
539
        }
540
541
        foreach ($data as $value) {
542
            if (!is_array($value)) {
543
                if (!$value || !$onlySuccessful) {
544
                    $numberFiles++;
545
                }
546
            } else {
547
                $numberFiles += $this->hasFileHelper($value, $onlySuccessful);
548
            }
549
        }
550
551
        return numberFiles;
0 ignored issues
show
Bug introduced by
The constant Gewaer\Http\numberFiles was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
552
    }
553
554
    public function getUploadedFiles($onlySuccessful = false)
555
    {
556
        $files = [];
557
558
        $superFiles = $this->files;
559
560
        if (count($superFiles) > 0) {
561
            foreach ($superFiles as $prefix => $input) {
562
                if (is_array(!$input['name'])) {
563
                    $smoothInput = $this->smoothFiles(
564
                        $input['name'],
565
                        $input['type'],
566
                        $input['tmp_name'],
567
                        $input['size'],
568
                        $input['error'],
569
                        $prefix
570
                    );
571
572
                    foreach ($smoothInput as $file) {
573
                        if ($onlySuccessful == false || $file['error'] == UPLOAD_ERR_OK) {
574
                            $dataFile = [
575
                                'name' => $file['name'],
576
                                'type' => $file['type'],
577
                                'tmp_name' => $file['tmp_name'],
578
                                'size' => $file['size'],
579
                                'error' => $file['error']
580
                            ];
581
582
                            $files[] = new File($dataFile, $file['key']);
583
                        }
584
                    }
585
                } else {
586
                    if ($onlySuccessful == false || $input['error'] == UPLOAD_ERR_OK) {
587
                        $files[] = new File($input, $prefix);
588
                    }
589
                }
590
            }
591
        }
592
593
        return $files;
594
    }
595
596
    public function getFile($key)
597
    {
598
        if (!isset($this->_files)) {
599
            $this->_files = [];
600
            $files = $this->getUploadedFiles();
601
            foreach ($files as $file) {
602
                $this->_files[$file->getKey()] = $file;
603
            }
604
        }
605
606
        if (!isset($this->_files[$key])) {
607
            return null;
608
        }
609
610
        return $this->_files[$key];
611
    }
612
613
    /**
614
     * Smooth out $_FILES to have plain array with all files uploaded
615
     */
616
    protected function smoothFiles($names, $types, $tmp_names, $sizes, $errors, $prefix)
617
    {
618
        $files = [];
619
620
        foreach ($names as $idx => $name) {
621
            $p = $prefix . '.' . $idx;
622
623
            if (is_string($name)) {
624
                $files[] = [
625
                    'name' => $name,
626
                    'type' => $types[$idx],
627
                    'tmp_name' => $tmp_names[$idx],
628
                    'size' => $sizes[$idx],
629
                    'error' => $errors[$idx],
630
                    'key' => $p
631
                ];
632
            }
633
634
            if (is_array($name)) {
635
                $parentFiles = $this->smoothFiles(
636
                    $names[$idx],
637
                    $types[$idx],
638
                    $tmp_names[$idx],
639
                    $sizes[$idx],
640
                    $errors[$idx],
641
                    $p
642
                );
643
644
                foreach ($parentFiles as $file) {
645
                    $files[] = $file;
646
                }
647
            }
648
        }
649
650
        return files;
0 ignored issues
show
Bug introduced by
The constant Gewaer\Http\files was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
651
    }
652
653
    public function getServers()
654
    {
655
        return $this->server;
656
    }
657
658
    public function getHeaders()
659
    {
660
        $headers = [];
661
        $contentHeaders = ['CONTENT_TYPE' => true, 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true];
662
663
        $servers = $this->getServers();
664
        foreach ($servers as $name => $value) {
665
            if (Text::startsWith($name, 'HTTP_')) {
666
                $name = ucwords(strtolower(str_replace('_', ' ', substr($name, 5))));
667
                $name = str_replace(' ', '-', $name);
668
                $headers[$name] = $value;
669
            }
670
671
            $name = strtoupper($name);
672
            if (isset($contentHeaders[$name])) {
673
                $name = ucwords(strtolower(str_replace('_', ' ', $name)));
674
                $name = str_replace(' ', '-', $name);
675
                $headers[$name] = $value;
676
            }
677
        }
678
679
        $authHeaders = $this->resolveAuthorizationHeaders();
680
681
        // Protect for future (child classes) changes
682
        if (is_array($authHeaders)) {
683
            $headers = array_merge($headers, $authHeaders);
684
        }
685
686
        return $headers;
687
    }
688
689
    public function getHTTPReferer()
690
    {
691
        $httpReferer = $this->getServer('HTTP_REFERER');
692
        if ($httpReferer) {
693
            return $httpReferer;
694
        }
695
696
        return '';
697
    }
698
699
    /**
700
     * Process a request header and return the one with best quality
701
     */
702
    protected function _getBestQuality($qualityParts, $name)
703
    {
704
        $i = 0;
705
        $quality = 0.0;
706
        $selectedName = '';
707
708
        foreach ($qualityParts as $accept) {
709
            if ($i == 0) {
710
                $quality = (double)$accept['quality'];
711
                $selectedName = $accept[$name];
712
            } else {
713
                $acceptQuality = (double)$accept['quality'];
714
                if ($acceptQuality > $quality) {
715
                    $quality = $acceptQuality;
716
                    $selectedName = $accept[$name];
717
                }
718
            }
719
            $i++;
720
        }
721
722
        return $selectedName;
723
    }
724
725
    public function getAcceptableContent()
726
    {
727
        return $this->_getQualityHeader('HTTP_ACCEPT', 'accept');
728
    }
729
730
    public function getBestAccept()
731
    {
732
        return $this->_getBestQuality($this->getAcceptableContent(), 'accept');
733
    }
734
735
    public function getClientCharsets()
736
    {
737
        return $this->_getQualityHeader('HTTP_ACCEPT_CHARSET', 'charset');
738
    }
739
740
    public function getBestCharset()
741
    {
742
        return $this->_getBestQuality($this->getClientCharsets(), 'charset');
743
    }
744
745
    public function getLanguages()
746
    {
747
        return $this->_getQualityHeader('HTTP_ACCEPT_LANGUAGE', 'language');
748
    }
749
750
    public function getBestLanguage()
751
    {
752
        return $this->_getBestQuality($this->getLanguages(), 'language');
753
    }
754
755
    public function getBasicAuth()
756
    {
757
        if ($this->hasServer('PHP_AUTH_USER') && $this->hasServer('PHP_AUTH_PW')) {
758
            return [
759
                'username' => $this->getServer('PHP_AUTH_USER'),
760
                'password' => $this->getServer('PHP_AUTH_PW')
761
            ];
762
        }
763
764
        return null;
765
    }
766
767
    public function getDigestAuth()
768
    {
769
        $auth = [];
770
        if ($this->hasServer('PHP_AUTH_DIGEST')) {
771
            $digest = $this->getServer('PHP_AUTH_DIGEST');
772
            $matches = [];
773
            if (!preg_match_all("#(\\w+)=(['\"]?)([^'\" ,]+)\\2#", $digest, $matches, 2)) {
774
                return $auth;
775
            }
776
            if (is_array($matches)) {
777
                foreach ($matches as $match) {
778
                    $auth[$match[1]] = $match[3];
779
                }
780
            }
781
        }
782
783
        return $auth;
784
    }
785
786
    /**
787
     * Checks if a method is a valid HTTP method
788
     */
789
    public function isValidHttpMethod($method)
790
    {
791
        switch (strtoupper($method)) {
792
            case 'GET':
793
            case 'POST':
794
            case 'PUT':
795
            case 'DELETE':
796
            case 'HEAD':
797
            case 'OPTIONS':
798
            case 'PATCH':
799
            case 'PURGE': // Squid and Varnish support
800
            case 'TRACE':
801
            case 'CONNECT':
802
                return true;
803
        }
804
805
        return false;
806
    }
807
808
    /**
809
     * Helper to get data from superglobals, applying filters if needed.
810
     * If no parameters are given the superglobal is returned.
811
     */
812
    protected function getHelper($source, $name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
813
    {
814
        if ($name === null) {
815
            return $source;
816
        }
817
818
        if (!isset($source[$name])) {
819
            return $defaultValue;
820
        }
821
822
        $value = $source[$name];
823
824
        if ($filters !== null) {
825
            $filter = $this->_filter;
826
            if (!$filter instanceof FilterInterface) {
827
                $dependencyInjector = $this->_dependencyInjector;
828
                if (!$dependencyInjector instanceof DiInterface) {
829
                    throw new Exception("A dependency injection object is required to access the 'filter' service");
830
                }
831
832
                $filter = $dependencyInjector->getShared('filter');
833
                $this->_filter = $filter;
834
            }
835
836
            $value = $filter->sanitize($value, $filters, $noRecursive);
1 ignored issue
show
Unused Code introduced by
The call to Phalcon\FilterInterface::sanitize() has too many arguments starting with $noRecursive. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

836
            /** @scrutinizer ignore-call */ 
837
            $value = $filter->sanitize($value, $filters, $noRecursive);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
837
        }
838
839
        if (empty($value) && $notAllowEmpty === true) {
840
            return $defaultValue;
841
        }
842
843
        return $value;
844
    }
845
846
    /**
847
     * Gets content type which request has been made
848
     */
849
    public function getContentType()
850
    {
851
        $contentType = $this->getHeader('CONTENT_TYPE');
852
        if ($contentType) {
853
            return $contentType;
854
        }
855
856
        return null;
857
    }
858
859
    /**
860
     * Process a request header and return an array of values with their qualities
861
     */
862
    protected function _getQualityHeader($serverIndex, $name)
863
    {
864
        $returnedParts = [];
865
        $parts = preg_split('/,\\s*/', $this->getServer($serverIndex), -1, PREG_SPLIT_NO_EMPTY);
866
        foreach ($parts as $part) {
867
            $headerParts = [];
868
            $hParts = preg_split("/\s*;\s*/", trim($part), -1, PREG_SPLIT_NO_EMPTY);
869
            foreach ($hParts as $headerPart) {
870
                if (strpos($headerPart, '=') !== false) {
871
                    $split = explode('=', $headerPart, 2);
872
                    if ($split[0] === 'q') {
873
                        $headerParts['quality'] = (double)$split[1];
874
                    } else {
875
                        $headerParts[$split[0]] = $split[1];
876
                    }
877
                } else {
878
                    $headerParts[$name] = $headerPart;
879
                    $headerParts['quality'] = 1.0;
880
                }
881
            }
882
883
            $returnedParts[] = $headerParts;
884
        }
885
886
        return $returnedParts;
887
    }
888
889
    /**
890
     * Resolve authorization headers.
891
     */
892
    protected function resolveAuthorizationHeaders()
893
    {
894
        $headers = [];
895
        $authHeader = null;
896
897
        $dependencyInjector = $this->getDI();
898
        if ($dependencyInjector instanceof DiInterface) {
899
            $hasEventsManager = (bool)$dependencyInjector->has('eventsManager');
900
            if ($hasEventsManager) {
901
                $eventsManager = $dependencyInjector->getShared('eventsManager');
902
            }
903
        }
904
905
        if ($hasEventsManager && $eventsManager instanceof Manager) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $hasEventsManager does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $eventsManager does not seem to be defined for all execution paths leading up to this point.
Loading history...
906
            $resolved = $eventsManager->fire(
907
                'request:beforeAuthorizationResolve',
908
                $this,
909
                ['server' => $this->getServers()]
910
            );
911
912
            if (is_array($resolved)) {
913
                $headers = array_merge($headers, $resolved);
914
            }
915
        }
916
917
        if ($this->hasServer('PHP_AUTH_USER') && $this->hasServer('PHP_AUTH_PW')) {
918
            $headers['Php-Auth-User'] = $this->getServer('PHP_AUTH_USER');
919
            $headers['Php-Auth-Pw'] = $this->getServer('PHP_AUTH_PW');
920
        } else {
921
            if ($this->hasServer('HTTP_AUTHORIZATION')) {
922
                $authHeader = $this->getServer('HTTP_AUTHORIZATION');
923
            } elseif ($this->hasServer('REDIRECT_HTTP_AUTHORIZATION')) {
924
                $authHeader = $this->getServer('REDIRECT_HTTP_AUTHORIZATION');
925
            }
926
927
            if ($authHeader) {
928
                if (stripos($authHeader, 'basic ') === 0) {
929
                    $exploded = explode(':', base64_decode(substr($authHeader, 6)), 2);
930
                    if (count($exploded) == 2) {
931
                        $headers['Php-Auth-User'] = $exploded[0];
932
                        $headers['Php-Auth-Pw'] = $exploded[1];
933
                    }
934
                } elseif (stripos($authHeader, 'digest ') === 0 && !$this->hasServer('PHP_AUTH_DIGEST')) {
935
                    $headers['Php-Auth-Digest'] = $authHeader;
936
                } elseif (stripos($authHeader, 'bearer ') === 0) {
937
                    $headers['Authorization'] = $authHeader;
938
                }
939
            }
940
        }
941
942
        if (!isset($headers['Authorization'])) {
943
            if (isset($headers['Php-Auth-User'])) {
944
                $headers['Authorization'] = 'Basic ' . base64_encode($headers['Php-Auth-User'] . ':' . $headers['Php-Auth-Pw']);
945
            } elseif (isset($headers['Php-Auth-Digest'])) {
946
                $headers['Authorization'] = $headers['Php-Auth-Digest'];
947
            }
948
        }
949
950
        if ($hasEventsManager && $eventsManager instanceof Manager) {
951
            $resolved = $eventsManager->fire(
952
                'request:afterAuthorizationResolve',
953
                $this,
954
                ['headers' => $headers, 'server' => $this->getServers()]
955
            );
956
957
            if (is_array($resolved)) {
958
                $headers = array_merge($headers, $resolved);
959
            }
960
        }
961
962
        return $headers;
963
    }
964
}
965