Commits

Toby Davies  committed 7b7b2b8

copyright

  • Participants
  • Parent commits 57d5d08

Comments (0)

Files changed (2)

File php/server.php

+<?
+/* 
+
+Copyright (c) 2011, Toby Davies
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+      
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+   
+*/
+
+
+/*
+ * JSON RPC Framework Server Side code 
+ * 
+ * calling rpcServer($functions); handles one RPC request per HTTP request. 
+ *
+ * Usage: 
+ * rpcServer(array("someRPCFunctionDefinedInThisFile"=>False,
+ *                 "someAnonFunc"=>function{ ... }, //requires PHP>=5.3.0
+ *                 "someRPCFunction"=>"some/file/defining-or-requred-by/the/RPCFunc.php", 
+ *                   ...));
+ *
+ * functions should return normal PHP values - strings/numbers/arrays/objects-and-assocs
+ * the RPC code serializes them and deserializes them as Javascript equivalents 
+ * (strings/numbers/arrays/objects respectively,
+ *  note only public members of objects will be sent to the client)
+ * it is important NOT to echo anything in an RPC func, it will break the RPC protocol format!
+ *
+ * Request Format:
+ * POST application/x-www-form-urlencoded variables:
+ *  'f' - the name of the function to be called
+ *  'a' - a JSON encoded array of arguments
+ *
+ * Response Format:
+ * {error:"Error Message As JSON Encoded String"}
+ * or
+ * {success:{some:"JSON", encoded:["object"]}
+ *
+ */
+
+//handle errors and exceptions such that they can be caught client side.
+function rpcError($errno,$errstring,$errfile=NULL,$errline=NULL){
+  if(error_reporting()){
+    die(json_encode(array('error'=>$errstring." :: $errfile @ $errline")));
+  }
+  return true;
+}
+
+//Use the associative array $rpcs (functionName => fileName) or (functionName=>anonFunc)
+//(allows call-time loading of subsets of functions)
+//$func=$_POST['f'] is the rpc function name to use. 
+//$file=$rpc[$func] is the file in which the function named $func lives 
+// (if False, function $func already loaded)
+//$_POST['a'] is a JSON encoded array to apply to $func
+//see rpc.js for client-side usage.
+function rpcServer($rpcs){
+  header("Content-Type: application/json");
+  set_error_handler('rpcError');
+  try{
+    $f=($postp=($_SERVER['REQUEST_METHOD']=='POST'))?$_POST['f']:'array_keys';
+    $args=($postp?json_decode((get_magic_quotes_gpc())?
+			      stripslashes($_POST['a']):$_POST['a']):array($rpcs));
+    if($postp && !isset($rpcs[$f])) rpcError(-1,"Undefined Function $f");
+    if($postp && ($file=$rpcs[$f]) && is_string($file)) include_once $file; //import necessary file if $f requires it
+    if($postp && !is_string($file) && is_callable($file)) $f=$file; //if $rpcs[$f] is an anonymous function, use that
+    $result=array('success'=>call_user_func_array($f,$args));
+  }catch (Exception $e){
+    $result=array('error'=>$e->getMessage()); // catch and encode any exceptions in the JSON RPC format described above
+  }
+  echo json_encode($result);
+}
+
+
+/*
+  Utility Functions for composing safe query based RPCs
+*/
+
+$qProcessors=array(); // store result types available
+
+//escape args and insert them into the the appropriate placeholders
+// '?' is replaced with the next numeric arg
+// {argName}  in replaced with the value of the key 'argName' in $args
+// this form also works for {n} for some integer n
+function query($pattern,$db,$args=array(),$resultType=NULL){
+  global $qProcessors;
+
+  //initialize result type dependant on query
+  if($resultType==NULL){
+    if(preg_match('/^\s*(SELECT|SHOW|DESCRIBE|EXPLAIN)\b/i',$pattern)){
+      $resultType="assocs";
+    }else if(preg_match('/^\s*INSERT\b/i',$pattern)){
+      $resultType='insert_id';
+    }else{
+      $resultType="count";
+    }
+  }
+
+  foreach ($args as $argName => $argVal){
+    if(is_int($argName)){
+      //replace ? with $argVal
+      $pattern = preg_replace("/\\?/",mysql_real_escape_string("$argVal"),$pattern,1);
+    }
+    //replace {$argname} with $argVal
+    $pattern = preg_replace("/\\{".preg_quote("$argName")."\\}/",mysql_real_escape_string("$argVal"),$pattern);
+  }
+  //  echo $pattern;
+  $res=mysql_query($pattern);
+  if(($e=mysql_error())) 
+    throw new Exception($e);
+  // use the appropriate query processor to return the result, or false if query failed
+  return $res?call_user_func($qProcessors[$resultType],$res):$res;
+}
+
+//return a single value from a result set
+$qProcessors['value']="result_value";
+function result_value($res){
+  list($r)=mysql_fetch_row($res);
+  return $r;
+}
+
+//return a single row as an integer indexed array
+$qProcessors['list']="result_list";
+function result_list($res){
+  return mysql_fetch_row($res);
+}
+
+//return a single row as an associative array
+$qProcessors['assoc']="result_assoc";
+function result_assoc($res){
+  return mysql_fetch_assoc($res);
+}
+
+//return a list of values (single element rows)
+$qProcessors['values']="result_values";
+function result_values($res){
+  $rows=array();
+  while((list($row)=mysql_fetch_row($res)))
+    $rows[]=$row;
+  return $rows;
+}
+
+//return anarray of 0-indexed rows
+$qProcessors['lists']="result_lists";
+function result_lists($res){
+  $rows=array();
+  while(($row=mysql_fetch_row($res)))
+    $rows[]=$row;
+  return $rows;
+}
+
+//return an array of assocs
+$qProcessors['assocs']="result_assocs";
+function result_assocs($res){
+  $rows=array();
+  while(($row=mysql_fetch_assoc($res)))
+    $rows[]=$row;
+  return $rows;
+}
+
+//return the number of rows affected
+$qProcessors['count']="result_count";
+function result_count($res){
+  return $res===True?mysql_affected_rows():mysql_num_rows();
+}
+
+//return the number of rows returned/modified
+$qProcessors['pairs']="result_pairs";
+function result_pairs($res){
+  $rows=array();
+  while(($row=mysql_fetch_row($res)))
+    $rows[$row[0]]=$row[1];
+  return $rows;
+}
+
+//return the autoincrement ID of the last row inserted
+$qProcessors['insert_id']="result_insert_id";
+function result_insert_id($res){
+  return mysql_insert_id();
+}
+
+?>

