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\App, |
13
|
|
|
cs\ExitException, |
14
|
|
|
cs\Language, |
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
|
|
|
* @var float |
31
|
|
|
*/ |
32
|
|
|
protected $request_started; |
33
|
|
|
/** |
34
|
|
|
* @param \React\Http\Request $request |
35
|
|
|
* @param \React\Http\Response $response |
36
|
|
|
* @param float $request_started |
37
|
|
|
*/ |
38
|
|
|
function __construct ($request, $response, $request_started) { |
39
|
|
|
$this->request = $request; |
40
|
|
|
$this->response = $response; |
41
|
|
|
$this->request_started = $request_started; |
42
|
|
|
} |
43
|
|
|
/** |
44
|
|
|
* @param string $data |
45
|
|
|
* |
46
|
|
|
* @throws ExitException |
47
|
|
|
*/ |
48
|
|
|
function __invoke ($data) { |
49
|
|
|
$request = $this->request; |
50
|
|
|
$this->fill_superglobals( |
51
|
|
|
$this->prepare_superglobals($request, $data) |
52
|
|
|
); |
53
|
|
|
try { |
54
|
|
|
try { |
55
|
|
|
$this->execute_request(); |
56
|
|
|
} catch (ExitException $e) { |
57
|
|
|
if ($e->getCode() >= 400) { |
58
|
|
|
Page::instance()->error($e->getMessage() ?: null, $e->getJson()); |
59
|
|
|
} |
60
|
|
|
} |
61
|
|
|
} catch (\Exception $e) { |
62
|
|
|
// Handle generic exceptions to avoid server from stopping |
63
|
|
|
} |
64
|
|
|
$Response = System_response::instance(); |
65
|
|
|
$this->response->writeHead($Response->code, $Response->headers); |
66
|
|
|
if (is_resource($Response->body_stream)) { |
67
|
|
|
$position = ftell($Response->body_stream); |
68
|
|
|
rewind($Response->body_stream); |
69
|
|
|
while (!feof($Response->body_stream)) { |
70
|
|
|
$this->response->write(fread($Response->body_stream, 1024)); |
71
|
|
|
} |
72
|
|
|
fseek($Response->body_stream, $position); |
73
|
|
|
} else { |
74
|
|
|
$this->response->end($Response->body); |
75
|
|
|
} |
76
|
|
|
$request->close(); |
77
|
|
|
User::instance()->disable_memory_cache(); |
78
|
|
|
} |
79
|
|
|
/** |
80
|
|
|
* @param \React\HTTP\Request $request |
81
|
|
|
* @param string $data |
82
|
|
|
* |
83
|
|
|
* @return array |
84
|
|
|
*/ |
85
|
|
|
protected function prepare_superglobals ($request, $data) { |
86
|
|
|
$SERVER = [ |
87
|
|
|
'SERVER_SOFTWARE' => 'ReactPHP' |
88
|
|
|
]; |
89
|
|
|
$COOKIE = []; |
90
|
|
|
$POST = []; |
91
|
|
|
foreach ($request->getHeaders() as $key => $value) { |
92
|
|
|
if ($key == 'Content-Type') { |
93
|
|
|
$SERVER['CONTENT_TYPE'] = $value; |
94
|
|
|
} elseif ($key == 'Cookie') { |
95
|
|
|
$value = _trim(explode(';', $value)); |
96
|
|
|
foreach ($value as $c) { |
97
|
|
|
$c = explode('=', $c); |
98
|
|
|
$COOKIE[$c[0]] = $c[1]; |
99
|
|
|
} |
100
|
|
|
unset($c); |
101
|
|
|
} else { |
102
|
|
|
$key = strtoupper(str_replace('-', '_', $key)); |
103
|
|
|
$SERVER["HTTP_$key"] = $value; |
104
|
|
|
} |
105
|
|
|
} |
106
|
|
|
$SERVER['REQUEST_METHOD'] = $request->getMethod(); |
107
|
|
|
$SERVER['REQUEST_URI'] = $request->getPath(); |
108
|
|
|
$SERVER['QUERY_STRING'] = http_build_query($request->getQuery()); |
109
|
|
|
$SERVER['REMOTE_ADDR'] = $request->remoteAddress; |
110
|
|
|
$GET = $request->getQuery(); |
111
|
|
|
$SERVER['SERVER_PROTOCOL'] = 'HTTP/'.$request->getHttpVersion(); |
112
|
|
|
if (isset($SERVER['CONTENT_TYPE'])) { |
113
|
|
|
if (strpos($SERVER['CONTENT_TYPE'], 'application/x-www-form-urlencoded') === 0) { |
114
|
|
|
parse_str($data, $POST); |
115
|
|
|
} elseif (preg_match('#^application/([^+\s]+\+)?json#', $SERVER['CONTENT_TYPE'])) { |
116
|
|
|
$POST = json_decode($data, true); |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
return [ |
120
|
|
|
'SERVER' => $SERVER, |
121
|
|
|
'COOKIE' => $COOKIE, |
122
|
|
|
'GET' => $GET, |
123
|
|
|
'POST' => $POST |
124
|
|
|
]; |
125
|
|
|
} |
126
|
|
|
/** |
127
|
|
|
* @param array $SUPERGLOBALS |
128
|
|
|
* |
129
|
|
|
* @throws ExitException |
130
|
|
|
*/ |
131
|
|
|
protected function fill_superglobals ($SUPERGLOBALS) { |
132
|
|
|
// Hack: Filling $_SERVER is primarily needed for HybridAuth (many hard dependencies on `$_SERVER`) |
133
|
|
|
$_SERVER = new _SERVER($SUPERGLOBALS['SERVER']); |
|
|
|
|
134
|
|
|
$_COOKIE = $SUPERGLOBALS['COOKIE']; |
135
|
|
|
$_GET = $SUPERGLOBALS['GET']; |
136
|
|
|
$_POST = $SUPERGLOBALS['POST']; |
137
|
|
|
$_REQUEST = $SUPERGLOBALS['POST'] + $SUPERGLOBALS['GET']; |
138
|
|
|
} |
139
|
|
|
/** |
140
|
|
|
* @throws ExitException |
141
|
|
|
*/ |
142
|
|
|
protected function execute_request () { |
143
|
|
|
$Request = System_request::instance(); |
144
|
|
|
$Request->init_from_globals(); |
145
|
|
|
$Request->started = $this->request_started; |
146
|
|
|
System_response::instance()->init_with_typical_default_settings(); |
147
|
|
|
$L = Language::instance(true); |
148
|
|
|
$url_language = $L->url_language(); |
149
|
|
|
if ($url_language) { |
150
|
|
|
$L->change($url_language); |
151
|
|
|
} |
152
|
|
|
App::instance()->execute(); |
153
|
|
|
} |
154
|
|
|
} |
155
|
|
|
|
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.