PHPRPC 2.1 的 ASP 服务器和客户端

经过 3 天的努力,终于把 ASP 的 PHPRPC 服务器和客户端写好了,为了充分利用已经写好的编码,ASP 的服务器和客户端都是用 JScript 实现的,里面调用了原来写好的 utf.js、base64.js、phpserializer.js、powmod.js 和 xxtea.js 这五个文件。ASP 版本的 PHPRPC 服务器和 PHP 版本的 PHPRPC 服务器端功能基本上一致,不过 ASP 版本的不支持输出重定向,也就是说如果远程函数中有用 Response.Write 输出的内容,在客户端是不能通过 output 参数得到的。这是由于 ASP 本身输出控制功能太弱造成的,另外,ASP 服务器端创建时,没有 debug 参数。ASP 服务器端发生的错误都是严重错误(没有警告和提示性错误)。ASP 客户端在初始化调用时,应使用绝对地址,而不能使用相对地址。

phprpc_server.js
  1. /**
  2. * @author      Ma Bingyao(andot@ujn.edu.cn)
  3. * @copyright   CoolCode.CN
  4. * @package     ASP_PHPRPC_SERVER
  5. * @version     2.1
  6. * @last_update 2006-06-12
  7. * @link        http://www.coolcode.cn/?p=187
  8. *
  9. * Example usage:
  10. *
  11. * server.asp
  12. * <%@ CodePage = 65001 %>
  13. * <script runat="server" type="text/javascript" src="phprpc_server.js"></script>
  14. * <%
  15. * function add(a, b)
  16. *     add = a + b
  17. * end function
  18.  
  19. * function subtract(a, b)
  20. *     subtract = a - b
  21. * end function
  22. * phprpc_server.create(Array('add', 'sub'));
  23. * %>
  24. */
  25.  
  26. function addjsslashes(str, flag) {
  27.     var test;
  28.     if (flag == false) {
  29.         test = /([\0-\037\042\047\134])/g;
  30.     }
  31.     else {
  32.         test = /([\0-\037\042\047\134\177-\377])/g;
  33.     }
  34.     return str.replace(test, function ($1) {
  35.         var s = $1.charCodeAt(0).toString(8);
  36.         return '\\' + ((s.length == 1) ? "00" : ((s.length == 2) ? "0" : "")) + s;
  37.     });
  38. }
  39.  
  40. function getGMTDate(date) {
  41.     var week = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  42.     return week[date.getUTCDay()] + ", " + date.toGMTString();
  43. }
  44.  
  45. function IsEmpty(o) {
  46.     if (typeof(o) == "object" && String(o) == "undefined") return true;
  47.     return false;
  48. }
  49.  
  50. function phprpc_server(functions) {
  51.     Response.CodePage = 65001;
  52.     Session.CodePage = 65001;
  53.     var func, args, result, encrypt;
  54.     var date = getGMTDate(new Date());
  55.     Response.Buffer = true;
  56.     Response.ContentType = "text/plain";
  57.     Response.Charset = "utf-8";
  58.     Response.AddHeader("X-Powered-By", "PHPRPC Server/2.1");
  59.     Response.AddHeader("Date", date);
  60.     Response.AddHeader("Last0Modified", date);
  61.     Response.AddHeader("Cache-Control", "no-store, no-cache, must-revalidate");
  62.     Response.AddHeader("Cache-Control", "pre-check=0, post-check=0, max-age=0");
  63.     Response.AddHeader("Content-Encoding", "none");
  64.     if (functions.constructor == Array) {
  65.         this.functions = functions;
  66.     }
  67.     else if (functions.constructor == VBArray) {
  68.         this.functions = functions.toArray();
  69.     }
  70.     else {
  71.         this.functions = [functions];
  72.     }
  73.     this.encode = true;
  74.     if (!IsEmpty(Request('phprpc_encode'))) {
  75.         this.encode = String(Request('phprpc_encode')).toLowerCase();
  76.         if (this.encode == "false") {
  77.             this.encode = false;
  78.         }
  79.     }
  80.     if (!IsEmpty(Request('phprpc_callback'))) {
  81.         this.callback = utf8to16(base64decode(String(Request('phprpc_callback'))));
  82.     }
  83.     else {
  84.         this.callback = "";
  85.     }
  86.     this.ref = true;
  87.     if (!IsEmpty(Request('phprpc_ref'))) {
  88.         this.ref = String(Request('phprpc_ref')).toLowerCase();
  89.         if (this.ref == "false") {
  90.             this.ref = false;
  91.         }
  92.     }
  93.     this.errno = 0;
  94.     this.errstr = "";
  95.    
  96.     try {
  97.         this.encrypt = false;
  98.         if (!IsEmpty(Request('phprpc_encrypt'))) {
  99.             this.encrypt = String(Request('phprpc_encrypt'));
  100.             if (this.encrypt === "true") this.encrypt = true;
  101.             if (this.encrypt === "false") this.encrypt = false;
  102.         }
  103.         if (!IsEmpty(Request('phprpc_func'))) {
  104.             func = String(Request('phprpc_func'));
  105.             if (this.is_defined(func)) {
  106.                 if (!IsEmpty(Request('phprpc_args'))) {
  107.                     args = base64decode(String(Request('phprpc_args')));
  108.                     if (this.encrypt > 0) {
  109.                         if (typeof(Session('PHPRPC_ENCRYPT')['k']) != "undefined") {
  110.                             args = xxtea_decrypt(args, Session('PHPRPC_ENCRYPT')['k']);
  111.                         }
  112.                         else {
  113.                             this.errno = 1;
  114.                             this.errstr = "Can't find the key for decryption.";
  115.                         }
  116.                     }
  117.                     args = unserialize(args);
  118.                 }
  119.                 else {
  120.                     args = [];
  121.                 }
  122.                 result = serialize(this.call(func, args));
  123.                 if (this.ref) {
  124.                     args = serialize(args);
  125.                 }
  126.                 if (this.encrypt > 0) {
  127.                     if (typeof(Session('PHPRPC_ENCRYPT')['k']) != "undefined") {
  128.                         if (this.encrypt > 1) {
  129.                             result = xxtea_encrypt(result, Session('PHPRPC_ENCRYPT')['k']);
  130.                         }
  131.                         if (this.ref) {
  132.                             args = xxtea_encrypt(args, Session('PHPRPC_ENCRYPT')['k']);
  133.                         }
  134.                     }
  135.                     else {
  136.                         this.errno = 1;
  137.                         this.errstr = "Can't find the key for encryption.";
  138.                     }
  139.                 }
  140.                 if (this.encode) {
  141.                     result = base64encode(result);
  142.                     if (this.ref) {
  143.                         args = base64encode(args);
  144.                     }
  145.                 }
  146.                 else {
  147.                     result = addjsslashes(result);
  148.                     if (this.ref) {
  149.                         args = addjsslashes(args);
  150.                     }
  151.                 }
  152.             }
  153.             else {
  154.                 this.errno = 1;
  155.                 this.errstr = "Can't find this function " + func + "().";
  156.             }
  157.             Response.Clear();
  158.             if (this.errno != 1) {
  159.                 Response.Write('phprpc_result="' + result + '";\r\n');
  160.                 if (this.ref) {
  161.                     Response.Write('phprpc_args="' + args + '";\r\n');
  162.                 }
  163.             }
  164.             Response.Write('phprpc_errno="' + this.errno + '";\r\n');
  165.             if (this.encode) {
  166.                 Response.Write('phprpc_errstr="' + base64encode(utf16to8(this.errstr)) + '";\r\n');
  167.                 Response.Write('phprpc_output="";\r\n');
  168.             }
  169.             else {
  170.                 Response.Write('phprpc_errstr="' + addjsslashes(this.errstr, false) + '";\r\n');
  171.                 Response.Write('phprpc_output="";\r\n');
  172.             }
  173.         }
  174.         else {
  175.             if (this.encrypt != false) {
  176.                 if (this.encrypt === true) {
  177.                     encrypt = phprpc_keypair[Math.floor(Math.random() * phprpc_keypair.length)];
  178.                     Session('PHPRPC_ENCRYPT') = [];
  179.                     Session('PHPRPC_ENCRYPT')['x'] = rand(127, 1);
  180.                     Session('PHPRPC_ENCRYPT')['g'] = dec2num(encrypt['g']);
  181.                     Session('PHPRPC_ENCRYPT')['p'] = dec2num(encrypt['p']);
  182.                     encrypt['y'] = num2dec(pow_mod(Session('PHPRPC_ENCRYPT')['g'],
  183.                                                    Session('PHPRPC_ENCRYPT')['x'],
  184.                                                    Session('PHPRPC_ENCRYPT')['p']));
  185.                 }
  186.                 else {
  187.                     Session('PHPRPC_ENCRYPT')['y'] = dec2num(this.encrypt);
  188.                     var key = num2str(pow_mod(Session('PHPRPC_ENCRYPT')['y'],
  189.                                               Session('PHPRPC_ENCRYPT')['x'],
  190.                                               Session('PHPRPC_ENCRYPT')['p']));
  191.                     var n = 16 - key.length;
  192.                     var k = [];
  193.                     for (var i = 0; i < n; i++) {
  194.                         k[i] = '\0';
  195.                     }
  196.                     k[n] = key;
  197.                     Session('PHPRPC_ENCRYPT')['k'] = k.join('');
  198.                     encrypt = true;
  199.                 }
  200.                 if (this.encode) {
  201.                     Response.Write('phprpc_encrypt="' + base64encode(serialize(encrypt)) + '";\r\n');
  202.                 }
  203.                 else {
  204.                     Response.Write('phprpc_encrypt="' + addjsslashes(serialize(encrypt)) + '";\r\n');
  205.                 }
  206.             }
  207.             if (this.encode) {
  208.                 Response.Write('phprpc_functions="' + base64encode(serialize(this.functions)) + '";\r\n');
  209.             }
  210.             else {
  211.                 Response.Write('phprpc_functions="' + addjsslashes(serialize(this.functions)) + '";\r\n');
  212.             }
  213.         }
  214.         Response.Write(this.callback);
  215.     }
  216.     catch (e) {
  217.         this.errno = 1;
  218.         this.errstr = e.description;
  219.         Response.Clear();
  220.         Response.Write('phprpc_errno=' + this.errno + ';\r\n');
  221.         if (this.encode) {
  222.             Response.Write('phprpc_errstr="' + base64encode(utf16to8(this.errstr)) + '";\r\n');
  223.         }
  224.         else {
  225.             Response.Write('phprpc_errstr="' + addjsslashes(this.errstr, false) + '";\r\n');
  226.         }
  227.         Response.Write('phprpc_output="";\r\n');
  228.         Response.Write(this.callback);
  229.     }
  230.     Response.End();
  231. }
  232.  
  233. phprpc_server.prototype.is_defined = function (func) {
  234.     for (var i = 0, n = this.functions.length; i < n; i++) {
  235.         if (this.functions[i] == func) return true;
  236.     }
  237.     return false;
  238. }
  239.  
  240. phprpc_server.prototype.call = function (func, args) {
  241.     var a = [];
  242.     for (var i = 0, n = args.length; i < n; i++) {
  243.         a[i] = 'args[' + i + ']';
  244.     }
  245.     return eval(func + "(" + a.join(', ') + ")");
  246. }
  247.  
  248. phprpc_server.create = function (functions) {
  249.     new phprpc_server(functions);
  250. }

