Requesting::getServerRequest()   B
last analyzed

Complexity

Conditions 7
Paths 13

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 39
c 0
b 0
f 0
rs 8.6186
cc 7
nc 13
nop 0
1
<?php
2
/**
3
 * HTTP Decoder
4
 * User: moyo
5
 * Date: 08/01/2018
6
 * Time: 2:48 PM
7
 */
8
9
namespace Carno\HTTP\Powered\Native\Parser;
10
11
use Carno\HTTP\Exception\NVServerRequestingException;
12
use Carno\HTTP\Standard\ServerRequest;
13
use Carno\HTTP\Standard\Uri;
14
15
class Requesting
16
{
17
    private const BUFFER = 512;
18
19
    /**
20
     * @var Protocol
21
     */
22
    private $socket = null;
23
24
    /**
25
     * @var string
26
     */
27
    private $header = '';
28
29
    /**
30
     * @var string
31
     */
32
    private $body = '';
33
34
    /**
35
     * Decoder constructor.
36
     * @param Protocol $socket
37
     */
38
    public function __construct(Protocol $socket)
39
    {
40
        $this->socket = $socket;
41
    }
42
43
    /**
44
     * @return ServerRequest
45
     */
46
    public function getServerRequest() : ServerRequest
47
    {
48
        $this->partH();
49
        $this->partB();
50
51
        if (empty($this->header)) {
52
            throw new NVServerRequestingException;
53
        }
54
55
        list($method, $uri) = explode(
56
            ' ',
57
            substr($this->header, 0, $flp = strpos($this->header, Protocol::CRLF))
58
        );
59
60
        $qss = '';
61
        $qrs = [];
62
        if (false !== $qsp = strpos($uri, '?')) {
63
            parse_str($qss = substr($uri, $qsp), $qrs);
64
            $uri = substr($uri, 0, $qsp);
65
        }
66
67
        $headers = [];
68
        foreach (explode(Protocol::CRLF, substr($this->header, $flp + 2)) as $hl) {
69
            if (false !== $hsp = strpos($hl, ':')) {
70
                $headers[substr($hl, 0, $hsp)] = trim(substr($hl, $hsp + 1));
71
            }
72
        }
73
74
        $srq = new ServerRequest([], [], $qrs, $method, $headers, $this->body ?: null);
75
76
        $hosts = $srq->getHeader('host');
77
        $host = reset($hosts);
78
        if (strpos($host, ':')) {
79
            list($host, $port) = explode(':', $host);
80
        }
81
82
        $srq->withUri(new Uri('http', $host, $port ?? 80, $uri, $qss));
83
84
        return $srq;
85
    }
86
87
    /**
88
     */
89
    private function partH() : void
90
    {
91
        $got = $this->socket->read(self::BUFFER);
92
93
        if (false !== $eof = strpos($got, Protocol::SPLIT)) {
94
            $this->header .= substr($got, 0, $eof + 2);
95
            if ($eof + 4 < strlen($got)) {
96
                $this->body = substr($got, $eof + 4);
97
            }
98
            return;
99
        }
100
101
        if ($got) {
102
            $this->header .= $got;
103
            $this->partH();
104
        }
105
    }
106
107
    /**
108
     */
109
    private function partB() : void
110
    {
111
        // TODO support http post
112
    }
113
}
114