Failed Conditions
Push — 0.2 ( 9080b3...48d4dc )
by Maximo
10:15 queued 04:56
created

SwooleRequest::isSecureRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
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 Canvas\Http;
11
12
use Phalcon\DiInterface;
0 ignored issues
show
Bug introduced by
The type Phalcon\DiInterface 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...
13
use Phalcon\Events\Manager;
0 ignored issues
show
Bug introduced by
The type Phalcon\Events\Manager 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...
14
use Phalcon\FilterInterface;
0 ignored issues
show
Bug introduced by
The type Phalcon\FilterInterface 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...
15
use Phalcon\Http\RequestInterface;
1 ignored issue
show
Bug introduced by
The type Phalcon\Http\RequestInterface 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...
16
use Phalcon\Di\InjectionAwareInterface;
0 ignored issues
show
Bug introduced by
The type Phalcon\Di\InjectionAwareInterface 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...
17
use Phalcon\Http\Request\File;
0 ignored issues
show
Bug introduced by
The type Phalcon\Http\Request\File 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...
18
use Phalcon\Text;
0 ignored issues
show
Bug introduced by
The type Phalcon\Text 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...
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;
0 ignored issues
show
Bug introduced by
The type Phalcon\Di\FactoryDefault 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...
22
use function Canvas\Core\isJson;
23
use Canvas\Traits\RequestJwtTrait;
24
25
/**
26
 * Class SwooleRequest.
27
 *
28
 * To use Swoole Server with Phalcon we need to overwrite the Phalcon Request Object to use swoole Respnose object
29
 * Since swoole is our server he is the one who get all our _GET , _FILES, _POST , _PUT request and we need to parse that info
30
 * to make our phalcon project work
31
 *
32
 * @package Canvas\Http
33
 *
34
 * @property \Phalcon\Di $di
35
 */