下面的程序 keypair.js 是自动生成的,生成该程序的程序与生成 keypair.php 的程序差不多,这里就不单独提供了,我会在以后的 phprpc_2.1 包中发布的。

phprpc_client.js
  1. /**
  2. * @author      Ma Bingyao(andot@ujn.edu.cn)
  3. * @copyright   CoolCode.CN
  4. * @package     ASP_PHPRPC_CLIENT
  5. * @version     2.1
  6. * @last_update 2006-06-14
  7. * @link        http://www.coolcode.cn/?p=143
  8. *
  9. * Example usage:
  10. *
  11. * server.asp
  12. * <%@ CodePage = 65001 %>
  13. * <script runat="server" type="text/javascript" src="phprpc_client.js"></script>
  14. * <%
  15. * phprpc_client.create('rpc')
  16. * rpc.use_service('http://test.coolcode.cn/phprpc/server.php')
  17. * Response.Write(rpc.add(1,2))
  18. * %>
  19. */
  20.  
  21. function phprpc_error(errno, errstr) {
  22.     this.errno = errno;
  23.     this.errstr = errstr;
  24. }
  25.  
  26. function phprpc_client() {
  27.     this.__url = '';
  28.     this.__encrypt = false;
  29.     this.encrypt = 0;
  30.     this.args = null;
  31.     this.warning = null;
  32.     this.output = "";
  33.     this.use_service = function (url, encrypt) {
  34.         if (typeof(encrypt) == "undefined") {
  35.             encrypt = this.__encrypt;
  36.         }
  37.         if (typeof(this.__name) == "undefined") {
  38.             return false;
  39.         }
  40.         this.__url = url;
  41.         var xmlhttp = this.__create_xmlhttp()
  42.         if (encrypt === true) {
  43.             xmlhttp.open("GET", [this.__url, '?phprpc_encrypt=true&phprpc_encode=false'].join(''), false);
  44.             xmlhttp.send(null);
  45.             if (xmlhttp.responseText) {
  46.                 eval(xmlhttp.responseText);
  47.                 if (typeof(phprpc_encrypt) == "undefined") {
  48.                     this.__encrypt = false;
  49.                     encrypt = false;
  50.                 }
  51.                 else {
  52.                     this.__encrypt = unserialize(phprpc_encrypt);
  53.                     this.__encrypt['p'] = dec2num(this.__encrypt['p']);
  54.                     this.__encrypt['g'] = dec2num(this.__encrypt['g']);
  55.                     this.__encrypt['y'] = dec2num(this.__encrypt['y']);
  56.                     this.__encrypt['x'] = rand(127, 1);
  57.                     var key = pow_mod(this.__encrypt['y'],
  58.                                       this.__encrypt['x'],
  59.                                       this.__encrypt['p']);
  60.                     key = num2str(key);
  61.                     var n = 16 - key.length;
  62.                     var k = [];
  63.                     for (var i = 0; i < n; i++) k[i] = '\0';
  64.                     k[n] = key;
  65.                     this.__encrypt['k'] = k.join('');
  66.                     encrypt = num2dec(pow_mod(this.__encrypt['g'],
  67.                                               this.__encrypt['x'],
  68.                                               this.__encrypt['p']));
  69.                 }
  70.             }
  71.         }
  72.  
  73.         xmlhttp.open("GET", [this.__url, '?phprpc_encrypt=', encrypt, '&phprpc_encode=false'].join(''), false);
  74.         xmlhttp.send(null);
  75.         if (xmlhttp.responseText) {
  76.             eval(xmlhttp.responseText);
  77.             var functions = unserialize(phprpc_functions);
  78.             var func = [];
  79.             for (var i = 0, n = functions.length; i < n; i++) {
  80.                 func[i] = [this.__name, ".", functions[i],
  81.                         " = function () { return this.__call('",
  82.                         functions[i],
  83.                         "', this.__args_to_array(arguments)); }\r\n",
  84.                         this.__name, ".", functions[i],
  85.                         ".ref = false;\r\n"].join('');
  86.             }
  87.             eval(func.join(''));
  88.         }
  89.         delete(xmlhttp);
  90.     };
  91.     this.__call = function (func, args) {
  92.         var __args = serialize(args);
  93.         if ((this.__encrypt !== false) && (this.encrypt > 0)) {
  94.             __args = xxtea_encrypt(__args, this.__encrypt['k']);
  95.         }
  96.         __args = base64encode(__args);
  97.         var request = ['phprpc_func=', func,
  98.                        '&phprpc_args=', __args,
  99.                        '&phprpc_encode=false',
  100.                        '&phprpc_encrypt=', this.encrypt];
  101.         var ref = eval([this.__name, ".", func, ".ref"].join(''));
  102.         if (!ref) {
  103.             request[request.length] = '&phprpc_ref=false';
  104.         }
  105.         var xmlhttp = this.__create_xmlhttp();
  106.         var session = {'args': args, 'ref': ref, 'encrypt': this.encrypt};
  107.         xmlhttp.open("POST", this.__url, false);
  108.         xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
  109.         xmlhttp.send(request.join('').replace(/\+/g, '%2B'));
  110.         if (xmlhttp.responseText) {
  111.             this.__get_result(xmlhttp, session);
  112.             this.output = phprpc_output;
  113.             this.args = phprpc_args;
  114.             this.warning = phprpc_warning;
  115.         }
  116.         else {
  117.             phprpc_result = new phprpc_error(1, "No data received from server");
  118.         }
  119.         delete(xmlhttp);
  120.  
  121.         return phprpc_result;
  122.     };
  123.     this.__get_result = function (xmlhttp, session) {
  124.         eval(xmlhttp.responseText);
  125.         phprpc_warning = null;
  126.         if ((phprpc_errno != 1) && (phprpc_errno != 16) &&
  127.             (phprpc_errno != 64) && (phprpc_errno != 256)) {
  128.             if ((this.__encrypt !== false) && (session.encrypt > 0)) {
  129.                 if (session.encrypt > 1) {
  130.                     phprpc_result = xxtea_decrypt(phprpc_result, this.__encrypt['k']);
  131.                 }
  132.                 if (session.ref) {
  133.                     phprpc_args = xxtea_decrypt(phprpc_args, this.__encrypt['k']);
  134.                 }
  135.             }
  136.             phprpc_result = unserialize(phprpc_result);
  137.  
  138.             if (session.ref) {
  139.                 phprpc_args = unserialize(phprpc_args);
  140.             }
  141.             else {
  142.                 phprpc_args = session.args;
  143.             }
  144.             phprpc_warning = new phprpc_error(phprpc_errno, phprpc_errstr);
  145.         }
  146.         else {
  147.             phprpc_result = new phprpc_error(phprpc_errno, phprpc_errstr);
  148.             phprpc_args = session.args;
  149.         }
  150.     }
  151.     this.__create_xmlhttp = function() {
  152.         var MSXML = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
  153.         var n = MSXML.length;
  154.         for(var i = 0; i < n; i++) {
  155.             try {
  156.                 return new ActiveXObject(MSXML[i]);
  157.             }
  158.             catch(e) {}
  159.         }
  160.         throw new Error("Your server does not support xmlhttp objects");
  161.     };
  162.     this.__args_to_array = function (args) {
  163.         var argArray = [];
  164.         var n = args.length;
  165.         for (i = 0; i < n; i++) {
  166.             argArray[i] = args[i];
  167.         }
  168.         return argArray;
  169.     }
  170. }
  171.  
  172. phprpc_client.create = function (name, encrypt) {
  173.     eval([name, ' = new phprpc_client();', name, '.__name = "', name, '";'].join(''));
  174.     if (encrypt) {
  175.         encrypt = true;
  176.         eval([name, '.__encrypt = ', encrypt, ';'].join(''));
  177.     }
  178. }

标签: Ajax, PHPRPC

« 上一篇 | 下一篇 »

只显示10条记录相关文章

发表评论

评论 (必须):