Failed Conditions
Pull Request — master (#30)
by Maximo
03:49
created

SwooleRequest   F

Complexity

Total Complexity 199

Size/Duplication

Total Lines 941
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 199
eloc 408
dl 0
loc 941
ccs 0
cts 699
cp 0
rs 2
c 0
b 0
f 0

66 Methods

Rating   Name   Duplication   Size   Complexity  
B getMethod() 0 24 7
A getServers() 0 3 1
A getHeaders() 0 29 5
A isStrictHostCheck() 0 3 1
A hasHeader() 0 9 3
B isValidHttpMethod() 0 17 11
A smoothFiles() 0 35 5
A getContentType() 0 8 2
B isMethod() 0 26 8
A get() 0 4 1
B getHelper() 0 32 8
A getClientCharsets() 0 3 1
A getServer() 0 7 2
A getPost() 0 4 1
A hasPut() 0 5 1
A isSecure() 0 3 1
F resolveAuthorizationHeaders() 0 71 22
A getQuery() 0 4 1
A isHead() 0 3 1
A getServerAddress() 0 8 2
A isSecureRequest() 0 3 1
A hasQuery() 0 3 1
A isTrace() 0 3 1
A getHeader() 0 13 3
A getServerName() 0 8 2
A hasFileHelper() 0 19 6
A _getBestQuality() 0 21 4
A isGet() 0 3 1
A isDelete() 0 3 1
A getBestLanguage() 0 3 1
A getUserAgent() 0 7 2
A isPurge() 0 3 1
A setDI() 0 3 1
A getHTTPReferer() 0 8 2
A hasServer() 0 5 1
A _getQualityHeader() 0 25 5
A getURI() 0 8 2
A setStrictHostCheck() 0 5 1
B getHttpHost() 0 40 7
A isPatch() 0 3 1
B init() 0 20 7
A getBasicAuth() 0 10 3
A getBestCharset() 0 3 1
A isPost() 0 3 1
A isConnect() 0 3 1
A getPut() 0 14 3
A getClientAddress() 0 29 6
A isSoapRequested() 0 3 1
A isOptions() 0 3 1
A hasPost() 0 3 1
A getJsonRawBody() 0 8 2
A getDigestAuth() 0 17 5
A getScheme() 0 8 3
A getDI() 0 3 1
A isAjax() 0 3 1
B getUploadedFiles() 0 40 9
A getPort() 0 18 5
A getBestAccept() 0 3 1
A getLanguages() 0 3 1
A getAcceptableContent() 0 3 1
A getRawBody() 0 3 1
B hasFiles() 0 24 7
A has() 0 4 1
A getFile() 0 15 4
A isSoap() 0 12 3
A isPut() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like SwooleRequest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SwooleRequest, and based on these observations, apply Extract Interface, too.

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 $_rawBody;
39
40
    protected $headers;
41
42
    protected $server;
43
44
    protected $get;
45
46
    protected $post;
47
48
    protected $cookies;
49
50
    protected $files;
51
52
    protected $swooleRequest;
53
54
    public function init(swoole_http_request $request)
55
    {
56
        $this->swooleRequest = $request;
57
        $this->headers = [];
58
        $this->server = [];
59
60
        $this->get = isset($request->get) ? $request->get : [];
61
        $this->post = isset($request->post) ? $request->post : [];
62
        $this->cookies = isset($request->cookie) ? $request->cookie : [];
63
        $this->files = isset($request->files) ? $request->files : [];
64
        $this->_rawBody = $request->rawContent();
65
66
        foreach ($request->header as $key => $val) {
67
            $key = strtoupper(str_replace(['-'], '_', $key));
68
            $this->headers[$key] = $val;
69
            $this->server[$key] = $val;
70
        }
71
        foreach ($request->server as $key => $val) {
72
            $key = strtoupper(str_replace(['-'], '_', $key));
73
            $this->server[$key] = $val;
74
        }
75
76
        /** @var Cookies $cookies */
77
        //$cookies = FactoryDefault::getDefault()->getCookies();
78
        //  $cookies->setSwooleCookies($this->cookies);
79
    }
80
81
    public function setDI(DiInterface $dependencyInjector)
82
    {
83
        $this->_dependencyInjector = $dependencyInjector;
84
    }
85
86
    public function getDI()
87
    {
88
        return $this->_dependencyInjector;
89
    }
90
91
    public function get($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
92
    {
93
        $source = array_merge($this->get, $this->post);
94
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
95
    }
96
97
    public function getPost($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
98
    {
99
        $source = $this->post;
100
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
101
    }
102
103
    public function getQuery($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
104
    {
105
        $source = $this->get;
106
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
107
    }
108
109
    public function getServer($name)
110
    {
111
        $name = strtoupper(str_replace(['-'], '_', $name));
112
        if (isset($this->server[$name])) {
113
            return $this->server[$name];
114
        }
115
        return null;
116
    }
117
118
    public function getPut($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
119
    {
120
        $put = $this->_putCache;
121
122
        if (empty($put)) {
123
            if (!isJson($this->getRawBody())) {
124
                parse_str($this->getRawBody(), $put);
125
            } else {
126
                $put = $this->getJsonRawBody(true);
127
            }
128
            $this->_putCache = $put;
129
        }
130
131
        return $this->getHelper($put, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
132
    }
133
134
    public function has($name)
135
    {
136
        $source = array_merge($this->get, $this->post);
137
        return isset($source[$name]);
138
    }
139
140
    public function hasPost($name)
141
    {
142
        return isset($this->post[$name]);
143
    }
144
145
    public function hasPut($name)
146
    {
147
        $put = $this->getPut();
148
149
        return isset($put[$name]);
150
    }
151
152
    public function hasQuery($name)
153
    {
154
        return isset($this->get[$name]);
155
    }
156
157
    public function hasServer($name)
158
    {
159
        $name = strtoupper(str_replace(['-'], '_', $name));
160
161
        return isset($this->server[$name]);
162
    }
163
164
    public function hasHeader($header)
165
    {
166
        if ($this->hasServer($header)) {
167
            return true;
168
        }
169
        if ($this->hasServer('HTTP_' . $header)) {
170
            return true;
171
        }
172
        return false;
173
    }
174
175
    public function getHeader($header)
176
    {
177
        $header = $this->getServer($header);
178
        if (isset($header)) {
179
            return $header;
180
        }
181
182
        $header = $this->getServer('HTTP_' . $header);
183
        if (isset($header)) {
184
            return $header;
185
        }
186
187
        return '';
188
    }
189
190
    public function getScheme()
191
    {
192
        $https = $this->getServer('HTTPS');
193
        if ($https && $https != 'off') {
194
            return 'https';
195
        }
196
197
        return 'http';
198
    }
199
200
    public function isAjax()
201
    {
202
        return $this->getServer('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest';
203
    }
204
205
    public function isSoap()
206
    {
207
        if ($this->hasServer('HTTP_SOAPACTION')) {
208
            return true;
209
        }
210
211
        $contentType = $this->getContentType();
212
        if (!empty($contentType)) {
213
            return (bool) strpos($contentType, 'application/soap+xml') !== false;
214
        }
215
216
        return false;
217
    }
218
219
    public function isSoapRequested()
220
    {
221
        return $this->isSoap();
222
    }
223
224
    public function isSecure()
225
    {
226
        return $this->getScheme() === 'https';
227
    }
228
229
    public function isSecureRequest()
230
    {
231
        return $this->isSecure();
232
    }
233
234
    public function getRawBody()
235
    {
236
        return $this->_rawBody;
237
    }
238
239
    public function getJsonRawBody($associative = false)
240
    {
241
        $rawBody = $this->getRawBody();
242
        if (!is_string($rawBody)) {
243
            return false;
244
        }
245
246
        return json_decode($rawBody, $associative);
247
    }
248
249
    public function getServerAddress()
250
    {
251
        $serverAddr = $this->getServer('SERVER_ADDR');
252
        if ($serverAddr) {
253
            return $serverAddr;
254
        }
255
256
        return gethostbyname('localhost');
257
    }
258
259
    public function getServerName()
260
    {
261
        $serverName = $this->getServer('SERVER_NAME');
262
        if ($serverName) {
263
            return $serverName;
264
        }
265
266
        return 'localhost';
267
    }
268
269
    public function getHttpHost()
270
    {
271
        $strict = $this->_strictHostCheck;
272
273
        /**
274
         * Get the server name from $_SERVER["HTTP_HOST"]
275
         */
276
        $host = $this->getServer('HTTP_HOST');
277
        if (!$host) {
278
            /**
279
             * Get the server name from $_SERVER["SERVER_NAME"]
280
             */
281
            $host = $this->getServer('SERVER_NAME');
282
            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...
283
                /**
284
                 * Get the server address from $_SERVER["SERVER_ADDR"]
285
                 */
286
                $host = $this->getServer('SERVER_ADDR');
287
            }
288
        }
289
290
        if ($host && $strict) {
291
            /**
292
             * Cleanup. Force lowercase as per RFC 952/2181
293
             */
294
            $host = strtolower(trim($host));
295
            if (strpos($host, ':') !== false) {
296
                $host = preg_replace('/:[[:digit:]]+$/', '', $host);
297
            }
298
299
            /**
300
             * Host may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner),
301
             * the digits '0' through '9', and the hyphen ('-') as per RFC 952/2181
302
             */
303
            if ('' !== preg_replace("/[a-z0-9-]+\.?/", '', $host)) {
304
                throw new \UnexpectedValueException('Invalid host ' . host);
305
            }
306
        }
307
308
        return (string)host;
309
    }
310
311
    /**
312
     * Sets if the `Request::getHttpHost` method must be use strict validation of host name or not
313
     */
314
    public function setStrictHostCheck($flag = true)
315
    {
316
        $this->_strictHostCheck = $flag;
317
318
        return $this;
319
    }
320
321
    /**
322
     * Checks if the `Request::getHttpHost` method will be use strict validation of host name or not
323
     */
324
    public function isStrictHostCheck()
325
    {
326
        return $this->_strictHostCheck;
327
    }
328
329
    public function getPort()
330
    {
331
        /**
332
         * Get the server name from $_SERVER["HTTP_HOST"]
333
         */
334
        $host = $this->getServer('HTTP_HOST');
335
        if ($host) {
336
            if (strpos($host, ':') !== false) {
337
                $pos = strrpos($host, ':');
338
339
                if (false !== $pos) {
340
                    return (int)substr($host, $pos + 1);
341
                }
342
343
                return 'https' === $this->getScheme() ? 443 : 80;
344
            }
345
        }
346
        return (int)$this->getServer('SERVER_PORT');
347
    }
348
349
    /**
350
     * Gets HTTP URI which request has been made
351
     */
352
    public function getURI()
353
    {
354
        $requestURI = $this->getServer('request_uri'); //$this->getServer('REQUEST_URI') == $this->getQuery('_url') ? $this->getServer('REQUEST_URI') : $this->getQuery('_url');
355
        if ($requestURI) {
356
            return $requestURI;
357
        }
358
359
        return '';
360
    }
361
362
    public function getClientAddress($trustForwardedHeader = true)
363
    {
364
        $address = null;
365
366
        /**
367
         * Proxies uses this IP
368
         */
369
        if ($trustForwardedHeader) {
370
            $address = $this->getServer('X_FORWARDED_FOR');
371
            if ($address === null) {
372
                $address = $this->getServer('X_REAL_IP');
373
            }
374
        }
375
376
        if ($address === null) {
377
            $address = $this->getServer('REMOTE_ADDR');
378
        }
379
380
        if (is_string($address)) {
381
            if (strpos($address, ',') !== false) {
382
                /**
383
                 * The client address has multiples parts, only return the first part
384
                 */
385
                return explode(',', $address)[0];
386
            }
387
            return $address;
388
        }
389
390
        return false;
391
    }
392
393
    public function getMethod()
394
    {
395
        $returnMethod = $this->getServer('REQUEST_METHOD');
396
        if (!isset($returnMethod)) {
397
            return 'GET';
398
        }
399
400
        $returnMethod = strtoupper($returnMethod);
401
        if ($returnMethod === 'POST') {
402
            $overridedMethod = $this->getHeader('X-HTTP-METHOD-OVERRIDE');
403
            if (!empty($overridedMethod)) {
404
                $returnMethod = strtoupper($overridedMethod);
405
            } elseif ($this->_httpMethodParameterOverride) {
406
                if ($spoofedMethod = $this->get('_method')) {
407
                    $returnMethod = strtoupper($spoofedMethod);
408
                }
409
            }
410
        }
411
412
        if (!$this->isValidHttpMethod($returnMethod)) {
413
            return 'GET';
414
        }
415
416
        return $returnMethod;
417
    }
418
419
    public function getUserAgent()
420
    {
421
        $userAgent = $this->getServer('HTTP_USER_AGENT');
422
        if ($userAgent) {
423
            return $userAgent;
424
        }
425
        return '';
426
    }
427
428
    public function isMethod($methods, $strict = false)
429
    {
430
        $httpMethod = $this->getMethod();
431
432
        if (is_string($methods)) {
433
            if ($strict && !$this->isValidHttpMethod($methods)) {
434
                throw new Exception('Invalid HTTP method: ' . $methods);
435
            }
436
            return $methods == $httpMethod;
437
        }
438
439
        if (is_array($methods)) {
440
            foreach ($methods as $method) {
441
                if ($this->isMethod($method, $strict)) {
442
                    return true;
443
                }
444
            }
445
446
            return false;
447
        }
448
449
        if ($strict) {
450
            throw new Exception('Invalid HTTP method: non-string');
451
        }
452
453
        return false;
454
    }
455
456
    public function isPost()
457
    {
458
        return $this->getMethod() === 'POST';
459
    }
460
461
    public function isGet()
462
    {
463
        return $this->getMethod() === 'GET';
464
    }
465
466
    public function isPut()
467
    {
468
        return $this->getMethod() === 'PUT';
469
    }
470
471
    public function isPatch()
472
    {
473
        return $this->getMethod() === 'PATCH';
474
    }
475
476
    public function isHead()
477
    {
478
        return $this->getMethod() === 'HEAD';
479
    }
480
481
    public function isDelete()
482
    {
483
        return $this->getMethod() === 'DELETE';
484
    }
485
486
    public function isOptions()
487
    {
488
        return $this->getMethod() === 'OPTIONS';
489
    }
490
491
    public function isPurge()
492
    {
493
        return $this->getMethod() === 'PURGE';
494
    }
495
496
    public function isTrace()
497
    {
498
        return $this->getMethod() === 'TRACE';
499
    }
500
501
    public function isConnect()
502
    {
503
        return $this->getMethod() === 'CONNECT';
504
    }
505
506
    public function hasFiles($onlySuccessful = false)
507
    {
508
        $numberFiles = 0;
509
510
        $files = $this->files;
511
512
        if (empty($files)) {
513
            return $numberFiles;
514
        }
515
516
        foreach ($files as $file) {
517
            $error = $file['error'];
518
            if ($error) {
519
                if (!is_array($error)) {
520
                    if (!$error || !$onlySuccessful) {
521
                        $numberFiles++;
522
                    }
523
                } else {
524
                    $numberFiles += $this->hasFileHelper($error, $onlySuccessful);
525
                }
526
            }
527
        }
528
529
        return $numberFiles;
530
    }
531
532
    /**
533
     * Recursively counts file in an array of files
534
     */
535
    protected function hasFileHelper($data, $onlySuccessful)
536
    {
537
        $numberFiles = 0;
538
539
        if (!is_array($data)) {
540
            return 1;
541
        }
542
543
        foreach ($data as $value) {
544
            if (!is_array($value)) {
545
                if (!$value || !$onlySuccessful) {
546
                    $numberFiles++;
547
                }
548
            } else {
549
                $numberFiles += $this->hasFileHelper($value, $onlySuccessful);
550
            }
551
        }
552
553
        return $numberFiles;
554
    }
555
556
    public function getUploadedFiles($onlySuccessful = false)
557
    {
558
        $files = [];
559
560
        $superFiles = $this->files;
561
562
        if (count($superFiles) > 0) {
563
            foreach ($superFiles as $prefix => $input) {
564
                if (is_array(!$input['name'])) {
565
                    $smoothInput = $this->smoothFiles(
566
                        $input['name'],
567
                        $input['type'],
568
                        $input['tmp_name'],
569
                        $input['size'],
570
                        $input['error'],
571
                        $prefix
572
                    );
573
574
                    foreach ($smoothInput as $file) {
575
                        if ($onlySuccessful == false || $file['error'] == UPLOAD_ERR_OK) {
576
                            $dataFile = [
577
                                'name' => $file['name'],
578
                                'type' => $file['type'],
579
                                'tmp_name' => $file['tmp_name'],
580
                                'size' => $file['size'],
581
                                'error' => $file['error']
582
                            ];
583
584
                            $files[] = new File($dataFile, $file['key']);
585
                        }
586
                    }
587
                } else {
588
                    if ($onlySuccessful == false || $input['error'] == UPLOAD_ERR_OK) {
589
                        $files[] = new File($input, $prefix);
590
                    }
591
                }
592
            }
593
        }
594
595
        return $files;
596
    }
597
598
    public function getFile($key)
599
    {
600
        if (!isset($this->_files)) {
601
            $this->_files = [];
602
            $files = $this->getUploadedFiles();
603
            foreach ($files as $file) {
604
                $this->_files[$file->getKey()] = $file;
605
            }
606
        }
607
608
        if (!isset($this->_files[$key])) {
609
            return null;
610
        }
611
612
        return $this->_files[$key];
613
    }
614
615
    /**
616
     * Smooth out $_FILES to have plain array with all files uploaded
617
     */
618
    protected function smoothFiles($names, $types, $tmp_names, $sizes, $errors, $prefix)
619
    {
620
        $files = [];
621
622
        foreach ($names as $idx => $name) {
623
            $p = $prefix . '.' . $idx;
624
625
            if (is_string($name)) {
626
                $files[] = [
627
                    'name' => $name,
628
                    'type' => $types[$idx],
629
                    'tmp_name' => $tmp_names[$idx],
630
                    'size' => $sizes[$idx],
631
                    'error' => $errors[$idx],
632
                    'key' => $p
633
                ];
634
            }
635
636
            if (is_array($name)) {
637
                $parentFiles = $this->smoothFiles(
638
                    $names[$idx],
639
                    $types[$idx],
640
                    $tmp_names[$idx],
641
                    $sizes[$idx],
642
                    $errors[$idx],
643
                    $p
644
                );
645
646
                foreach ($parentFiles as $file) {
647
                    $files[] = $file;
648
                }
649
            }
650
        }
651
652
        return $files;
653
    }
654
655
    public function getServers()
656
    {
657
        return $this->server;
658
    }
659
660
    public function getHeaders()
661
    {
662
        $headers = [];
663
        $contentHeaders = ['CONTENT_TYPE' => true, 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true];
664
665
        $servers = $this->getServers();
666
        foreach ($servers as $name => $value) {
667
            if (Text::startsWith($name, 'HTTP_')) {
668
                $name = ucwords(strtolower(str_replace('_', ' ', substr($name, 5))));
669
                $name = str_replace(' ', '-', $name);
670
                $headers[$name] = $value;
671
            }
672
673
            $name = strtoupper($name);
674
            if (isset($contentHeaders[$name])) {
675
                $name = ucwords(strtolower(str_replace('_', ' ', $name)));
676
                $name = str_replace(' ', '-', $name);
677
                $headers[$name] = $value;
678
            }
679
        }
680
681
        $authHeaders = $this->resolveAuthorizationHeaders();
682
683
        // Protect for future (child classes) changes
684
        if (is_array($authHeaders)) {
685
            $headers = array_merge($headers, $authHeaders);
686
        }
687
688
        return $headers;
689
    }
690
691
    public function getHTTPReferer()
692
    {
693
        $httpReferer = $this->getServer('HTTP_REFERER');
694
        if ($httpReferer) {
695
            return $httpReferer;
696
        }
697
698
        return '';
699
    }
700
701
    /**
702
     * Process a request header and return the one with best quality
703
     */
704
    protected function _getBestQuality($qualityParts, $name)
705
    {
706
        $i = 0;
707
        $quality = 0.0;
708
        $selectedName = '';
709
710
        foreach ($qualityParts as $accept) {
711
            if ($i == 0) {
712
                $quality = (double)$accept['quality'];
713
                $selectedName = $accept[$name];
714
            } else {
715
                $acceptQuality = (double)$accept['quality'];
716
                if ($acceptQuality > $quality) {
717
                    $quality = $acceptQuality;
718
                    $selectedName = $accept[$name];
719
                }
720
            }
721
            $i++;
722
        }
723
724
        return $selectedName;
725
    }
726
727
    public function getAcceptableContent()
728
    {
729
        return $this->_getQualityHeader('HTTP_ACCEPT', 'accept');
730
    }
731
732
    public function getBestAccept()
733
    {
734
        return $this->_getBestQuality($this->getAcceptableContent(), 'accept');
735
    }
736
737
    public function getClientCharsets()
738
    {
739
        return $this->_getQualityHeader('HTTP_ACCEPT_CHARSET', 'charset');
740
    }
741
742
    public function getBestCharset()
743
    {
744
        return $this->_getBestQuality($this->getClientCharsets(), 'charset');
745
    }
746
747
    public function getLanguages()
748
    {
749
        return $this->_getQualityHeader('HTTP_ACCEPT_LANGUAGE', 'language');
750
    }
751
752
    public function getBestLanguage()
753
    {
754
        return $this->_getBestQuality($this->getLanguages(), 'language');
755
    }
756
757
    public function getBasicAuth()
758
    {
759
        if ($this->hasServer('PHP_AUTH_USER') && $this->hasServer('PHP_AUTH_PW')) {
760
            return [
761
                'username' => $this->getServer('PHP_AUTH_USER'),
762
                'password' => $this->getServer('PHP_AUTH_PW')
763
            ];
764
        }
765
766
        return null;
767
    }
768
769
    public function getDigestAuth()
770
    {
771
        $auth = [];
772
        if ($this->hasServer('PHP_AUTH_DIGEST')) {
773
            $digest = $this->getServer('PHP_AUTH_DIGEST');
774
            $matches = [];
775
            if (!preg_match_all("#(\\w+)=(['\"]?)([^'\" ,]+)\\2#", $digest, $matches, 2)) {
776
                return $auth;
777
            }
778
            if (is_array($matches)) {
779
                foreach ($matches as $match) {
780
                    $auth[$match[1]] = $match[3];
781
                }
782
            }
783
        }
784
785
        return $auth;
786
    }
787
788
    /**
789
     * Checks if a method is a valid HTTP method
790
     */
791
    public function isValidHttpMethod($method)
792
    {
793
        switch (strtoupper($method)) {
794
            case 'GET':
795
            case 'POST':
796
            case 'PUT':
797
            case 'DELETE':
798
            case 'HEAD':
799
            case 'OPTIONS':
800
            case 'PATCH':
801
            case 'PURGE': // Squid and Varnish support
802
            case 'TRACE':
803
            case 'CONNECT':
804
                return true;
805
        }
806
807
        return false;
808
    }
809
810
    /**
811
     * Helper to get data from superglobals, applying filters if needed.
812
     * If no parameters are given the superglobal is returned.
813
     */
814
    protected function getHelper($source, $name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
815
    {
816
        if ($name === null) {
817
            return $source;
818
        }
819
820
        if (!isset($source[$name])) {
821
            return $defaultValue;
822
        }
823
824
        $value = $source[$name];
825
826
        if ($filters !== null) {
827
            $filter = $this->_filter;
828
            if (!$filter instanceof FilterInterface) {
829
                $dependencyInjector = $this->_dependencyInjector;
830
                if (!$dependencyInjector instanceof DiInterface) {
831
                    throw new Exception("A dependency injection object is required to access the 'filter' service");
832
                }
833
834
                $filter = $dependencyInjector->getShared('filter');
835
                $this->_filter = $filter;
836
            }
837
838
            $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

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