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