File rpc.php

-<?
-/*
- * JSON RPC Framework Server Side code 
- * 
- * calling rpcServer($functions); handles one RPC request per HTTP request. 
- *
- * Usage: 
- * rpcServer(array("someRPCFunctionDefinedInThisFile"=>False,
- *                 "someAnonFunc"=>function{ ... }, //requires PHP>=5.3.0
- *                 "someRPCFunction"=>"some/file/defining-or-requred-by/the/RPCFunc.php", 
- *                   ...));
- *
- * functions should return normal PHP values - strings/numbers/arrays/objects-and-assocs
- * the RPC code serializes them and deserializes them as Javascript equivalents 
- * (strings/numbers/arrays/objects respectively,
- *  note only public members of objects will be sent to the client)
- * it is important NOT to echo anything in an RPC func, it will break the RPC protocol format!
- *
- * Request Format:
- * POST application/x-www-form-urlencoded variables:
- *  'f' - the name of the function to be called
- *  'a' - a JSON encoded array of arguments
- *
- * Response Format:
- * {error:"Error Message As JSON Encoded String"}
- * or
- * {success:{some:"JSON", encoded:["object"]}
- *
- */
-
-//handle errors and exceptions such that they can be caught client side.
-function rpcError($errno,$errstring,$errfile=NULL,$errline=NULL){
-  if(error_reporting()){
-    die(json_encode(array('error'=>$errstring." :: $errfile @ $errline")));
-  }
-  return true;
-}
-
-//Use the associative array $rpcs (functionName => fileName) or (functionName=>anonFunc)
-//(allows call-time loading of subsets of functions)
-//$func=$_POST['f'] is the rpc function name to use. 
-//$file=$rpc[$func] is the file in which the function named $func lives 
-// (if False, function $func already loaded)
-//$_POST['a'] is a JSON encoded array to apply to $func
-//see rpc.js for client-side usage.
-function rpcServer($rpcs){
-  header("Content-Type: application/json");
-  set_error_handler('rpcError');
-  try{
-    $f=($postp=($_SERVER['REQUEST_METHOD']=='POST'))?$_POST['f']:'array_keys';
-    $args=($postp?json_decode((get_magic_quotes_gpc())?
-			      stripslashes($_POST['a']):$_POST['a']):array($rpcs));
-    if($postp && !isset($rpcs[$f])) rpcError(-1,"Undefined Function $f");
-    if($postp && ($file=$rpcs[$f]) && is_string($file)) include_once $file; //import necessary file if $f requires it
-    if($postp && !is_string($file) && is_callable($file)) $f=$file; //if $rpcs[$f] is an anonymous function, use that
-    $result=array('success'=>call_user_func_array($f,$args));
-  }catch (Exception $e){
-    $result=array('error'=>$e->getMessage()); // catch and encode any exceptions in the JSON RPC format described above
-  }
-  echo json_encode($result);
-}
-
-
-/*
-  Utility Functions for composing safe query based RPCs
-*/
-
-$qProcessors=array(); // store result types available
-
-//escape args and insert them into the the appropriate placeholders
-// '?' is replaced with the next numeric arg
-// {argName}  in replaced with the value of the key 'argName' in $args
-// this form also works for {n} for some integer n
-function query($pattern,$db,$args=array(),$resultType=NULL){
-  global $qProcessors;
-
-  //initialize result type dependant on query
-  if($resultType==NULL){
-    if(preg_match('/^\s*(SELECT|SHOW|DESCRIBE|EXPLAIN)\b/i',$pattern)){
-      $resultType="assocs";
-    }else if(preg_match('/^\s*INSERT\b/i',$pattern)){
-      $resultType='insert_id';
-    }else{
-      $resultType="count";
-    }
-  }
-
-  foreach ($args as $argName => $argVal){
-    if(is_int($argName)){
-      //replace ? with $argVal
-      $pattern = preg_replace("/\\?/",mysql_real_escape_string("$argVal"),$pattern,1);
-    }
-    //replace {$argname} with $argVal
-    $pattern = preg_replace("/\\{".preg_quote("$argName")."\\}/",mysql_real_escape_string("$argVal"),$pattern);
-  }
-  //  echo $pattern;
-  $res=mysql_query($pattern);
-  if(($e=mysql_error())) 
-    throw new Exception($e);
-  // use the appropriate query processor to return the result, or false if query failed
-  return $res?call_user_func($qProcessors[$resultType],$res):$res;
-}
-
-//return a single value from a result set
-$qProcessors['value']="result_value";
-function result_value($res){
-  list($r)=mysql_fetch_row($res);
-  return $r;
-}
-
-//return a single row as an integer indexed array
-$qProcessors['list']="result_list";
-function result_list($res){
-  return mysql_fetch_row($res);
-}
-
-//return a single row as an associative array
-$qProcessors['assoc']="result_assoc";
-function result_assoc($res){
-  return mysql_fetch_assoc($res);
-}
-
-//return a list of values (single element rows)
-$qProcessors['values']="result_values";
-function result_values($res){
-  $rows=array();
-  while((list($row)=mysql_fetch_row($res)))
-    $rows[]=$row;
-  return $rows;
-}
-
-//return anarray of 0-indexed rows
-$qProcessors['lists']="result_lists";
-function result_lists($res){
-  $rows=array();
-  while(($row=mysql_fetch_row($res)))
-    $rows[]=$row;
-  return $rows;
-}
-
-//return an array of assocs
-$qProcessors['assocs']="result_assocs";
-function result_assocs($res){
-  $rows=array();
-  while(($row=mysql_fetch_assoc($res)))
-    $rows[]=$row;
-  return $rows;
-}
-
-//return the number of rows affected
-$qProcessors['count']="result_count";
-function result_count($res){
-  return $res===True?mysql_affected_rows():mysql_num_rows();
-}
-
-//return the number of rows returned/modified
-$qProcessors['pairs']="result_pairs";
-function result_pairs($res){
-  $rows=array();
-  while(($row=mysql_fetch_row($res)))
-    $rows[$row[0]]=$row[1];
-  return $rows;
-}
-
-//return the autoincrement ID of the last row inserted
-$qProcessors['insert_id']="result_insert_id";
-function result_insert_id($res){
-  return mysql_insert_id();
-}
-
-?>