36
class SwooleRequest implements RequestInterface, InjectionAwareInterface
37
{
38
    use RequestJwtTrait;
39
40
    protected $_dependencyInjector;
41
42
    protected $_httpMethodParameterOverride = false;
43
44
    protected $_filter;
45
46
    protected $_putCache;
47
48
    protected $_strictHostCheck = false;
49
50
    protected $_files;
51
52
    protected $_rawBody;
53
54
    protected $headers;
55
56
    protected $server;
57
58
    protected $get;
59
60
    protected $post;
61
62
    protected $cookies;
63
64
    protected $files;
65
66
    protected $swooleRequest;
67
68
    /**
69
     * Init the object with Swoole reqeust.
70
     *
71
     * @param swoole_http_request $request
72
     * @return void
73
     */
74
    public function init(swoole_http_request $request): void
75
    {
76
        $this->swooleRequest = $request;
77
        $this->headers = [];
78
        $this->server = [];
79
80
        $this->get = isset($request->get) ? $request->get : [];
81
        $this->post = isset($request->post) ? $request->post : [];
82
        $this->cookies = isset($request->cookie) ? $request->cookie : [];
83
        $this->files = isset($request->files) ? $request->files : [];
84
        $this->_rawBody = $request->rawContent();
85
86
        //iterate header
87
        $this->setGlobalHeaders($request->header);
88
        $this->setGlobalServers($request->server);
89
90
        //iterate server
91
92
        /** @var Cookies $cookies */
93
        //$cookies = FactoryDefault::getDefault()->getCookies();
94
        //  $cookies->setSwooleCookies($this->cookies);
95
    }
96
97
    /**
98
     * Set global headers.
99
     *
100
     * @param array $headers
101
     * @return void
102
     */
103
    private function setGlobalHeaders(array $headers): void
104
    {
105
        foreach ($headers as $key => $val) {
106
            $key = strtoupper(str_replace(['-'], '_', $key));
107
            $this->headers[$key] = $val;
108
            $this->server[$key] = $val;
109
        }
110
    }
111
112
    /**
113
     * Set global Servers.
114
     *
115
     * @param array $servers
116
     * @return void
117
     */
118
    private function setGlobalServers(array $servers): void
119
    {
120
        foreach ($servers as $key => $val) {
121
            $key = strtoupper(str_replace(['-'], '_', $key));
122
            $this->server[$key] = $val;
123
        }
124
    }
125
126
    /**
127
     * Set Di.
128
     *
129
     * @param DiInterface $dependencyInjector
130
     * @return void
131
     */
132
    public function setDI(DiInterface $dependencyInjector)
133
    {
134
        $this->_dependencyInjector = $dependencyInjector;
135
    }
136
137
    /**
138
     * Get Di.
139
     *
140
     * @return void
141
     */
142
    public function getDI()
143
    {
144
        return $this->_dependencyInjector;
145
    }
146
147
    /**
148
     * Access to REQUEST.
149
     *
150
     * @param string $name
151
     * @param string $filters
152
     * @param string $defaultValue
153
     * @param boolean $notAllowEmpty
154
     * @param boolean $noRecursive
155
     * @return array|string
156
     */
157
    public function get($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
158
    {
159
        $source = array_merge($this->get, $this->post);
160
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
161
    }
162
163
    /**
164
     * Acces to Post.
165
     *
166
     * @param string $name
167
     * @param string $filters
168
     * @param string $defaultValue
169
     * @param boolean $notAllowEmpty
170
     * @param boolean $noRecursive
171
     * @return array|string
172
     */
173
    public function getPost($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
174
    {
175
        $source = $this->post;
176
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
177
    }
178
179
    /**
180
     * Access to GET.
181
     *
182
     * @param string $name
183
     * @param string $filters
184
     * @param string $defaultValue
185
     * @param boolean $notAllowEmpty
186
     * @param boolean $noRecursive
187
     * @return array|string
188
     */
189
    public function getQuery($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
190
    {
191
        $source = $this->get;
192
        return $this->getHelper($source, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
193
    }
194
195
    /**
196
     * Get _SERVER.
197
     *
198
     * @param string $name
199
     * @return string|null
200
     */
201
    public function getServer($name)
202
    {
203
        $name = strtoupper(str_replace(['-'], '_', $name));
204
        if (isset($this->server[$name])) {
205
            return $this->server[$name];
206
        }
207
208
        return null;
209
    }
210
211
    /**
212
     * Get _PUT.
213
     *
214
     * @param string $name
215
     * @param string $filters
216
     * @param string $defaultValue
217
     * @param boolean $notAllowEmpty
218
     * @param boolean $noRecursive
219
     * @return array|string
220
     */
221
    public function getPut($name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
222
    {
223
        $put = $this->_putCache;
224
225
        if (empty($put)) {
226
            if (!isJson($this->getRawBody())) {
227
                parse_str($this->getRawBody(), $put);
228
            } else {
229
                $put = $this->getJsonRawBody(true);
230
            }
231
            $this->_putCache = $put;
232
        }
233
234
        return $this->getHelper($put, $name, $filters, $defaultValue, $notAllowEmpty, $noRecursive);
235
    }
236
237
    /**
238
     * Has.
239
     *
240
     * @param string $name
241
     * @return boolean
242
     */
243
    public function has($name)
244
    {
245
        $source = array_merge($this->get, $this->post);
246
        return isset($source[$name]);
247
    }
248
249
    /**
250
     * Has Post.
251
     *
252
     * @param string $name
253
     * @return boolean
254
     */
255
    public function hasPost($name)
256
    {
257
        return isset($this->post[$name]);
258
    }
259
260
    /**
261
     * Has Put.
262
     *
263
     * @param string $name
264
     * @return boolean
265
     */
266
    public function hasPut($name)
267
    {
268
        $put = $this->getPut();
269
270
        return isset($put[$name]);
271
    }
272
273
    /**
274
     * Has GET.
275
     *
276
     * @param string $name
277
     * @return boolean
278
     */
279
    public function hasQuery($name)
280
    {
281
        return isset($this->get[$name]);
282
    }
283
284
    /**
285
     * Has SERVER.
286
     *
287
     * @param string $name
288
     * @return boolean
289
     */
290
    public function hasServer($name)
291
    {
292
        $name = strtoupper(str_replace(['-'], '_', $name));
293
294
        return isset($this->server[$name]);
295
    }
296
297
    /**
298
     * Has HEADER.
299
     *
300
     * @param string $name
301
     * @return boolean
302
     */
303
    public function hasHeader($header)
304
    {
305
        if ($this->hasServer($header)) {
306
            return true;
307
        }
308
        if ($this->hasServer('HTTP_' . $header)) {
309
            return true;
310
        }
311
        return false;
312
    }
313
314
    /**
315
     * Get Header.
316
     *
317
     * @param string $name
318
     * @return string|void
319
     */
320
    public function getHeader($header)
321
    {
322
        $header = $this->getServer($header);
323
        if (isset($header)) {
324
            return $header;
325
        }
326
327
        $header = $this->getServer('HTTP_' . $header);
328
        if (isset($header)) {
329
            return $header;
330
        }
331
332
        return '';
333
    }
334
335
    /**
336
     * Get Schema.
337
     *
338
     * @return string
339
     */
340
    public function getScheme()
341
    {
342
        $https = $this->getServer('HTTPS');
343
        if ($https && $https != 'off') {
344
            return 'https';
345
        }
346
347
        return 'http';
348
    }
349
350
    /**
351
     * Is ajax.
352
     *
353
     * @return boolean
354
     */
355
    public function isAjax()
356
    {
357
        return $this->getServer('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest';
358
    }
359
360
    /**
361
     * is Soap.
362
     *
363
     * @return boolean
364
     */
365
    public function isSoap()
366
    {
367
        if ($this->hasServer('HTTP_SOAPACTION')) {
368
            return true;
369
        }
370
371
        $contentType = $this->getContentType();
372
        if (!empty($contentType)) {
373
            return (bool) strpos($contentType, 'application/soap+xml') !== false;
374
        }
375
376
        return false;
377
    }
378
379
    /**
380
     * is Soap.
381
     *
382
     * @return boolean
383
     */
384
    public function isSoapRequested()
385
    {
386
        return $this->isSoap();
387
    }
388
389
    /**
390
     * is HTTPS.
391
     *
392
     * @return boolean
393
     */
394
    public function isSecure()
395
    {
396
        return $this->getScheme() === 'https';
397
    }
398
399
    /**
400
     * is HTTPS.
401
     *
402
     * @return boolean
403
     */
404
    public function isSecureRequest()
405
    {
406
        return $this->isSecure();
407
    }
408
409
    /**
410
     * get RAW.
411
     *
412
     * @return string
413
     */
414
    public function getRawBody()
415
    {
416
        return $this->_rawBody;
417
    }
418
419
    /**
420
     * Get json.
421
     *
422
     * @param boolean $associative
423
     * @return void|string
424
     */
425
    public function getJsonRawBody($associative = false)
426
    {
427
        $rawBody = $this->getRawBody();
428
        if (!is_string($rawBody)) {
0 ignored issues
show
introduced by
The condition is_string($rawBody) is always true.
Loading history...
429
            return false;
430
        }
431
432
        return json_decode($rawBody, $associative);
433
    }
434
435
    /**
436
     * Get servers addres.
437
     *
438
     * @return string
439
     */
440
    public function getServerAddress()
441
    {
442
        $serverAddr = $this->getServer('SERVER_ADDR');
443
        if ($serverAddr) {
444
            return $serverAddr;
445
        }
446
447
        return gethostbyname('localhost');
448
    }
449
450
    /**
451
     * Get server name.
452
     *
453
     * @return string
454
     */
455
    public function getServerName()
456
    {
457
        $serverName = $this->getServer('SERVER_NAME');
458
        if ($serverName) {
459
            return $serverName;
460
        }
461
462
        return 'localhost';
463
    }
464
465
    /**
466
     * Get https hosts.
467
     *
468
     * @return string
469
     */
470
    public function getHttpHost()
471
    {
472
        $strict = $this->_strictHostCheck;
473
474
        /**
475
         * Get the server name from $_SERVER["HTTP_HOST"].
476
         */
477
        $host = $this->getServer('HTTP_HOST');
478
        if (!$host) {
479
            /**
480
             * Get the server name from $_SERVER["SERVER_NAME"].
481
             */
482
            $host = $this->getServer('SERVER_NAME');
483
            if (!$host) {
484
                /**
485
                 * Get the server address from $_SERVER["SERVER_ADDR"].
486
                 */
487
                $host = $this->getServer('SERVER_ADDR');
488
            }
489
        }
490
491
        if ($host && $strict) {
492
            /**
493
             * Cleanup. Force lowercase as per RFC 952/2181.
494
             */
495
            $host = strtolower(trim($host));
496
            if (strpos($host, ':') !== false) {
497
                $host = preg_replace('/:[[:digit:]]+$/', '', $host);
498
            }
499
500
            /**
501
             * Host may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner),
502
             * the digits '0' through '9', and the hyphen ('-') as per RFC 952/2181.
503
             */
504
            if ('' !== preg_replace("/[a-z0-9-]+\.?/", '', $host)) {
505
                throw new \UnexpectedValueException('Invalid host ' . $host);
506
            }
507
        }
508
509
        return (string) $host;
510
    }
511
512
    /**
513
     * Sets if the `Request::getHttpHost` method must be use strict validation of host name or not.
514
     */
515
    public function setStrictHostCheck($flag = true)
516
    {
517
        $this->_strictHostCheck = $flag;
518
519
        return $this;
520
    }
521
522
    /**
523
     * Checks if the `Request::getHttpHost` method will be use strict validation of host name or not.
524
     */
525
    public function isStrictHostCheck()
526
    {
527
        return $this->_strictHostCheck;
528
    }
529
530
    /**
531
     * Get port.
532
     *
533
     * @return int
534
     */
535
    public function getPort()
536
    {
537
        /**
538
         * Get the server name from $_SERVER["HTTP_HOST"].
539
         */
540
        $host = $this->getServer('HTTP_HOST');
541
        if ($host) {
542
            if (strpos($host, ':') !== false) {
543
                $pos = strrpos($host, ':');
544
545
                if (false !== $pos) {
546
                    return (int)substr($host, $pos + 1);
547
                }
548
549
                return 'https' === $this->getScheme() ? 443 : 80;
550
            }
551
        }
552
        return (int) $this->getServer('SERVER_PORT');
553
    }
554
555
    /**
556
     * Gets HTTP URI which request has been made.
557
     */
558
    public function getURI()
559
    {
560
        $requestURI = $this->getServer('request_uri'); //$this->getServer('REQUEST_URI') == $this->getQuery('_url') ? $this->getServer('REQUEST_URI') : $this->getQuery('_url');
561
        if ($requestURI) {
562
            return $requestURI;
563
        }
564
565
        return '';
566
    }
567
568
    /**
569
     * Get client ip.
570
     *
571
     * @param boolean $trustForwardedHeader
572
     * @return string|boolean
573
     */
574
    public function getClientAddress($trustForwardedHeader = true)
575
    {
576
        $address = null;
577
578
        /**
579
         * Proxies uses this IP.
580
         */
581
        if ($trustForwardedHeader) {
582
            $address = $this->getServer('X_FORWARDED_FOR');
583
            if ($address === null) {
584
                $address = $this->getServer('X_REAL_IP');
585
            }
586
        }
587
588
        if ($address === null) {
589
            $address = $this->getServer('REMOTE_ADDR');
590
        }
591
592
        if (is_string($address)) {
593
            if (strpos($address, ',') !== false) {
594
                /**
595
                 * The client address has multiples parts, only return the first part.
596
                 */
597
                return explode(',', $address)[0];
598
            }
599
            return $address;
600
        }
601
602
        return false;
603
    }
604
605
    /**
606
     * Get method.
607
     *
608
     * @return string
609
     */
610
    public function getMethod()
611
    {
612
        $returnMethod = $this->getServer('REQUEST_METHOD');
613
        if (!isset($returnMethod)) {
614
            return 'GET';
615
        }
616
617
        $returnMethod = strtoupper($returnMethod);
618
        if ($returnMethod === 'POST') {
619
            $overridedMethod = $this->getHeader('X-HTTP-METHOD-OVERRIDE');
620
            if (!empty($overridedMethod)) {
621
                $returnMethod = strtoupper($overridedMethod);
622
            } elseif ($this->_httpMethodParameterOverride) {
623
                if ($spoofedMethod = $this->get('_method')) {
624
                    $returnMethod = strtoupper($spoofedMethod);
625
                }
626
            }
627
        }
628
629
        if (!$this->isValidHttpMethod($returnMethod)) {
630
            return 'GET';
631
        }
632
633
        return $returnMethod;
634
    }
635
636
    /**
637
     * Get user agent.
638
     *
639
     * @return string|void
640
     */
641
    public function getUserAgent()
642
    {
643
        $userAgent = $this->getServer('HTTP_USER_AGENT');
644
        if ($userAgent) {
645
            return $userAgent;
646
        }
647
        return '';
648
    }
649
650
    /**
651
     * Is method.
652
     *
653
     * @param string $methods
654
     * @param boolean $strict
655
     * @return boolean
656
     */
657
    public function isMethod($methods, $strict = false)
658
    {
659
        $httpMethod = $this->getMethod();
660
661
        if (is_string($methods)) {
0 ignored issues
show
introduced by
The condition is_string($methods) is always true.
Loading history...
662
            if ($strict && !$this->isValidHttpMethod($methods)) {
663
                throw new Exception('Invalid HTTP method: ' . $methods);
664
            }
665
            return $methods == $httpMethod;
666
        }
667
668
        if (is_array($methods)) {
669
            foreach ($methods as $method) {
670
                if ($this->isMethod($method, $strict)) {
671
                    return true;
672
                }
673
            }
674
675
            return false;
676
        }
677
678
        if ($strict) {
679
            throw new Exception('Invalid HTTP method: non-string');
680
        }
681
682
        return false;
683
    }
684
685
    /**
686
     * Is post.
687
     *
688
     * @return boolean
689
     */
690
    public function isPost()
691
    {
692
        return $this->getMethod() === 'POST';
693
    }
694
695
    /**
696
     * Is GET.
697
     *
698
     * @return boolean
699
     */
700
    public function isGet()
701
    {
702
        return $this->getMethod() === 'GET';
703
    }
704
705
    /**
706
     * Is Put.
707
     *
708
     * @return boolean
709
     */
710
    public function isPut()
711
    {
712
        return $this->getMethod() === 'PUT';
713
    }
714
715
    /**
716
     * Is patch.
717
     *
718
     * @return boolean
719
     */
720
    public function isPatch()
721
    {
722
        return $this->getMethod() === 'PATCH';
723
    }
724
725
    /**
726
     * Is head.
727
     *
728
     * @return boolean
729
     */
730
    public function isHead()
731
    {
732
        return $this->getMethod() === 'HEAD';
733
    }
734
735
    /**
736
     * Is dealete.
737
     *
738
     * @return boolean
739
     */
740
    public function isDelete()
741
    {
742
        return $this->getMethod() === 'DELETE';
743
    }
744
745
    /**
746
     * Is Options.
747
     *
748
     * @return boolean
749
     */
750
    public function isOptions()
751
    {
752
        return $this->getMethod() === 'OPTIONS';
753
    }
754
755
    /**
756
     * Is Purge.
757
     *
758
     * @return boolean
759
     */
760
    public function isPurge()
761
    {
762
        return $this->getMethod() === 'PURGE';
763
    }
764
765
    /**
766
     * Is trace.
767
     *
768
     * @return boolean
769
     */
770
    public function isTrace()
771
    {
772
        return $this->getMethod() === 'TRACE';
773
    }
774
775
    /**
776
     * Is connect.
777
     *
778
     * @return boolean
779
     */
780
    public function isConnect()
781
    {
782
        return $this->getMethod() === 'CONNECT';
783
    }
784
785
    /**
786
     * Has uploaded files?
787
     *
788
     * @param boolean $onlySuccessful
789
     * @return string
790
     */
791
    public function hasFiles($onlySuccessful = false)
792
    {
793
        $numberFiles = 0;
794
795
        $files = $this->files;
796
797
        if (empty($files)) {
798
            return $numberFiles;
799
        }
800
801
        foreach ($files as $file) {
802
            $error = $file['error'];
803
            if ($error) {
804
                if (!is_array($error)) {
805
                    if (!$error || !$onlySuccessful) {
806
                        $numberFiles++;
807
                    }
808
                } else {
809
                    $numberFiles += $this->hasFileHelper($error, $onlySuccessful);
810
                }
811
            }
812
        }
813
814
        return $numberFiles;
815
    }
816
817
    /**
818
     * Recursively counts file in an array of files.
819
     */
820
    protected function hasFileHelper($data, $onlySuccessful)
821
    {
822
        $numberFiles = 0;
823
824
        if (!is_array($data)) {
825
            return 1;
826
        }
827
828
        foreach ($data as $value) {
829
            if (!is_array($value)) {
830
                if (!$value || !$onlySuccessful) {
831
                    $numberFiles++;
832
                }
833
            } else {
834
                $numberFiles += $this->hasFileHelper($value, $onlySuccessful);
835
            }
836
        }
837
838
        return $numberFiles;
839
    }
840
841
    /**
842
     * Get the uploaded files.
843
     *
844
     * @param boolean $onlySuccessful
845
     * @return array
846
     */
847
    public function getUploadedFiles($onlySuccessful = false)
848
    {
849
        $files = [];
850
851
        $superFiles = $this->files;
852
853
        if (count($superFiles) > 0) {
854
            foreach ($superFiles as $prefix => $input) {
855
                if (is_array(!$input['name'])) {
856
                    $smoothInput = $this->smoothFiles(
857
                        $input['name'],
858
                        $input['type'],
859
                        $input['tmp_name'],
860
                        $input['size'],
861
                        $input['error'],
862
                        $prefix
863
                    );
864
865
                    foreach ($smoothInput as $file) {
866
                        if ($onlySuccessful === false || $file['error'] == UPLOAD_ERR_OK) {
867
                            $dataFile = [
868
                                'name' => $file['name'],
869
                                'type' => $file['type'],
870
                                'tmp_name' => $file['tmp_name'],
871
                                'size' => $file['size'],
872
                                'error' => $file['error']
873
                            ];
874
875
                            $files[] = new File($dataFile, $file['key']);
876
                        }
877
                    }
878
                } else {
879
                    if ($onlySuccessful === false || $input['error'] == UPLOAD_ERR_OK) {
880
                        $files[] = new File($input, $prefix);
881
                    }
882
                }
883
            }
884
        }
885
886
        return $files;
887
    }
888
889
    /**
890
     * Get the files.
891
     *
892
     * @param string $key
893
     * @return string|void
894
     */
895
    public function getFile($key)
896
    {
897
        if (!isset($this->_files)) {
898
            $this->_files = [];
899
            $files = $this->getUploadedFiles();
900
            foreach ($files as $file) {
901
                $this->_files[$file->getKey()] = $file;
902
            }
903
        }
904
905
        if (!isset($this->_files[$key])) {
906
            return null;
907
        }
908
909
        return $this->_files[$key];
910
    }
911
912
    /**
913
     * Smooth out $_FILES to have plain array with all files uploaded.
914
     */
915
    protected function smoothFiles($names, $types, $tmp_names, $sizes, $errors, $prefix)
916
    {
917
        $files = [];
918
919
        foreach ($names as $idx => $name) {
920
            $p = $prefix . '.' . $idx;
921
922
            if (is_string($name)) {
923
                $files[] = [
924
                    'name' => $name,
925
                    'type' => $types[$idx],
926
                    'tmp_name' => $tmp_names[$idx],
927
                    'size' => $sizes[$idx],
928
                    'error' => $errors[$idx],
929
                    'key' => $p
930
                ];
931
            }
932
933
            if (is_array($name)) {
934
                $parentFiles = $this->smoothFiles(
935
                    $names[$idx],
936
                    $types[$idx],
937
                    $tmp_names[$idx],
938
                    $sizes[$idx],
939
                    $errors[$idx],
940
                    $p
941
                );
942
943
                foreach ($parentFiles as $file) {
944
                    $files[] = $file;
945
                }
946
            }
947
        }
948
949
        return $files;
950
    }
951
952
    /**
953
     * Get the servers.
954
     *
955
     * @return array
956
     */
957
    public function getServers()
958
    {
959
        return $this->server;
960
    }
961
962
    /**
963
     * Get the headers.
964
     *
965
     * @return array
966
     */
967
    public function getHeaders()
968
    {
969
        $headers = [];
970
        $contentHeaders = ['CONTENT_TYPE' => true, 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true];
971
972
        $servers = $this->getServers();
973
        foreach ($servers as $name => $value) {
974
            if (Text::startsWith($name, 'HTTP_')) {
975
                $name = ucwords(strtolower(str_replace('_', ' ', substr($name, 5))));
976
                $name = str_replace(' ', '-', $name);
977
                $headers[$name] = $value;
978
            }
979
980
            $name = strtoupper($name);
981
            if (isset($contentHeaders[$name])) {
982
                $name = ucwords(strtolower(str_replace('_', ' ', $name)));
983
                $name = str_replace(' ', '-', $name);
984
                $headers[$name] = $value;
985
            }
986
        }
987
988
        $authHeaders = $this->resolveAuthorizationHeaders();
989
990
        // Protect for future (child classes) changes
991
        if (is_array($authHeaders)) {
992
            $headers = array_merge($headers, $authHeaders);
993
        }
994
995
        return $headers;
996
    }
997
998
    /**
999
     * Get the httpd reference.
1000
     *
1001
     * @return string|void
1002
     */
1003
    public function getHTTPReferer()
1004
    {
1005
        $httpReferer = $this->getServer('HTTP_REFERER');
1006
        if ($httpReferer) {
1007
            return $httpReferer;
1008
        }
1009
1010
        return '';
1011
    }
1012
1013
    /**
1014
     * Process a request header and return the one with best quality.
1015
     *
1016
     * @return string
1017
     */
1018
    protected function _getBestQuality($qualityParts, $name)
1019
    {
1020
        $i = 0;
1021
        $quality = 0.0;
1022
        $selectedName = '';
1023
1024
        foreach ($qualityParts as $accept) {
1025
            if ($i == 0) {
1026
                $quality = (double)$accept['quality'];
1027
                $selectedName = $accept[$name];
1028
            } else {
1029
                $acceptQuality = (double)$accept['quality'];
1030
                if ($acceptQuality > $quality) {
1031
                    $quality = $acceptQuality;
1032
                    $selectedName = $accept[$name];
1033
                }
1034
            }
1035
            $i++;
1036
        }
1037
1038
        return $selectedName;
1039
    }
1040
1041
    /**
1042
     * Get the content.
1043
     *
1044
     * @return array
1045
     */
1046
    public function getAcceptableContent()
1047
    {
1048
        return $this->_getQualityHeader('HTTP_ACCEPT', 'accept');
1049
    }
1050
1051
    /**
1052
     * Get the content.
1053
     *
1054
     * @return string
1055
     */
1056
    public function getBestAccept()
1057
    {
1058
        return $this->_getBestQuality($this->getAcceptableContent(), 'accept');
1059
    }
1060
1061
    /**
1062
     * Get the content.
1063
     *
1064
     * @return array
1065
     */
1066
    public function getClientCharsets()
1067
    {
1068
        return $this->_getQualityHeader('HTTP_ACCEPT_CHARSET', 'charset');
1069
    }
1070
1071
    /**
1072
     * Get the content.
1073
     *
1074
     * @return string
1075
     */
1076
    public function getBestCharset()
1077
    {
1078
        return $this->_getBestQuality($this->getClientCharsets(), 'charset');
1079
    }
1080
1081
    /**
1082
     * Get the content.
1083
     *
1084
     * @return array
1085
     */
1086
    public function getLanguages()
1087
    {
1088
        return $this->_getQualityHeader('HTTP_ACCEPT_LANGUAGE', 'language');
1089
    }
1090
1091
    /**
1092
     * Get the content.
1093
     *
1094
     * @return string
1095
     */
1096
    public function getBestLanguage()
1097
    {
1098
        return $this->_getBestQuality($this->getLanguages(), 'language');
1099
    }
1100
1101
    /**
1102
     * Get the basic httpd auth.
1103
     *
1104
     * @return array|void
1105
     */
1106
    public function getBasicAuth()
1107
    {
1108
        if ($this->hasServer('PHP_AUTH_USER') && $this->hasServer('PHP_AUTH_PW')) {
1109
            return [
1110
                'username' => $this->getServer('PHP_AUTH_USER'),
1111
                'password' => $this->getServer('PHP_AUTH_PW')
1112
            ];
1113
        }
1114
1115
        return null;
1116
    }
1117
1118
    /**
1119
     * Get the server digest.
1120
     *
1121
     * @return array
1122
     */
1123
    public function getDigestAuth()
1124
    {
1125
        $auth = [];
1126
        if ($this->hasServer('PHP_AUTH_DIGEST')) {
1127
            $digest = $this->getServer('PHP_AUTH_DIGEST');
1128
            $matches = [];
1129
            if (!preg_match_all("#(\\w+)=(['\"]?)([^'\" ,]+)\\2#", $digest, $matches, 2)) {
1130
                return $auth;
1131
            }
1132
            if (is_array($matches)) {
1133
                foreach ($matches as $match) {
1134
                    $auth[$match[1]] = $match[3];
1135
                }
1136
            }
1137
        }
1138
1139
        return $auth;
1140
    }
1141
1142
    /**
1143
     * Checks if a method is a valid HTTP method.
1144
     */
1145
    public function isValidHttpMethod($method)
1146
    {
1147
        switch (strtoupper($method)) {
1148
            case 'GET':
1149
            case 'POST':
1150
            case 'PUT':
1151
            case 'DELETE':
1152
            case 'HEAD':
1153
            case 'OPTIONS':
1154
            case 'PATCH':
1155
            case 'PURGE': // Squid and Varnish support
1156
            case 'TRACE':
1157
            case 'CONNECT':
1158
                return true;
1159
        }
1160
1161
        return false;
1162
    }
1163
1164
    /**
1165
     * Helper to get data from superglobals, applying filters if needed.
1166
     * If no parameters are given the superglobal is returned.
1167
     */
1168
    protected function getHelper($source, $name = null, $filters = null, $defaultValue = null, $notAllowEmpty = false, $noRecursive = false)
1169
    {
1170
        if ($name === null) {
1171
            return $source;
1172
        }
1173
1174
        if (!isset($source[$name])) {
1175
            return $defaultValue;
1176
        }
1177
1178
        $value = $source[$name];
1179
1180
        if ($filters !== null) {
1181
            $filter = $this->_filter;
1182
            if (!$filter instanceof FilterInterface) {
1183
                $dependencyInjector = $this->_dependencyInjector;
1184
                if (!$dependencyInjector instanceof DiInterface) {
1185
                    throw new Exception("A dependency injection object is required to access the 'filter' service");
1186
                }
1187
1188
                $filter = $dependencyInjector->getShared('filter');
1189
                $this->_filter = $filter;
1190
            }
1191
1192
            $value = $filter->sanitize($value, $filters, $noRecursive);
1193
        }
1194
1195
        if (empty($value) && $notAllowEmpty === true) {
1196
            return $defaultValue;
1197
        }
1198
1199
        return $value;
1200
    }
1201
1202
    /**
1203
     * Gets content type which request has been made.
1204
     */
1205
    public function getContentType()
1206
    {
1207
        $contentType = $this->getHeader('CONTENT_TYPE');
1208
        if ($contentType) {
1209
            return $contentType;
1210
        }
1211
1212
        return null;
1213
    }
1214
1215
    /**
1216
     * Process a request header and return an array of values with their qualities.
1217
     *
1218
     * @return array
1219
     */
1220
    protected function _getQualityHeader($serverIndex, $name)
1221
    {
1222
        $returnedParts = [];
1223
        $parts = preg_split('/,\\s*/', $this->getServer($serverIndex), -1, PREG_SPLIT_NO_EMPTY);
1224
        foreach ($parts as $part) {
1225
            $headerParts = [];
1226
            $hParts = preg_split("/\s*;\s*/", trim($part), -1, PREG_SPLIT_NO_EMPTY);
1227
            foreach ($hParts as $headerPart) {
1228
                if (strpos($headerPart, '=') !== false) {
1229
                    $split = explode('=', $headerPart, 2);
1230
                    if ($split[0] === 'q') {
1231
                        $headerParts['quality'] = (double)$split[1];
1232
                    } else {
1233
                        $headerParts[$split[0]] = $split[1];
1234
                    }
1235
                } else {
1236
                    $headerParts[$name] = $headerPart;
1237
                    $headerParts['quality'] = 1.0;
1238
                }
1239
            }
1240
1241
            $returnedParts[] = $headerParts;
1242
        }
1243
1244
        return $returnedParts;
1245
    }
1246
1247
    /**
1248
     * Resolve authorization headers.
1249
     */
1250
    protected function resolveAuthorizationHeaders()
1251
    {
1252
        $headers = [];
1253
        $hasEventsManager = false;
1254
        $eventsManager = null;
1255
1256
        $dependencyInjector = $this->getDI();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $dependencyInjector is correct as $this->getDI() targeting Canvas\Http\SwooleRequest::getDI() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1257
        if ($dependencyInjector instanceof DiInterface) {
1258
            $hasEventsManager = (bool)$dependencyInjector->has('eventsManager');
1259
            if ($hasEventsManager) {
1260
                $eventsManager = $dependencyInjector->getShared('eventsManager');
1261
            }
1262
        }
1263
1264
        if ($hasEventsManager && $eventsManager instanceof Manager) {
1265
            $resolved = $eventsManager->fire(
1266
                'request:beforeAuthorizationResolve',
1267
                $this,
1268
                ['server' => $this->getServers()]
1269
            );
1270
1271
            if (is_array($resolved)) {
1272
                $headers = array_merge($headers, $resolved);
1273
            }
1274
        }
1275
1276
        $this->resolveAuthHeaderPhp($headers);
1277
        $this->resolveAuthHeaderPhpDigest($headers);
1278
1279
        if ($hasEventsManager && $eventsManager instanceof Manager) {
1280
            $resolved = $eventsManager->fire(
1281
                'request:afterAuthorizationResolve',
1282
                $this,
1283
                ['headers' => $headers, 'server' => $this->getServers()]
1284
            );
1285
1286
            if (is_array($resolved)) {
1287
                $headers = array_merge($headers, $resolved);
1288
            }
1289
        }
1290
1291
        return $headers;
1292
    }
1293
1294
    /**
1295
     * Resolve the PHP_AUTH_USER.
1296
     *
1297
     * @param array $headers
1298
     * @return void
1299
     */
1300
    protected function resolveAuthHeaderPhp(array &$headers): void
1301
    {
1302
        $authHeader = false;
1303
1304
        if ($this->hasServer('PHP_AUTH_USER') && $this->hasServer('PHP_AUTH_PW')) {
1305
            $headers['Php-Auth-User'] = $this->getServer('PHP_AUTH_USER');
1306
            $headers['Php-Auth-Pw'] = $this->getServer('PHP_AUTH_PW');
1307
        } else {
1308
            if ($this->hasServer('HTTP_AUTHORIZATION')) {
1309
                $authHeader = $this->getServer('HTTP_AUTHORIZATION');
1310
            } elseif ($this->hasServer('REDIRECT_HTTP_AUTHORIZATION')) {
1311
                $authHeader = $this->getServer('REDIRECT_HTTP_AUTHORIZATION');
1312
            }
1313
1314
            if ($authHeader) {
1315
                if (stripos($authHeader, 'basic ') === 0) {
1316
                    $exploded = explode(':', base64_decode(substr($authHeader, 6)), 2);
1317
                    if (count($exploded) == 2) {
1318
                        $headers['Php-Auth-User'] = $exploded[0];
1319
                        $headers['Php-Auth-Pw'] = $exploded[1];
1320
                    }
1321
                } elseif (stripos($authHeader, 'digest ') === 0 && !$this->hasServer('PHP_AUTH_DIGEST')) {
1322
                    $headers['Php-Auth-Digest'] = $authHeader;
1323
                } elseif (stripos($authHeader, 'bearer ') === 0) {
1324
                    $headers['Authorization'] = $authHeader;
1325
                }
1326
            }
1327
        }
1328
    }
1329
1330
    /**
1331
     * Reseolve PHP auth digest.
1332
     *
1333
     * @param array $headers
1334
     * @return void
1335
     */
1336
    protected function resolveAuthHeaderPhpDigest(array &$headers): void
1337
    {
1338
        if (!isset($headers['Authorization'])) {
1339
            if (isset($headers['Php-Auth-User'])) {
1340
                $headers['Authorization'] = 'Basic ' . base64_encode($headers['Php-Auth-User'] . ':' . $headers['Php-Auth-Pw']);
1341
            } elseif (isset($headers['Php-Auth-Digest'])) {
1342
                $headers['Authorization'] = $headers['Php-Auth-Digest'];
1343
            }
1344
        }
1345
    }
1346
}
1347