Passed
Push — master ( b45126...8af3f1 )
by 世昌
03:18
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
     * @var array
23
     */
24
    protected $server;
25
26
    /**
27
     * 创建请求包装器
28
     *
29
     * @param RawRequest $request
30
     */
31
    public function __construct(RawRequest $request)
32
    {
33
        $this->request = $request;
34
        $this->server = $this->getFormatServer($request);
35
    }
36
37
    /**
38
     * 构建对象
39
     *
40
     * @param RequestWrapper $request
41
     * @return void
42
     */
43
    public function build(RequestWrapper $request)
44
    {
45
        $request->setServer($this->server);
46
        $request->setRemoteAddr($this->filterRemoteAddr());
47
        $method = strtoupper($request->getServer('request-method', 'GET'));
48
        $request->setMethod($method);
49
        $request->setHost($this->getHttpHost());
50
        $request->setSecure($this->getSecure());
51
        $request->setPort($this->getServerPort());
52
        $this->createUri($request);
53
        $request->setUriBase(static::createUriBase($request));
54
    }
55
56
    /**
57
     * 获取IP地址
58
     *
59
     * @return string
60
     */
61
    private function filterRemoteAddr():string
62
    {
63
        static $ipFrom = [
64
            'http-client-ip',
65
            'http-x-forwarded-for',
66
            'http-x-forwarded',
67
            'http-x-cluster-client-ip',
68
            'http-forwarded-for',
69
            'http-forwarded',
70
            'remote-addr',
71
        ];
72
73
        foreach ($ipFrom as $key) {
74
            if (array_key_exists($key, $this->server)) {
75
                foreach (explode(',', $this->server[$key]) as $ip) {
76
                    $ip = trim($ip);
77
                    if (filter_var(
78
                        $ip,
79
                        FILTER_VALIDATE_IP,
80
                        FILTER_FLAG_IPV4
81
                        | FILTER_FLAG_IPV6
82
                        | FILTER_FLAG_NO_PRIV_RANGE
83
                        | FILTER_FLAG_NO_RES_RANGE
84
                    ) !== false) {
85
                        return $ip;
86
                    }
87
                }
88
            }
89
        }
90
        return  '0.0.0.0';
91
    }
92
    
93
    /**
94
     * 从请求投中获取HOST
95
     *
96
     * @return string
97
     */
98
    private function getHttpHost():string
99
    {
100
        if (array_key_exists('host', $this->request->header())) {
101
            return explode(':', $this->request->header()['host'])[0];
102
        }
103
        return $this->server['server-name'] ?? 'localhost';
104
    }
105
106
    /**
107
     * 获取端口
108
     *
109
     * @return integer
110
     */
111
    private function getServerPort():int
112
    {
113
        if (array_key_exists('server-port', $this->server)) {
114
            return $this->server['server-port'];
115
        }
116
        return $this->getSecure()?443:80;
117
    }
118
119
    /**
120
     * 获取安全状态
121
     *
122
     * @return boolean
123
     */
124
    private function getSecure():bool
125
    {
126
        $https = array_key_exists('https', $this->server)
127
            && strcasecmp($this->server['https'], 'off') != 0;
128
        $scheme = array_key_exists('request-scheme', $this->server)
129
            && strcasecmp($this->server['request-scheme'], 'https') === 0;
130
        return $https || $scheme;
131
    }
132
133
    /**
134
     * 创建URI
135
     *
136
     * @param RequestWrapper $request
137
     * @return void
138
     */
139
    private function createUri(RequestWrapper $request)
140
    {
141
        if (array_key_exists('document-root', $this->server)) {
142
            $index = (new IndexFinder(null, $this->server['document-root']))->getIndexFile();
143
        } else {
144
            $index = '';
145
        }
146
        $request->setIndex($index);
147
        $url = new UriParser($this->server['request-uri'] ?? '/', $index);
148
        $request->setQueries($url->getQuery());
149
        $request->setUri($url->getUri());
150
    }
151
152
    /**
153
     * 获取URI基础部分
154
     *
155
     * @param RequestWrapper $request
156
     * @return string
157
     */
158
    public static function createUriBase(RequestWrapper $request)
159
    {
160
        $scheme = $request->isSecure()?'https':'http';
161
        $port = $request->getPort();
162
        if ($port == 80 && $scheme == 'http') {
163
            $port = '';
164
        } elseif ($port == 433 && $scheme == 'https') {
165
            $port = '';
166
        } else {
167
            $port = ':'.$port;
168
        }
169
        $base = $scheme.'://'. $request->getHost().$port;
170
        return $base;
171
    }
172
173
    /**
174
     * 构建环境数据
175
     *
176
     * @param RawRequest $request
177
     * @return array
178
     */
179
    private function getFormatServer(RawRequest $request)
180
    {
181
        $server = [];
182
        foreach ($request->server() as $key => $value) {
183
            $name = strtolower(str_replace('_', '-', $key));
184
            $server[$name] = $value;
185
        }
186
        return $server;
187
    }
188
}
189