1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package Http server |
4
|
|
|
* @category modules |
5
|
|
|
* @author Nazar Mokrynskyi <[email protected]> |
6
|
|
|
* @copyright Copyright (c) 2015-2016, Nazar Mokrynskyi |
7
|
|
|
* @license MIT License, see license.txt |
8
|
|
|
*/ |
9
|
|
|
namespace cs\modules\Http_server; |
10
|
|
|
use |
11
|
|
|
cs\_SERVER, |
12
|
|
|
cs\ExitException, |
13
|
|
|
cs\Language, |
14
|
|
|
cs\Index, |
15
|
|
|
cs\Page, |
16
|
|
|
cs\Request as System_request, |
17
|
|
|
cs\Response as System_response, |
18
|
|
|
cs\User; |
19
|
|
|
|
20
|
|
|
class Request { |
21
|
|
|
/** |
22
|
|
|
* @var \React\Http\Request |
23
|
|
|
*/ |
24
|
|
|
protected $request; |
25
|
|
|
/** |
26
|
|
|
* @var \React\Http\Response |
27
|
|
|
*/ |
28
|
|
|
protected $response; |
29
|
|
|
/** |
30
|
|
|
* @param \React\Http\Request $request |
31
|
|
|
* @param \React\Http\Response $response |
32
|
|
|
*/ |
33
|
|
|
function __construct ($request, $response) { |
34
|
|
|
$this->request = $request; |
35
|
|
|
$this->response = $response; |
36
|
|
|
} |
37
|
|
|
/** |
38
|
|
|
* @param string $data |
39
|
|
|
* |
40
|
|
|
* @throws ExitException |
41
|
|
|
*/ |
42
|
|
|
function __invoke ($data) { |
43
|
|
|
$request = $this->request; |
44
|
|
|
$this->fill_superglobals( |
45
|
|
|
$this->prepare_superglobals($request, $data) |
46
|
|
|
); |
47
|
|
|
try { |
48
|
|
|
try { |
49
|
|
|
$this->execute_request(); |
50
|
|
|
} catch (ExitException $e) { |
51
|
|
|
if ($e->getCode() >= 400) { |
52
|
|
|
Page::instance()->error($e->getMessage() ?: null, $e->getJson(), $e->getCode()); |
53
|
|
|
} |
54
|
|
|
} |
55
|
|
|
} catch (\Exception $e) { |
56
|
|
|
// Handle generic exceptions to avoid server from stopping |
57
|
|
|
} |
58
|
|
|
$Response = System_response::instance(); |
59
|
|
|
$this->response->writeHead($Response->code, $Response->headers); |
60
|
|
|
if (is_resource($Response->body_stream)) { |
61
|
|
|
$position = ftell($Response->body_stream); |
62
|
|
|
rewind($Response->body_stream); |
63
|
|
|
while (!feof($Response->body_stream)) { |
64
|
|
|
$this->response->write(fread($Response->body_stream, 1024)); |
65
|
|
|
} |
66
|
|
|
fseek($Response->body_stream, $position); |
67
|
|
|
} else { |
68
|
|
|
$this->response->end($Response->body); |
69
|
|
|
} |
70
|
|
|
$this->cleanup(); |
71
|
|
|
$request->close(); |
72
|
|
|
} |
73
|
|
|
/** |
74
|
|
|
* @param \React\HTTP\Request $request |
75
|
|
|
* @param string $data |
76
|
|
|
* |
77
|
|
|
* @return array |
78
|
|
|
*/ |
79
|
|
|
protected function prepare_superglobals ($request, $data) { |
80
|
|
|
$SERVER = [ |
81
|
|
|
'SERVER_SOFTWARE' => 'ReactPHP' |
82
|
|
|
]; |
83
|
|
|
$COOKIE = []; |
84
|
|
|
$POST = []; |
85
|
|
|
foreach ($request->getHeaders() as $key => $value) { |
86
|
|
|
if ($key == 'Content-Type') { |
87
|
|
|
$SERVER['CONTENT_TYPE'] = $value; |
88
|
|
|
} elseif ($key == 'Cookie') { |
89
|
|
|
$value = _trim(explode(';', $value)); |
90
|
|
|
foreach ($value as $c) { |
91
|
|
|
$c = explode('=', $c); |
92
|
|
|
$COOKIE[$c[0]] = $c[1]; |
93
|
|
|
} |
94
|
|
|
unset($c); |
95
|
|
|
} else { |
96
|
|
|
$key = strtoupper(str_replace('-', '_', $key)); |
97
|
|
|
$SERVER["HTTP_$key"] = $value; |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
$SERVER['REQUEST_METHOD'] = $request->getMethod(); |
101
|
|
|
$SERVER['REQUEST_URI'] = $request->getPath(); |
102
|
|
|
$SERVER['QUERY_STRING'] = http_build_query($request->getQuery()); |
103
|
|
|
$SERVER['REMOTE_ADDR'] = $request->remoteAddress; |
104
|
|
|
$GET = $request->getQuery(); |
105
|
|
|
$SERVER['SERVER_PROTOCOL'] = 'HTTP/'.$request->getHttpVersion(); |
106
|
|
|
if (isset($SERVER['CONTENT_TYPE'])) { |
107
|
|
|
if (strpos($SERVER['CONTENT_TYPE'], 'application/x-www-form-urlencoded') === 0) { |
108
|
|
|
parse_str($data, $POST); |
109
|
|
|
} elseif (preg_match('#^application/([^+\s]+\+)?json#', $SERVER['CONTENT_TYPE'])) { |
110
|
|
|
$POST = json_decode($data, true); |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
return [ |
114
|
|
|
'SERVER' => $SERVER, |
115
|
|
|
'COOKIE' => $COOKIE, |
116
|
|
|
'GET' => $GET, |
117
|
|
|
'POST' => $POST |
118
|
|
|
]; |
119
|
|
|
} |
120
|
|
|
/** |
121
|
|
|
* @param array $SUPERGLOBALS |
122
|
|
|
* |
123
|
|
|
* @throws ExitException |
124
|
|
|
*/ |
125
|
|
|
protected function fill_superglobals ($SUPERGLOBALS) { |
126
|
|
|
$_SERVER = new _SERVER($SUPERGLOBALS['SERVER']); |
|
|
|
|
127
|
|
|
$_COOKIE = $SUPERGLOBALS['COOKIE']; |
128
|
|
|
$_GET = $SUPERGLOBALS['GET']; |
129
|
|
|
$_POST = $SUPERGLOBALS['POST']; |
130
|
|
|
$_REQUEST = $SUPERGLOBALS['POST'] + $SUPERGLOBALS['GET']; |
131
|
|
|
// TODO: Move this initialization separately |
132
|
|
|
System_request::instance()->init_from_globals(); |
133
|
|
|
System_response::instance()->init( |
134
|
|
|
'', |
135
|
|
|
null, |
136
|
|
|
[ |
137
|
|
|
'Content-Type' => 'text/html; charset=utf-8', |
138
|
|
|
'Vary' => 'Accept-Language,User-Agent,Cookie' |
139
|
|
|
], |
140
|
|
|
200, |
141
|
|
|
$_SERVER['SERVER_PROTOCOL'] |
142
|
|
|
); |
143
|
|
|
} |
144
|
|
|
/** |
145
|
|
|
* @throws ExitException |
146
|
|
|
*/ |
147
|
|
|
protected function execute_request () { |
148
|
|
|
try { |
149
|
|
|
$L = Language::instance(true); |
150
|
|
|
$url_language = $L->url_language(); |
151
|
|
|
if ($url_language) { |
152
|
|
|
$L->change($url_language); |
153
|
|
|
} |
154
|
|
|
Index::instance(); |
155
|
|
|
} catch (ExitException $e) { |
156
|
|
|
if ($e->getCode()) { |
157
|
|
|
throw $e; |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
try { |
161
|
|
|
Index::instance(true)->__finish(); |
162
|
|
|
Page::instance()->__finish(); |
163
|
|
|
User::instance(true)->__finish(); |
164
|
|
|
} catch (ExitException $e) { |
165
|
|
|
if ($e->getCode()) { |
166
|
|
|
throw $e; |
167
|
|
|
} |
168
|
|
|
} |
169
|
|
|
} |
170
|
|
|
/** |
171
|
|
|
* Various cleanups after processing of current request to free used memory |
172
|
|
|
*/ |
173
|
|
|
function cleanup () { |
174
|
|
|
/** |
175
|
|
|
* Clean objects pool |
176
|
|
|
*/ |
177
|
|
|
objects_pool([]); |
178
|
|
|
admin_path(false); |
179
|
|
|
api_path(false); |
180
|
|
|
current_module(''); |
181
|
|
|
home_page(false); |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.