Request::handleStatic()   B
last analyzed

Complexity

Conditions 7
Paths 5

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 7
eloc 15
c 3
b 0
f 0
nc 5
nop 3
dl 0
loc 27
rs 8.8333
1
<?php
2
3
namespace SwooleTW\Http\Transformers;
4
5
use Illuminate\Http\Request as IlluminateRequest;
6
use Illuminate\Http\Response as IlluminateResponse;
7
use Swoole\Http\Request as SwooleRequest;
8
use SwooleTW\Http\Helpers\FW;
9
use SwooleTW\Http\Helpers\MimeType;
10
use Symfony\Component\HttpFoundation\ParameterBag;
11
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
12
13
/**
14
 * Class Request
15
 */
16
class Request
17
{
18
    /**
19
     * Blacklisted extensions
20
     *
21
     * @const array
22
     */
23
    protected const EXTENSION_BLACKLIST = ['php', 'htaccess', 'config'];
24
25
    /**
26
     * Extension mime types
27
     */
28
    protected const EXTENSION_MIMES = ['js' => 'text/javascript', 'css' => 'text/css'];
29
30
    /**
31
     * @var \Illuminate\Http\Request
32
     */
33
    protected $illuminateRequest;
34
35
    /**
36
     * Make a request.
37
     *
38
     * @param \Swoole\Http\Request $swooleRequest
39
     *
40
     * @return \SwooleTW\Http\Transformers\Request
41
     */
42
    public static function make(SwooleRequest $swooleRequest)
43
    {
44
        return new static(...static::toIlluminateParameters($swooleRequest));
45
    }
46
47
    /**
48
     * Request constructor.
49
     *
50
     * @param array $params provides GET, POST, COOKIE, FILES, SERVER, CONTENT
51
     */
52
    public function __construct(...$params)
53
    {
54
        $this->createIlluminateRequest(...$params);
55
    }
56
57
    /**
58
     * Create Illuminate Request.
59
     *
60
     * @param array $get
61
     * @param array $post
62
     * @param array $cookie
63
     * @param array $files
64
     * @param array $server
65
     * @param string $content
66
     *
67
     * @return void
68
     */
69
    protected function createIlluminateRequest($get, $post, $cookie, $files, $server, $content = null)
70
    {
71
        IlluminateRequest::enableHttpMethodParameterOverride();
72
73
        /*
74
        |--------------------------------------------------------------------------
75
        | Copy from \Symfony\Component\HttpFoundation\Request::createFromGlobals().
76
        |--------------------------------------------------------------------------
77
        |
78
        | With the php's bug #66606, the php's built-in web server
79
        | stores the Content-Type and Content-Length header values in
80
        | HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH fields.
81
        |
82
        */
83
84
        if ('cli-server' === PHP_SAPI) {
85
            if (array_key_exists('HTTP_CONTENT_LENGTH', $server)) {
86
                $server['CONTENT_LENGTH'] = $server['HTTP_CONTENT_LENGTH'];
87
            }
88
            if (array_key_exists('HTTP_CONTENT_TYPE', $server)) {
89
                $server['CONTENT_TYPE'] = $server['HTTP_CONTENT_TYPE'];
90
            }
91
        }
92
93
        $request = new SymfonyRequest($get, $post, [], $cookie, $files, $server, $content);
94
95
        if (0 === strpos($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded')
96
            && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'])
97
        ) {
98
            parse_str($request->getContent(), $data);
99
            $request->request = new ParameterBag($data);
100
        }
101
102
        $this->illuminateRequest = IlluminateRequest::createFromBase($request);
103
    }
104
105
    /**
106
     * @return \Illuminate\Http\Request
107
     */
108
    public function toIlluminate()
109
    {
110
        return $this->getIlluminateRequest();
111
    }
112
113
    /**
114
     * @return \Illuminate\Http\Request
115
     */
116
    public function getIlluminateRequest()
117
    {
118
        return $this->illuminateRequest;
119
    }
120
121
    /**
122
     * Transforms request parameters.
123
     *
124
     * @param \Swoole\Http\Request $request
125
     *
126
     * @return array
127
     */
128
    protected static function toIlluminateParameters(SwooleRequest $request)
129
    {
130
        $get = $request->get ?? [];
131
        $post = $request->post ?? [];
132
        $cookie = $request->cookie ?? [];
133
        $files = $request->files ?? [];
134
        $header = $request->header ?? [];
135
        $server = $request->server ?? [];
136
        $server = static::transformServerParameters($server, $header);
137
        $content = $request->rawContent();
138
139
        return [$get, $post, $cookie, $files, $server, $content];
140
    }
141
142
    /**
143
     * Transforms $_SERVER array.
144
     *
145
     * @param array $server
146
     * @param array $header
147
     *
148
     * @return array
149
     */
150
    protected static function transformServerParameters(array $server, array $header)
151
    {
152
        $__SERVER = [];
153
154
        foreach ($server as $key => $value) {
155
            $key = strtoupper($key);
156
            $__SERVER[$key] = $value;
157
        }
158
159
        foreach ($header as $key => $value) {
160
            $key = str_replace('-', '_', $key);
161
            $key = strtoupper($key);
162
163
            if (! in_array($key, ['REMOTE_ADDR', 'SERVER_PORT', 'HTTPS'])) {
164
                $key = 'HTTP_' . $key;
165
            }
166
167
            $__SERVER[$key] = $value;
168
        }
169
170
        return $__SERVER;
171
    }
172
173
    /**
174
     * Handle static request.
175
     *
176
     * @param \Swoole\Http\Request $swooleRequest
177
     * @param \Swoole\Http\Response $swooleResponse
178
     * @param string $publicPath
179
     *
180
     * @return boolean
181
     */
182
    public static function handleStatic($swooleRequest, $swooleResponse, string $publicPath)
183
    {
184
        $uri = $swooleRequest->server['request_uri'] ?? '';
185
        $extension = strtok(pathinfo($uri, PATHINFO_EXTENSION), '?');
186
        $filePath = @realpath($publicPath . $uri);
187
188
        if (!$filePath) {
189
            return false;
190
        }
191
192
        if ($extension && in_array($extension, static::EXTENSION_BLACKLIST)) {
193
            return false;
194
        }
195
196
        if (substr($filePath, 0, strlen($publicPath)) != $publicPath) {
197
            return false;
198
        }
199
200
        if (! is_file($filePath) || ! filesize($filePath)) {
201
            return false;
202
        }
203
204
        $swooleResponse->status(IlluminateResponse::HTTP_OK);
205
        $swooleResponse->header('Content-Type', MimeType::get($extension));
0 ignored issues
show
Bug introduced by
It seems like SwooleTW\Http\Helpers\MimeType::get($extension) can also be of type array; however, parameter $value of Swoole\Http\Response::header() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

205
        $swooleResponse->header('Content-Type', /** @scrutinizer ignore-type */ MimeType::get($extension));
Loading history...
206
        $swooleResponse->sendfile($filePath);
207
208
        return true;
209
    }
210
}
211