3 Minimal raw RPC query support over HTTP. All variables are simply
4 serialized() and then transmitted, minimal access permission checks
5 are done (there is a $phprpc_methods like with the xmlrpc lib).
8 define("PHPRPC_VERSION", 1);
9 define("PHPRPC_TYPE", "application/vnd.php.serialized");
10 @$ewiki_config["ua"] .= " phprpc/1";
14 function phprpc($url, $func, $args) {
15 global $ewiki_config, $phprpc_error;
19 "methodName" => $func,
22 $args = serialize($args);
23 $args = gzdeflate($args);
24 $len_args = strlen($args);
26 #-- prepare HTTP request
29 ($port) || ($port=80);
30 ($query) && ($path .= "?$query");
32 $req = "POST $path HTTP/1.0$n"
34 . ($user ? "Authorization: Basic ".base64_encode("$user:$pass").$n : "")
35 . "User-Agent: $ewiki_config[ua]$n"
36 . "Accept-Encoding: deflate$n"
37 . "Connection: close$n"
38 . "Accept: ".PHPRPC_TYPE."$n"
39 . "Content-Type: ".PHPRPC_TYPE."; version=".PHP_VERSION."$n"
43 if ($f = fsockopen($host, $port, $io_err, $io_err_s, 20)) {
44 socket_set_blocking($f, true);
45 socket_set_timeout($f, 17, 555);
49 fwrite($f, "Content-Length: $len_args$n");
51 fwrite($f, $args); $args = ""; //freemem()
57 $result .= fread($f, 1<<21); // max 2MB (incl. headers)
61 while ($p = strpos($result, "\n")) {
62 $line = trim(substr($result, 0, $p));
63 $result = substr($result, $p + 1);
67 $h[strtolower(strtok($line, ":"))] = trim(strtok("\000"));
74 if (strtolower(trim(strtok($h["content-type"], ";"))) == PHPRPC_TYPE) {
75 if ($h["content-encoding"] == "gzip") {
76 $result = gzinflate(substr($result, 10, strlen($result)-18));
78 if ($h["content-encoding"] == "deflate") {
79 $result = gzinflate($result);
81 $result = unserialize($result);
89 } else { $phprpc_error = "no socket/connection"; } //socket
95 function phprpc_server($allowed="*") {
97 global $phprpc_methods, $ewiki_config, $HTTP_RAW_POST_DATA;
98 if ($phprpc_methods) {
99 $allowed = $phprpc_methods;
102 if (($_SERVER["REQUEST_METHOD"] == "POST")
103 and (strtolower(trim(strtok($_SERVER["CONTENT_TYPE"], ";"))) == PHPRPC_TYPE))
106 if ($f = fopen("php://input", "rb")) {
107 $HTTP_RAW_POST_DATA = fread($f, 1<<21); // 2MB max (packed)
110 $call = unserialize(gzinflate($HTTP_RAW_POST_DATA));
112 #-- make function call
113 if (is_array($call)) {
116 ($method = $call["method"]) || ($method = $call["func"]) || ($method = $call["function"]) || ($method = $call["methodName"]);
117 ($args = $call["args"]) || ($args = $call["params"]);
119 #-- plain function or static method call
120 if (strpos($method, ":") || strpos($method, ".")) {
121 $class = strtok($method, ":.");
122 $method = trim(strtok(" "), ":");
125 $method = array($class, $method);
129 if (($allowed=="*") || in_array(strtolower($method), $allowed)
130 || in_array(strtolower($class), $allowed)
131 || ($method = $allowed[strtolower($method)]))
133 $r = call_user_func_array($method, $args);
136 header("Status: 400 Forbidden Method"); exit;
140 header("Status: 500 Could Not Unserialize"); exit;
145 header("X-Server: $ewiki_config[ua]");
146 header("Content-Type: ".PHPRPC_TYPE."; version=".PHP_VERSION);
147 header("Cache-Control: no-cache, private");
150 header("Content-Encoding: deflate");
151 header("Content-Length: ".strlen($r));
157 header("Status: 500 Didn't Work");
161 header("X-PHP-RPC-Error: Wrong request method $_SERVER[REQUEST_METHOD] and/or type $_SERVER[CONTENT_TYPE]");