1<?php 2 3namespace dokuwiki\Remote; 4 5/** 6 * Provide the Remote XMLRPC API as a JSON based API 7 */ 8class JsonRpcServer 9{ 10 11 protected $remote; 12 13 /** 14 * JsonRpcServer constructor. 15 */ 16 public function __construct() 17 { 18 $this->remote = new Api(); 19 $this->remote->setFileTransformation(array($this, 'toFile')); 20 } 21 22 /** 23 * Serve the request 24 * 25 * @return mixed 26 * @throws RemoteException 27 */ 28 public function serve() 29 { 30 global $conf; 31 global $INPUT; 32 33 if (!$conf['remote']) { 34 http_status(404); 35 throw new RemoteException("JSON-RPC server not enabled.", -32605); 36 } 37 if (!empty($conf['remotecors'])) { 38 header('Access-Control-Allow-Origin: ' . $conf['remotecors']); 39 } 40 if ($INPUT->server->str('REQUEST_METHOD') !== 'POST') { 41 http_status(405); 42 header('Allow: POST'); 43 throw new RemoteException("JSON-RPC server only accepts POST requests.", -32606); 44 } 45 if ($INPUT->server->str('CONTENT_TYPE') !== 'application/json') { 46 http_status(415); 47 throw new RemoteException("JSON-RPC server only accepts application/json requests.", -32606); 48 } 49 50 $call = $INPUT->server->str('PATH_INFO'); 51 $call = trim($call, '/'); 52 try { 53 $args = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR); 54 } catch (\Exception $e) { 55 $args = []; 56 } 57 if (!is_array($args)) $args = []; 58 59 return $this->call($call, $args); 60 } 61 62 /** 63 * Call an API method 64 * 65 * @param string $methodname 66 * @param array $args 67 * @return mixed 68 * @throws RemoteException 69 */ 70 public function call($methodname, $args) 71 { 72 try { 73 $result = $this->remote->call($methodname, $args); 74 return $result; 75 } catch (AccessDeniedException $e) { 76 if (!isset($_SERVER['REMOTE_USER'])) { 77 http_status(401); 78 throw new RemoteException("server error. not authorized to call method $methodname", -32603); 79 } else { 80 http_status(403); 81 throw new RemoteException("server error. forbidden to call the method $methodname", -32604); 82 } 83 } catch (RemoteException $e) { 84 http_status(400); 85 throw $e; 86 } 87 } 88 89 /** 90 * @param string $data 91 * @return string 92 */ 93 public function toFile($data) 94 { 95 return base64_encode($data); 96 } 97 98} 99