PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/xianpipa/ThinkPHP/Library/Vendor/phpRPC/phprpc_server.php

https://gitlab.com/fangfangchen/xianpipa
PHP | 496 lines | 440 code | 4 blank | 52 comment | 100 complexity | b261a5b70b0dcff8d09d390b857319eb MD5 | raw file
  1. <?php
  2. /**********************************************************\
  3. | |
  4. | The implementation of PHPRPC Protocol 3.0 |
  5. | |
  6. | phprpc_server.php |
  7. | |
  8. | Release 3.0.1 |
  9. | Copyright by Team-PHPRPC |
  10. | |
  11. | WebSite: http://www.phprpc.org/ |
  12. | http://www.phprpc.net/ |
  13. | http://www.phprpc.com/ |
  14. | http://sourceforge.net/projects/php-rpc/ |
  15. | |
  16. | Authors: Ma Bingyao <andot@ujn.edu.cn> |
  17. | |
  18. | This file may be distributed and/or modified under the |
  19. | terms of the GNU General Public License (GPL) version |
  20. | 2.0 as published by the Free Software Foundation and |
  21. | appearing in the included file LICENSE. |
  22. | |
  23. \**********************************************************/
  24. /* PHPRPC Server for PHP.
  25. *
  26. * Copyright: Ma Bingyao <andot@ujn.edu.cn>
  27. * Version: 3.0
  28. * LastModified: Apr 12, 2010
  29. * This library is free. You can redistribute it and/or modify it under GPL.
  30. *
  31. /*
  32. * Interfaces
  33. *
  34. * function add($a, $b) {
  35. * return $a + $b;
  36. * }
  37. * function sub($a, $b) {
  38. * return $a - $b;
  39. * }
  40. * function inc(&$n) {
  41. * return $n++;
  42. * }
  43. * include('phprpc_server.php');
  44. * $server = new PHPRPC_Server();
  45. * $server->add(array('add', 'sub'));
  46. * $server->add('inc');
  47. * $server->setCharset('UTF-8');
  48. * $server->setDebugMode(true);
  49. * $server->start();
  50. *
  51. */
  52. class PHPRPC_Server {
  53. var $callback;
  54. var $charset;
  55. var $encode;
  56. var $ref;
  57. var $encrypt;
  58. var $enableGZIP;
  59. var $debug;
  60. var $keylen;
  61. var $key;
  62. var $errno;
  63. var $errstr;
  64. var $functions;
  65. var $cid;
  66. var $buffer;
  67. // Private Methods
  68. function addJsSlashes($str, $flag) {
  69. if ($flag) {
  70. $str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134\177..\377");
  71. }
  72. else {
  73. $str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134\177");
  74. }
  75. return str_replace(array(chr(7), chr(11)), array('\007', '\013'), $str);
  76. }
  77. function encodeString($str, $flag = true) {
  78. if ($this->encode) {
  79. return base64_encode($str);
  80. }
  81. else {
  82. return $this->addJsSlashes($str, $flag);
  83. }
  84. }
  85. function encryptString($str, $level) {
  86. if ($this->encrypt >= $level) {
  87. $str = xxtea_encrypt($str, $this->key);
  88. }
  89. return $str;
  90. }
  91. function decryptString($str, $level) {
  92. if ($this->encrypt >= $level) {
  93. $str = xxtea_decrypt($str, $this->key);
  94. }
  95. return $str;
  96. }
  97. function sendHeader() {
  98. header("HTTP/1.1 200 OK");
  99. header("Content-Type: text/plain; charset={$this->charset}");
  100. header("X-Powered-By: PHPRPC Server/3.0");
  101. header('P3P: CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"');
  102. header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
  103. header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
  104. }
  105. function getRequestURL() {
  106. if (!isset($_SERVER['HTTPS']) ||
  107. $_SERVER['HTTPS'] == 'off' ||
  108. $_SERVER['HTTPS'] == '') {
  109. $scheme = 'http';
  110. }
  111. else {
  112. $scheme = 'https';
  113. }
  114. $host = $_SERVER['SERVER_NAME'];
  115. $port = $_SERVER['SERVER_PORT'];
  116. $path = $_SERVER['SCRIPT_NAME'];
  117. return $scheme . '://' . $host . (($port == 80) ? '' : ':' . $port) . $path;
  118. }
  119. function sendURL() {
  120. if (SID != "") {
  121. $url = $this->getRequestURL();
  122. if (count($_GET) > 0) {
  123. $url .= '?' . strip_tags(SID);
  124. foreach ($_GET as $key => $value) {
  125. if (strpos(strtolower($key), 'phprpc_') !== 0) {
  126. $url .= '&' . $key . '=' . urlencode($value);
  127. }
  128. }
  129. }
  130. $this->buffer .= "phprpc_url=\"" . $this->encodeString($url) . "\";\r\n";
  131. }
  132. }
  133. function gzip($buffer) {
  134. $len = strlen($buffer);
  135. if ($this->enableGZIP && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip,deflate')) {
  136. $gzbuffer = gzencode($buffer);
  137. $gzlen = strlen($gzbuffer);
  138. if ($len > $gzlen) {
  139. header("Content-Length: $gzlen");
  140. header("Content-Encoding: gzip");
  141. return $gzbuffer;
  142. }
  143. }
  144. header("Content-Length: $len");
  145. return $buffer;
  146. }
  147. function sendCallback() {
  148. $this->buffer .= $this->callback;
  149. echo $this->gzip($this->buffer);
  150. ob_end_flush();
  151. restore_error_handler();
  152. if (function_exists('restore_exception_handler')) {
  153. restore_exception_handler();
  154. }
  155. exit();
  156. }
  157. function sendFunctions() {
  158. $this->buffer .= "phprpc_functions=\"" . $this->encodeString(serialize_fix(array_keys($this->functions))) . "\";\r\n";
  159. $this->sendCallback();
  160. }
  161. function sendOutput($output) {
  162. if ($this->encrypt >= 3) {
  163. $this->buffer .= "phprpc_output=\"" . $this->encodeString(xxtea_encrypt($output, $this->key)) . "\";\r\n";
  164. }
  165. else {
  166. $this->buffer .= "phprpc_output=\"" . $this->encodeString($output, false) . "\";\r\n";
  167. }
  168. }
  169. function sendError($output = NULL) {
  170. if (is_null($output)) {
  171. $output = ob_get_clean();
  172. }
  173. $this->buffer .= "phprpc_errno=\"{$this->errno}\";\r\n";
  174. $this->buffer .= "phprpc_errstr=\"" . $this->encodeString($this->errstr, false) . "\";\r\n";
  175. $this->sendOutput($output);
  176. $this->sendCallback();
  177. }
  178. function fatalErrorHandler($buffer) {
  179. if (preg_match('/<b>(.*?) error<\/b>:(.*?)<br/', $buffer, $match)) {
  180. if ($match[1] == 'Fatal') {
  181. $errno = E_ERROR;
  182. }
  183. else {
  184. $errno = E_COMPILE_ERROR;
  185. }
  186. if ($this->debug) {
  187. $errstr = preg_replace('/<.*?>/', '', $match[2]);
  188. }
  189. else {
  190. $errstr = preg_replace('/ in <b>.*<\/b>$/', '', $match[2]);
  191. }
  192. $buffer = "phprpc_errno=\"{$errno}\";\r\n" .
  193. "phprpc_errstr=\"" . $this->encodeString(trim($errstr), false) . "\";\r\n" .
  194. "phprpc_output=\"\";\r\n" .
  195. $this->callback;
  196. $buffer = $this->gzip($buffer);
  197. }
  198. return $buffer;
  199. }
  200. function errorHandler($errno, $errstr, $errfile, $errline) {
  201. if ($this->debug) {
  202. $errstr .= " in $errfile on line $errline";
  203. }
  204. if (($errno == E_ERROR) or ($errno == E_CORE_ERROR) or
  205. ($errno == E_COMPILE_ERROR) or ($errno == E_USER_ERROR)) {
  206. $this->errno = $errno;
  207. $this->errstr = $errstr;
  208. $this->sendError();
  209. }
  210. else {
  211. if (($errno == E_NOTICE) or ($errno == E_USER_NOTICE)) {
  212. if ($this->errno == 0) {
  213. $this->errno = $errno;
  214. $this->errstr = $errstr;
  215. }
  216. }
  217. else {
  218. if (($this->errno == 0) or
  219. ($this->errno == E_NOTICE) or
  220. ($this->errno == E_USER_NOTICE)) {
  221. $this->errno = $errno;
  222. $this->errstr = $errstr;
  223. }
  224. }
  225. }
  226. return true;
  227. }
  228. function exceptionHandler($exception) {
  229. $this->errno = $exception->getCode();
  230. $this->errstr = $exception->getMessage();
  231. if ($this->debug) {
  232. $this->errstr .= "\nfile: " . $exception->getFile() .
  233. "\nline: " . $exception->getLine() .
  234. "\ntrace: " . $exception->getTraceAsString();
  235. }
  236. $this->sendError();
  237. }
  238. function initErrorHandler() {
  239. $this->errno = 0;
  240. $this->errstr = "";
  241. set_error_handler(array(&$this, 'errorHandler'));
  242. if (function_exists('set_exception_handler')) {
  243. set_exception_handler(array(&$this, 'exceptionHandler'));
  244. }
  245. }
  246. function call($function, &$args) {
  247. if ($this->ref) {
  248. $arguments = array();
  249. for ($i = 0; $i < count($args); $i++) {
  250. $arguments[$i] = &$args[$i];
  251. }
  252. }
  253. else {
  254. $arguments = $args;
  255. }
  256. return call_user_func_array($function, $arguments);
  257. }
  258. function getRequest($name) {
  259. $result = $_REQUEST[$name];
  260. if (get_magic_quotes_gpc()) {
  261. $result = stripslashes($result);
  262. }
  263. return $result;
  264. }
  265. function getBooleanRequest($name) {
  266. $var = true;
  267. if (isset($_REQUEST[$name])) {
  268. $var = strtolower($this->getRequest($name));
  269. if ($var == "false") {
  270. $var = false;
  271. }
  272. }
  273. return $var;
  274. }
  275. function initEncode() {
  276. $this->encode = $this->getBooleanRequest('phprpc_encode');
  277. }
  278. function initRef() {
  279. $this->ref = $this->getBooleanRequest('phprpc_ref');
  280. }
  281. function initCallback() {
  282. if (isset($_REQUEST['phprpc_callback'])) {
  283. $this->callback = base64_decode($this->getRequest('phprpc_callback'));
  284. }
  285. else {
  286. $this->callback = "";
  287. }
  288. }
  289. function initKeylen() {
  290. if (isset($_REQUEST['phprpc_keylen'])) {
  291. $this->keylen = (int)$this->getRequest('phprpc_keylen');
  292. }
  293. else if (isset($_SESSION[$this->cid])) {
  294. $session = unserialize(base64_decode($_SESSION[$this->cid]));
  295. if (isset($session['keylen'])) {
  296. $this->keylen = $session['keylen'];
  297. }
  298. else {
  299. $this->keylen = 128;
  300. }
  301. }
  302. else {
  303. $this->keylen = 128;
  304. }
  305. }
  306. function initClientID() {
  307. $this->cid = 0;
  308. if (isset($_REQUEST['phprpc_id'])) {
  309. $this->cid = $this->getRequest('phprpc_id');
  310. }
  311. $this->cid = "phprpc_" . $this->cid;
  312. }
  313. function initEncrypt() {
  314. $this->encrypt = false;
  315. if (isset($_REQUEST['phprpc_encrypt'])) {
  316. $this->encrypt = $this->getRequest('phprpc_encrypt');
  317. if ($this->encrypt === "true") $this->encrypt = true;
  318. if ($this->encrypt === "false") $this->encrypt = false;
  319. }
  320. }
  321. function initKey() {
  322. if ($this->encrypt == 0) {
  323. return;
  324. }
  325. else if (isset($_SESSION[$this->cid])) {
  326. $session = unserialize(base64_decode($_SESSION[$this->cid]));
  327. if (isset($session['key'])) {
  328. $this->key = $session['key'];
  329. require_once('xxtea.php');
  330. return;
  331. }
  332. }
  333. $this->errno = E_ERROR;
  334. $this->errstr = "Can't find the key for decryption.";
  335. $this->encrypt = 0;
  336. $this->sendError();
  337. }
  338. function getArguments() {
  339. if (isset($_REQUEST['phprpc_args'])) {
  340. $arguments = unserialize($this->decryptString(base64_decode($this->getRequest('phprpc_args')), 1));
  341. ksort($arguments);
  342. }
  343. else {
  344. $arguments = array();
  345. }
  346. return $arguments;
  347. }
  348. function callFunction() {
  349. $this->initKey();
  350. $function = strtolower($this->getRequest('phprpc_func'));
  351. if (array_key_exists($function, $this->functions)) {
  352. $function = $this->functions[$function];
  353. $arguments = $this->getArguments();
  354. $result = $this->encodeString($this->encryptString(serialize_fix($this->call($function, $arguments)), 2));
  355. $output = ob_get_clean();
  356. $this->buffer .= "phprpc_result=\"$result\";\r\n";
  357. if ($this->ref) {
  358. $arguments = $this->encodeString($this->encryptString(serialize_fix($arguments), 1));
  359. $this->buffer .= "phprpc_args=\"$arguments\";\r\n";
  360. }
  361. }
  362. else {
  363. $this->errno = E_ERROR;
  364. $this->errstr = "Can't find this function $function().";
  365. $output = ob_get_clean();
  366. }
  367. $this->sendError($output);
  368. }
  369. function keyExchange() {
  370. require_once('bigint.php');
  371. $this->initKeylen();
  372. if (isset($_SESSION[$this->cid])) {
  373. $session = unserialize(base64_decode($_SESSION[$this->cid]));
  374. }
  375. else {
  376. $session = array();
  377. }
  378. if ($this->encrypt === true) {
  379. require_once('dhparams.php');
  380. $DHParams = new DHParams($this->keylen);
  381. $this->keylen = $DHParams->getL();
  382. $encrypt = $DHParams->getDHParams();
  383. $x = bigint_random($this->keylen - 1, true);
  384. $session['x'] = bigint_num2dec($x);
  385. $session['p'] = $encrypt['p'];
  386. $session['keylen'] = $this->keylen;
  387. $encrypt['y'] = bigint_num2dec(bigint_powmod(bigint_dec2num($encrypt['g']), $x, bigint_dec2num($encrypt['p'])));
  388. $this->buffer .= "phprpc_encrypt=\"" . $this->encodeString(serialize_fix($encrypt)) . "\";\r\n";
  389. if ($this->keylen != 128) {
  390. $this->buffer .= "phprpc_keylen=\"{$this->keylen}\";\r\n";
  391. }
  392. $this->sendURL();
  393. }
  394. else {
  395. $y = bigint_dec2num($this->encrypt);
  396. $x = bigint_dec2num($session['x']);
  397. $p = bigint_dec2num($session['p']);
  398. $key = bigint_powmod($y, $x, $p);
  399. if ($this->keylen == 128) {
  400. $key = bigint_num2str($key);
  401. }
  402. else {
  403. $key = pack('H*', md5(bigint_num2dec($key)));
  404. }
  405. $session['key'] = str_pad($key, 16, "\0", STR_PAD_LEFT);
  406. }
  407. $_SESSION[$this->cid] = base64_encode(serialize($session));
  408. $this->sendCallback();
  409. }
  410. function initSession() {
  411. @ob_start();
  412. ob_implicit_flush(0);
  413. session_start();
  414. }
  415. function initOutputBuffer() {
  416. @ob_start(array(&$this, "fatalErrorHandler"));
  417. ob_implicit_flush(0);
  418. $this->buffer = "";
  419. }
  420. // Public Methods
  421. function PHPRPC_Server() {
  422. require_once('compat.php');
  423. $this->functions = array();
  424. $this->charset = 'UTF-8';
  425. $this->debug = false;
  426. $this->enableGZIP = false;
  427. }
  428. function add($functions, $obj = NULL, $aliases = NULL) {
  429. if (is_null($functions) || (gettype($functions) != gettype($aliases) && !is_null($aliases))) {
  430. return false;
  431. }
  432. if (is_object($functions)) {
  433. $obj = $functions;
  434. $functions = get_class_methods(get_class($obj));
  435. $aliases = $functions;
  436. }
  437. if (is_null($aliases)) {
  438. $aliases = $functions;
  439. }
  440. if (is_string($functions)) {
  441. if (is_null($obj)) {
  442. $this->functions[strtolower($aliases)] = $functions;
  443. }
  444. else if (is_object($obj)) {
  445. $this->functions[strtolower($aliases)] = array(&$obj, $functions);
  446. }
  447. else if (is_string($obj)) {
  448. $this->functions[strtolower($aliases)] = array($obj, $functions);
  449. }
  450. }
  451. else {
  452. if (count($functions) != count($aliases)) {
  453. return false;
  454. }
  455. foreach ($functions as $key => $function) {
  456. $this->add($function, $obj, $aliases[$key]);
  457. }
  458. }
  459. return true;
  460. }
  461. function setCharset($charset) {
  462. $this->charset = $charset;
  463. }
  464. function setDebugMode($debug) {
  465. $this->debug = $debug;
  466. }
  467. function setEnableGZIP($enableGZIP) {
  468. $this->enableGZIP = $enableGZIP;
  469. }
  470. function start() {
  471. while(ob_get_length() !== false) @ob_end_clean();
  472. $this->initOutputBuffer();
  473. $this->sendHeader();
  474. $this->initErrorHandler();
  475. $this->initEncode();
  476. $this->initCallback();
  477. $this->initRef();
  478. $this->initClientID();
  479. $this->initEncrypt();
  480. if (isset($_REQUEST['phprpc_func'])) {
  481. $this->callFunction();
  482. }
  483. else if ($this->encrypt != false) {
  484. $this->keyExchange();
  485. }
  486. else {
  487. $this->sendFunctions();
  488. }
  489. }
  490. }
  491. PHPRPC_Server::initSession();
  492. ?>