| 1 |
<?php
|
| 2 |
/**
|
| 3 |
* @author Ma Bingyao(andot@ujn.edu.cn)
|
| 4 |
* @copyright CoolCode.CN
|
| 5 |
* @package PHP_PHPRPC_SERVER
|
| 6 |
* @version 2.1
|
| 7 |
* @last_update 2006-08-10
|
| 8 |
* @link http://www.coolcode.cn/?p=143
|
| 9 |
*
|
| 10 |
* Example usage:
|
| 11 |
*
|
| 12 |
* server.php
|
| 13 |
* <?php
|
| 14 |
* include('phprpc_server.php');
|
| 15 |
* function add($a, $b) {
|
| 16 |
* return $a + $b;
|
| 17 |
* }
|
| 18 |
* function sub($a, $b) {
|
| 19 |
* return $a - $b;
|
| 20 |
* }
|
| 21 |
* new phprpc_server(array('add', 'sub'));
|
| 22 |
* ?>
|
| 23 |
*/
|
| 24 |
|
| 25 |
if (!function_exists("ob_get_clean")) {
|
| 26 |
function ob_get_clean() {
|
| 27 |
$ob_contents = ob_get_contents();
|
| 28 |
while(ob_get_length() !== false) @ob_end_clean();
|
| 29 |
return $ob_contents;
|
| 30 |
}
|
| 31 |
}
|
| 32 |
|
| 33 |
@ob_start();
|
| 34 |
|
| 35 |
class phprpc_server {
|
| 36 |
var $callback;
|
| 37 |
var $encode;
|
| 38 |
var $ref;
|
| 39 |
var $encrypt;
|
| 40 |
var $debug;
|
| 41 |
var $errno;
|
| 42 |
var $errstr;
|
| 43 |
var $functions;
|
| 44 |
function tolower(&$func, $keys) {
|
| 45 |
$func = strtolower($func);
|
| 46 |
}
|
| 47 |
function addjsslashes($str, $flag = true) {
|
| 48 |
if ($flag) {
|
| 49 |
$str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134\177..\377");
|
| 50 |
}
|
| 51 |
else {
|
| 52 |
$str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134");
|
| 53 |
}
|
| 54 |
return str_replace(array(chr(7), chr(11)), array('\007', '\013'), $str);
|
| 55 |
}
|
| 56 |
function error_handler($errno, $errstr, $errfile, $errline) {
|
| 57 |
if ($this->debug) {
|
| 58 |
$errstr .= "\nfile: $errfile\nline: $errline";
|
| 59 |
}
|
| 60 |
if (($errno == E_ERROR) or ($errno == E_CORE_ERROR) or
|
| 61 |
($errno == E_COMPILE_ERROR) or ($errno == E_USER_ERROR)) {
|
| 62 |
$output = ob_get_clean();
|
| 63 |
echo "phprpc_errno=\"$errno\";\r\n";
|
| 64 |
if ($this->encode) {
|
| 65 |
echo "phprpc_errstr=\"" . base64_encode($errstr) . "\";\r\n";
|
| 66 |
echo "phprpc_output=\"" . base64_encode($output) . "\";\r\n";
|
| 67 |
}
|
| 68 |
else {
|
| 69 |
echo "phprpc_errstr=\"" . $this->addjsslashes($errstr, false) . "\";\r\n";
|
| 70 |
echo "phprpc_output=\"" . $this->addjsslashes($output, false) . "\";\r\n";
|
| 71 |
}
|
| 72 |
echo $this->callback;
|
| 73 |
exit();
|
| 74 |
}
|
| 75 |
else {
|
| 76 |
if (($errno == E_NOTICE) or ($errno == E_USER_NOTICE)) {
|
| 77 |
if ($this->errno == 0) {
|
| 78 |
$this->errno = $errno;
|
| 79 |
$this->errstr = $errstr;
|
| 80 |
}
|
| 81 |
}
|
| 82 |
else {
|
| 83 |
if (($this->errno == 0) or
|
| 84 |
($this->errno == E_NOTICE) or
|
| 85 |
($this->errno == E_USER_NOTICE)) {
|
| 86 |
$this->errno = $errno;
|
| 87 |
$this->errstr = $errstr;
|
| 88 |
}
|
| 89 |
}
|
| 90 |
}
|
| 91 |
return true;
|
| 92 |
}
|
| 93 |
function call($function, &$args) {
|
| 94 |
$arguments = array();
|
| 95 |
for ($i = 0; $i < count($args); $i++) {
|
| 96 |
$arguments[$i] = &$args[$i];
|
| 97 |
}
|
| 98 |
return call_user_func_array($function, $arguments);
|
| 99 |
}
|
| 100 |
function get_request($name) {
|
| 101 |
$result = $_REQUEST[$name];
|
| 102 |
if (get_magic_quotes_gpc()) {
|
| 103 |
$result = stripslashes($result);
|
| 104 |
}
|
| 105 |
return $result;
|
| 106 |
}
|
| 107 |
function phprpc_server($functions = null, $debug = false, $obj = null, $charset = "utf-8") {
|
| 108 |
$this->functions = array();
|
| 109 |
if ($functions != null) {
|
| 110 |
$this->add($functions, $obj);
|
| 111 |
$this->start($debug, $charset);
|
| 112 |
}
|
| 113 |
}
|
| 114 |
function add($functions, $obj = null) {
|
| 115 |
if ($functions == null) return false;
|
| 116 |
if (is_string($functions)) {
|
| 117 |
$functions = array($functions);
|
| 118 |
}
|
| 119 |
$this->functions[] = array('functions' => $functions, 'obj' => $obj);
|
| 120 |
return true;
|
| 121 |
}
|
| 122 |
function start($debug = false, $charset = "utf-8") {
|
| 123 |
while(ob_get_length() !== false) @ob_end_clean();
|
| 124 |
@ob_start();
|
| 125 |
header("Content-Type: text/plain; charset=$charset");
|
| 126 |
header("X-Powered-By: PHPRPC Server/2.1");
|
| 127 |
header("Date: " . gmdate("D, d M Y H:i:s") . " GMT");
|
| 128 |
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
|
| 129 |
header('Cache-Control: no-store, no-cache, must-revalidate');
|
| 130 |
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
|
| 131 |
header('Content-Encoding: none');
|
| 132 |
$this->debug = $debug;
|
| 133 |
$this->encode = true;
|
| 134 |
if (isset($_REQUEST['phprpc_encode'])) {
|
| 135 |
$this->encode = strtolower($this->get_request('phprpc_encode'));
|
| 136 |
if ($this->encode == "false") {
|
| 137 |
$this->encode = false;
|
| 138 |
}
|
| 139 |
}
|
| 140 |
if (isset($_REQUEST['phprpc_callback'])) {
|
| 141 |
$this->callback = base64_decode($this->get_request('phprpc_callback'));
|
| 142 |
}
|
| 143 |
else {
|
| 144 |
$this->callback = "";
|
| 145 |
}
|
| 146 |
$this->ref = true;
|
| 147 |
if (isset($_REQUEST['phprpc_ref'])) {
|
| 148 |
$this->ref = strtolower($this->get_request('phprpc_ref'));
|
| 149 |
if ($this->ref == "false") {
|
| 150 |
$this->ref = false;
|
| 151 |
}
|
| 152 |
}
|
| 153 |
$this->errno = 0;
|
| 154 |
$this->errstr = "";
|
| 155 |
error_reporting(0);
|
| 156 |
set_error_handler(array(&$this, 'error_handler'));
|
| 157 |
|
| 158 |
$this->encrypt = false;
|
| 159 |
if (isset($_REQUEST['phprpc_encrypt'])) {
|
| 160 |
$this->encrypt = $this->get_request('phprpc_encrypt');
|
| 161 |
if ($this->encrypt === "true") $this->encrypt = true;
|
| 162 |
if ($this->encrypt === "false") $this->encrypt = false;
|
| 163 |
if ($this->encrypt != false) {
|
| 164 |
require_once('keypair.php');
|
| 165 |
if (!extension_loaded('xxtea')) {
|
| 166 |
require_once('xxtea.php');
|
| 167 |
}
|
| 168 |
session_start();
|
| 169 |
}
|
| 170 |
}
|
| 171 |
|
| 172 |
$functions = array();
|
| 173 |
$obj = array();
|
| 174 |
foreach ($this->functions as $value) {
|
| 175 |
foreach ($value['functions'] as $function) {
|
| 176 |
$functions[] = $function;
|
| 177 |
$objects[] = $value['obj'];
|
| 178 |
}
|
| 179 |
}
|
| 180 |
if (isset($_REQUEST['phprpc_func'])) {
|
| 181 |
array_walk($functions, array(&$this, 'tolower'));
|
| 182 |
$function = strtolower($this->get_request('phprpc_func'));
|
| 183 |
if (in_array($function, $functions)) {
|
| 184 |
if (isset($_REQUEST['phprpc_args'])) {
|
| 185 |
$arguments = base64_decode($this->get_request('phprpc_args'));
|
| 186 |
if ($this->encrypt > 0) {
|
| 187 |
if (isset($_SESSION['PHPRPC_ENCRYPT']['k'])) {
|
| 188 |
$arguments = xxtea_decrypt($arguments, $_SESSION['PHPRPC_ENCRYPT']['k']);
|
| 189 |
}
|
| 190 |
else {
|
| 191 |
$this->errno = E_ERROR;
|
| 192 |
$this->errstr = "Can't find the key for decryption.";
|
| 193 |
}
|
| 194 |
}
|
| 195 |
$arguments = unserialize($arguments);
|
| 196 |
}
|
| 197 |
else {
|
| 198 |
$arguments = array();
|
| 199 |
}
|
| 200 |
$obj = $objects[array_search($function, $functions)];
|
| 201 |
if ($obj != null && $obj != "") {
|
| 202 |
if (is_object($obj)) {
|
| 203 |
$function = array(&$obj, $function);
|
| 204 |
}
|
| 205 |
else if (is_string($obj)) {
|
| 206 |
$function = array($obj, $function);
|
| 207 |
}
|
| 208 |
}
|
| 209 |
if ($this->ref) {
|
| 210 |
$result = serialize($this->call($function, $arguments));
|
| 211 |
$arguments = serialize($arguments);
|
| 212 |
}
|
| 213 |
else {
|
| 214 |
$result = serialize(call_user_func_array($function, $arguments));
|
| 215 |
}
|
| 216 |
if ($this->encrypt > 0) {
|
| 217 |
if (isset($_SESSION['PHPRPC_ENCRYPT']['k'])) {
|
| 218 |
if ($this->encrypt > 1) {
|
| 219 |
$result = xxtea_encrypt($result, $_SESSION['PHPRPC_ENCRYPT']['k']);
|
| 220 |
}
|
| 221 |
if ($this->ref) {
|
| 222 |
$arguments = xxtea_encrypt($arguments, $_SESSION['PHPRPC_ENCRYPT']['k']);
|
| 223 |
}
|
| 224 |
}
|
| 225 |
else {
|
| 226 |
$this->errno = E_ERROR;
|
| 227 |
$this->errstr = "Can't find the key for encryption.";
|
| 228 |
}
|
| 229 |
}
|
| 230 |
if ($this->encode) {
|
| 231 |
$result = base64_encode($result);
|
| 232 |
if ($this->ref) {
|
| 233 |
$arguments = base64_encode($arguments);
|
| 234 |
}
|
| 235 |
}
|
| 236 |
else {
|
| 237 |
$result = $this->addjsslashes($result);
|
| 238 |
if ($this->ref) {
|
| 239 |
$arguments = $this->addjsslashes($arguments);
|
| 240 |
}
|
| 241 |
}
|
| 242 |
}
|
| 243 |
else {
|
| 244 |
$this->errno = E_ERROR;
|
| 245 |
$this->errstr = "Can't find this function $function().";
|
| 246 |
}
|
| 247 |
$output = ob_get_clean();
|
| 248 |
if ($this->errno != E_ERROR) {
|
| 249 |
echo "phprpc_result=\"$result\";\r\n";
|
| 250 |
if ($this->ref) {
|
| 251 |
echo "phprpc_args=\"$arguments\";\r\n";
|
| 252 |
}
|
| 253 |
}
|
| 254 |
echo "phprpc_errno=\"{$this->errno}\";\r\n";
|
| 255 |
if ($this->encode) {
|
| 256 |
echo "phprpc_errstr=\"" . base64_encode($this->errstr) . "\";\r\n";
|
| 257 |
echo "phprpc_output=\"" . base64_encode($output) . "\";\r\n";
|
| 258 |
}
|
| 259 |
else {
|
| 260 |
echo "phprpc_errstr=\"" . $this->addjsslashes($this->errstr, false) ."\";\r\n";
|
| 261 |
echo "phprpc_output=\"" . $this->addjsslashes($output, false) . "\";\r\n";
|
| 262 |
}
|
| 263 |
}
|
| 264 |
else {
|
| 265 |
if ($this->encrypt != false) {
|
| 266 |
require_once('bcmath.php');
|
| 267 |
if (extension_loaded('big_int')) {
|
| 268 |
if ($this->encrypt === true) {
|
| 269 |
$encrypt = $phprpc_keypair[mt_rand(0, count($phprpc_keypair) - 1)];
|
| 270 |
$_SESSION['PHPRPC_ENCRYPT'] = $encrypt;
|
| 271 |
$_SESSION['PHPRPC_ENCRYPT']['x'] = bi_to_str(bi_set_bit(bi_rand(127), 126));
|
| 272 |
$encrypt['y'] = bi_to_str(bi_powmod(bi_from_str($_SESSION['PHPRPC_ENCRYPT']['g']),
|
| 273 |
bi_from_str($_SESSION['PHPRPC_ENCRYPT']['x']),
|
| 274 |
bi_from_str($_SESSION['PHPRPC_ENCRYPT']['p'])));
|
| 275 |
}
|
| 276 |
else {
|
| 277 |
$_SESSION['PHPRPC_ENCRYPT']['y'] = $this->encrypt;
|
| 278 |
$key = bcdec2str(bi_to_str(bi_powmod(bi_from_str($_SESSION['PHPRPC_ENCRYPT']['y']),
|
| 279 |
bi_from_str($_SESSION['PHPRPC_ENCRYPT']['x']),
|
| 280 |
bi_from_str($_SESSION['PHPRPC_ENCRYPT']['p']))));
|
| 281 |
$_SESSION['PHPRPC_ENCRYPT']['k'] = str_repeat("\0", 16 - strlen($key)) . $key;
|
| 282 |
$encrypt = true;
|
| 283 |
}
|
| 284 |
}
|
| 285 |
else {
|
| 286 |
if ($this->encrypt === true) {
|
| 287 |
$encrypt = $phprpc_keypair[mt_rand(0, count($phprpc_keypair) - 1)];
|
| 288 |
$_SESSION['PHPRPC_ENCRYPT'] = $encrypt;
|
| 289 |
$_SESSION['PHPRPC_ENCRYPT']['x'] = bcrand(127, 1);
|
| 290 |
$encrypt['y'] = bcpowmod($_SESSION['PHPRPC_ENCRYPT']['g'],
|
| 291 |
$_SESSION['PHPRPC_ENCRYPT']['x'],
|
| 292 |
$_SESSION['PHPRPC_ENCRYPT']['p']);
|
| 293 |
}
|
| 294 |
else {
|
| 295 |
$_SESSION['PHPRPC_ENCRYPT']['y'] = $this->encrypt;
|
| 296 |
$key = bcdec2str(bcpowmod($_SESSION['PHPRPC_ENCRYPT']['y'],
|
| 297 |
$_SESSION['PHPRPC_ENCRYPT']['x'],
|
| 298 |
$_SESSION['PHPRPC_ENCRYPT']['p']));
|
| 299 |
$_SESSION['PHPRPC_ENCRYPT']['k'] = str_repeat("\0", 16 - strlen($key)) . $key;
|
| 300 |
$encrypt = true;
|
| 301 |
}
|
| 302 |
}
|
| 303 |
if ($this->encode) {
|
| 304 |
echo "phprpc_encrypt=\"" . base64_encode(serialize($encrypt)) . "\";\r\n";
|
| 305 |
}
|
| 306 |
else {
|
| 307 |
echo "phprpc_encrypt=\"" . $this->addjsslashes(serialize($encrypt)) . "\";\r\n";
|
| 308 |
}
|
| 309 |
}
|
| 310 |
if ($this->encode) {
|
| 311 |
echo "phprpc_functions=\"" . base64_encode(serialize($functions)) . "\";\r\n";
|
| 312 |
}
|
| 313 |
else {
|
| 314 |
echo "phprpc_functions=\"" . $this->addjsslashes(serialize($functions)) . "\";\r\n";
|
| 315 |
}
|
| 316 |
}
|
| 317 |
echo $this->callback;
|
| 318 |
restore_error_handler();
|
| 319 |
ob_end_flush();
|
| 320 |
}
|
| 321 |
}
|
| 322 |
?>
|