Passed
Push — dev ( e94c4f...6bd794 )
by 世昌
03:12
created

Builder::createUriBase()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 10
nc 6
nop 1
dl 0
loc 13
rs 9.2222
c 0
b 0
f 0
1
<?php
2
namespace suda\framework\request;
3
4
use function array_key_exists;
5
use suda\framework\http\Request as RawRequest;
6
7
/**
8
 * 请求包装器
9
 * 包装PHP请求
10
 */
11
class Builder
12
{
13
14
    /**
15
     * HTTP请求
16
     *
17
     * @var RawRequest
18
     */
19
    protected $request;
20
    
21
    /**
22
     * 创建请求包装器
23
     *
24
     * @param RawRequest $request
25
     */
26
    public function __construct(RawRequest $request)
27
    {
28
        $this->request = $request;
29
    }
30
31
    /**
32
     * 构建对象
33
     *
34
     * @param RequestWrapper $request
35
     * @return void
36
     */
37
    public function build(RequestWrapper $request)
38
    {
39
        $request->setRemoteAddr($this->filterRemoteAddr());
40
        $request->setMethod(strtoupper($this->request->server()['request-method'] ?? 'GET'));
41
        $request->setHost($this->getHttpHost());
42
        $request->setSecure($this->getSecure());
43
        $request->setPort($this->getServerPort());
44
        $this->createUri($request);
45
        $request->setUriBase(static::createUriBase($request));
46
    }
47
48
    /**
49
     * 获取IP地址
50
     *
51
     * @return string
52
     */
53
    private function filterRemoteAddr():string
54
    {
55
        static $ipFrom = [
56
            'http-client-ip',
57
            'http-x-forwarded-for',
58
            'http-x-forwarded',
59
            'http-x-cluster-client-ip',
60
            'http-forwarded-for',
61
            'http-forwarded',
62
            'remote-addr',
63
        ];
64
        foreach ($ipFrom as $key) {
65
            if (array_key_exists($key, $this->request->server())) {
66
                foreach (explode(',', $this->request->server()[$key]) as $ip) {
67
                    $ip = trim($ip);
68
                    if (filter_var(
69
                        $ip,
70
                        FILTER_VALIDATE_IP,
71
                        FILTER_FLAG_IPV4
72
                        | FILTER_FLAG_IPV6
73
                        | FILTER_FLAG_NO_PRIV_RANGE
74
                        | FILTER_FLAG_NO_RES_RANGE
75
                    ) !== false) {
76
                        return $ip;
77
                    }
78
                }
79
            }
80
        }
81
        return  '0.0.0.0';
82
    }
83
    
84
    /**
85
     * 从请求投中获取HOST
86
     *
87
     * @return string
88
     */
89
    private function getHttpHost():string
90
    {
91
        if (array_key_exists('host', $this->request->header())) {
92
            return explode(':', $this->request->header()['host'])[0];
93
        }
94
        return $this->request->server()['server-name'] ?? 'localhost';
95
    }
96
97
    /**
98
     * 获取端口
99
     *
100
     * @return integer
101
     */
102
    private function getServerPort():int
103
    {
104
        if (array_key_exists('server-port', $this->request->server())) {
105
            return $this->request->server()['server-port'];
106
        }
107
        return $this->getSecure()?443:80;
108
    }
109
110
    /**
111
     * 获取安全状态
112
     *
113
     * @return boolean
114
     */
115
    private function getSecure():bool
116
    {
117
        $https = array_key_exists('https', $this->request->server())
118
            && strcasecmp($this->request->server()['https'], 'off') != 0;
119
        $scheme = array_key_exists('request-scheme', $this->request->server())
120
            && strcasecmp($this->request->server()['request-scheme'], 'https') === 0;
121
        return $https || $scheme;
122
    }
123
124
    /**
125
     * 创建URI
126
     *
127
     * @param RequestWrapper $request
128
     * @return void
129
     */
130
    private function createUri(RequestWrapper $request)
131
    {
132
        if (array_key_exists('document-root', $this->request->server())) {
133
            $index = (new IndexFinder(null, $this->request->server()['document-root']))->getIndexFile();
134
        } else {
135
            $index = '';
136
        }
137
        $request->setIndex($index);
138
        $url = new UriParser($this->request->server()['request-uri'] ?? '/', $index);
139
        $request->setQueries($url->getQuery());
140
        $request->setUri($url->getUri());
141
    }
142
143
    /**
144
     * 获取URI基础部分
145
     *
146
     * @param RequestWrapper $request
147
     * @return string
148
     */
149
    public static function createUriBase(RequestWrapper $request)
150
    {
151
        $scheme = $request->isSecure()?'https':'http';
152
        $port = $request->getPort();
153
        if ($port == 80 && $scheme == 'http') {
154
            $port = '';
155
        } elseif ($port == 433 && $scheme == 'https') {
156
            $port = '';
157
        } else {
158
            $port = ':'.$port;
159
        }
160
        $base = $scheme.'://'. $request->getHost().$port;
161
        return $base;
162
    }
163
}
164