Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/buildyourownbotnet/assets/js/jquery-terminal/examples/json-rpc.php
1293 views
1
<?php
2
/*
3
JSON-RPC Server implemenation
4
Copyright (C) 2009 Jakub Jankiewicz <http://jcubic.pl>
5
6
This program is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
/*
21
USAGE: create one class with public methods and call handle_json_rpc function
22
with instance of this class
23
24
<?php
25
require('json_rpc.php');
26
class Server {
27
public function test($message) {
28
return "you send " . $message;
29
}
30
}
31
32
handle_json_rpc(new Server());
33
?>
34
35
you can provide documentations for methods
36
by adding static field:
37
38
class Server {
39
...
40
public static $test_documentation = "doc string";
41
}
42
*/
43
// ----------------------------------------------------------------------------
44
set_error_handler('error_handler');
45
ini_set('display_errors', 1);
46
ini_set('track_errors', 1);
47
ob_start();
48
function error_handler($err, $message, $file, $line) {
49
global $stop;
50
$stop = true;
51
$content = explode("\n", file_get_contents($file));
52
header('Content-Type: application/json');
53
$id = extract_id(); // don't need to parse
54
$error = array(
55
"code" => 100,
56
"message" => "Server error",
57
"error" => array(
58
"name" => "PHPErorr",
59
"code" => $err,
60
"message" => $message,
61
"file" => $file,
62
"at" => $line,
63
"line" => $content[$line-1]));
64
ob_end_clean();
65
echo response(null, $id, $error);
66
exit();
67
}
68
// ----------------------------------------------------------------------------
69
70
class JsonRpcExeption extends Exception {
71
function __construct($code, $message) {
72
$this->code = $code;
73
Exception::__construct($message);
74
}
75
function code() {
76
return $this->code;
77
}
78
}
79
80
// ----------------------------------------------------------------------------
81
function json_error() {
82
switch (json_last_error()) {
83
case JSON_ERROR_NONE:
84
return 'No error has occurred';
85
case JSON_ERROR_DEPTH:
86
return 'The maximum stack depth has been exceeded';
87
case JSON_ERROR_CTRL_CHAR:
88
return 'Control character error, possibly incorrectly encoded';
89
case JSON_ERROR_SYNTAX:
90
return 'Syntax error';
91
case JSON_ERROR_UTF8:
92
return 'Malformed UTF-8 characters, possibly incorrectly encoded';
93
}
94
}
95
96
// ----------------------------------------------------------------------------
97
function get_raw_post_data() {
98
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
99
return $GLOBALS['HTTP_RAW_POST_DATA'];
100
} else {
101
return file_get_contents('php://input');
102
}
103
}
104
105
// ----------------------------------------------------------------------------
106
// check if object has field
107
function has_field($object, $field) {
108
//return in_array($field, array_keys(get_object_vars($object)));
109
return array_key_exists($field, get_object_vars($object));
110
}
111
112
// ----------------------------------------------------------------------------
113
// return object field if exist otherwise return default value
114
function get_field($object, $field, $default) {
115
$array = get_object_vars($object);
116
if (isset($array[$field])) {
117
return $array[$field];
118
} else {
119
return $default;
120
}
121
}
122
123
124
// ----------------------------------------------------------------------------
125
//create json-rpc response
126
function response($result, $id, $error) {
127
if ($error) {
128
$error['name'] = 'JSONRPCError';
129
}
130
return json_encode(array("jsonrpc" => "2.0",
131
'result' => $result,
132
'id' => $id,
133
'error'=> $error));
134
}
135
136
// ----------------------------------------------------------------------------
137
// try to extract id from broken json
138
function extract_id() {
139
$regex = '/[\'"]id[\'"] *: *([0-9]*)/';
140
$raw_data = get_raw_post_data();
141
if (preg_match($regex, $raw_data, $m)) {
142
return intval($m[1]);
143
} else {
144
return null;
145
}
146
}
147
// ----------------------------------------------------------------------------
148
function currentURL() {
149
$pageURL = 'http';
150
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {
151
$pageURL .= "s";
152
}
153
$pageURL .= "://";
154
if ($_SERVER["SERVER_PORT"] != "80") {
155
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
156
} else {
157
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
158
}
159
return $pageURL;
160
}
161
// ----------------------------------------------------------------------------
162
function service_description($object) {
163
$class_name = get_class($object);
164
$methods = get_class_methods($class_name);
165
$service = array("sdversion" => "1.0",
166
"name" => "DemoService",
167
"address" => currentURL(),
168
"id" => "urn:md5:" . md5(currentURL()));
169
$static = get_class_vars($class_name);
170
foreach ($methods as $method_name) {
171
$proc = array("name" => $method_name);
172
$method = new ReflectionMethod($class_name, $method_name);
173
$params = array();
174
foreach ($method->getParameters() as $param) {
175
$params[] = $param->name;
176
}
177
$proc['params'] = $params;
178
$help_str_name = $method_name . "_documentation";
179
if (array_key_exists($help_str_name, $static)) {
180
$proc['help'] = $static[$help_str_name];
181
}
182
$service['procs'][] = $proc;
183
}
184
return $service;
185
}
186
187
// ----------------------------------------------------------------------------
188
function get_json_request() {
189
$request = get_raw_post_data();
190
if ($request == "") {
191
throw new JsonRpcExeption(101, "Parse Error: no data");
192
}
193
$encoding = mb_detect_encoding($request, 'auto');
194
//convert to unicode
195
if ($encoding != 'UTF-8') {
196
$request = iconv($encoding, 'UTF-8', $request);
197
}
198
$request = json_decode($request);
199
if ($request == NULL) { // parse error
200
$error = json_error();
201
throw new JsonRpcExeption(101, "Parse Error: $error");
202
}
203
return $request;
204
}
205
// ----------------------------------------------------------------------------
206
function handle_json_rpc($object) {
207
try {
208
$input = get_json_request();
209
210
header('Content-Type: application/json');
211
212
$method = get_field($input, 'method', null);
213
$params = get_field($input, 'params', null);
214
$id = intval(get_field($input, 'id', null));
215
216
// json rpc error
217
if (!($method && $id)) {
218
if (!$id) {
219
$id = extract_id();
220
}
221
if (!$method) {
222
$error = "no method";
223
} else if (!$id) {
224
$error = "no id";
225
} else {
226
$error = "unknown reason";
227
}
228
throw new JsonRpcExeption(103, "Invalid Request: $error");
229
//": " . $GLOBALS['HTTP_RAW_POST_DATA']));
230
}
231
232
// fix params (if params is null set it to empty array)
233
if (!$params) {
234
$params = array();
235
}
236
// if params is object change it to array
237
if (is_object($params)) {
238
if (count(get_object_vars($params)) == 0) {
239
$params = array();
240
} else {
241
$params = get_object_vars($params);
242
}
243
}
244
245
// call Service Method
246
$class = get_class($object);
247
$methods = get_class_methods($class);
248
if (strcmp($method, "system.describe") == 0) {
249
echo json_encode(service_description($object));
250
} else if (!in_array($method, $methods) && !in_array("__call", $methods)) {
251
// __call will be called for any method that's missing
252
$msg = "Procedure `" . $method . "' not found";
253
throw new JsonRpcExeption(104, $msg);
254
} else {
255
if (in_array("__call", $methods) && !in_array($method, $methods)) {
256
$result = call_user_func_array(array($object, $method), $params);
257
echo response($result, $id, null);
258
} else {
259
$method_object = new ReflectionMethod($class, $method);
260
$num_got = count($params);
261
$num_expect = $method_object->getNumberOfParameters();
262
if ($num_got != $num_expect) {
263
$msg = "Wrong number of parameters. Got $num_got expect $num_expect";
264
throw new JsonRpcExeption(105, $msg);
265
} else {
266
//throw new Exception('x -> ' . json_encode($params));
267
$result = call_user_func_array(array($object, $method), $params);
268
echo response($result, $id, null);
269
}
270
}
271
}
272
} catch (JsonRpcExeption $e) {
273
// exteption with error code
274
$msg = $e->getMessage();
275
$code = $e->code();
276
if ($code = 101) { // parse error;
277
$id = extract_id();
278
}
279
echo response(null, $id, array("code"=>$code, "message"=>$msg));
280
} catch (Exception $e) {
281
//catch all exeption from user code
282
$msg = $e->getMessage();
283
echo response(null, $id, array("code"=>200, "message"=>$msg));
284
}
285
ob_end_flush();
286
}
287
288
?>
289
290