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