/* phprpc_ajax_client.js - Ajax PHPRPC Client
*
* Copyright Ma Bingyao <andot@ujn.edu.cn>
* Version: 2.1
* LastModified: 2006-03-21
* This library is free. You can redistribute it and/or modify it.
* http://www.coolcode.cn/?p=146
*/
/*
* Interfaces:
* phprpc_client.create('rpc');
* rpc.use_service('http://domain.com/phprpc/server.php');
* rpc.method_callback = function(result, args, output) {
* if (result instanceof phprpc_error) {
* alert(result.errstr);
* }
* else {
* alert(result); // or do any other things.
* }
* }
* ....
* if (rpc.ready) rpc.method();
*/
function phprpc_error(errno, errstr) {
this.errno = errno;
this.errstr = errstr;
}
function phprpc_client() {
this.__php = new PHP_Serializer();
this.__url = '';
this.__encrypt = false;
this.encrypt = 0;
this.async = true;
this.ready = false;
this.args = null;
this.warning = null;
this.output = "";
this.use_service = function (url, encrypt) {
if (typeof(encrypt) == "undefined") {
encrypt = this.__encrypt;
}
if (typeof(this.__name) == "undefined") {
return false;
}
this.__url = url;
this.ready = false;
var xmlhttp = this.__create_xmlhttp();
var __rpc = this;
if (encrypt === true) {
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (xmlhttp.responseText) {
eval(xmlhttp.responseText);
if (typeof(phprpc_encrypt) == "undefined") {
__rpc.__encrypt = false;
__rpc.use_service(__rpc.__url);
}
else {
__rpc.__encrypt = __rpc.__php.unserialize(phprpc_encrypt);
__rpc.__encrypt['p'] = dec2num(__rpc.__encrypt['p']);
__rpc.__encrypt['g'] = dec2num(__rpc.__encrypt['g']);
__rpc.__encrypt['y'] = dec2num(__rpc.__encrypt['y']);
__rpc.__encrypt['x'] = rand(127, 1);
var key = pow_mod(__rpc.__encrypt['y'],
__rpc.__encrypt['x'],
__rpc.__encrypt['p']);
key = num2str(key);
for (var i = 0; i < 16 - key.length; i++) {
key = '\0' + key;
}
__rpc.__encrypt['k'] = key;
var encrypt = pow_mod(__rpc.__encrypt['g'],
__rpc.__encrypt['x'],
__rpc.__encrypt['p']);
__rpc.use_service(__rpc.__url, num2dec(encrypt).replace(/\+/g, '%2B'));
}
}
delete(xmlhttp);
}
}
}
else {
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (xmlhttp.responseText) {
eval(xmlhttp.responseText);
var functions = __rpc.__php.unserialize(phprpc_functions);
var func;
for (var i = 0; i < functions.length; i++) {
func = [__rpc.__name, ".", functions[i],
" = function () {\r\n this.__call('",
functions[i],
"', this.__args_to_array(arguments));\r\n}\r\n",
__rpc.__name, ".", functions[i],
".ref = false;\r\n"].join('');
eval(func);
}
__rpc.ready = true;
if (typeof(__rpc.onready) == "function") {
__rpc.onready();
}
}
delete(xmlhttp);
}
}
}
xmlhttp.open("get", [this.__url, '?phprpc_encrypt=', encrypt, '&phprpc_encode=false'].join(''), true);
xmlhttp.send(null);
};
this.__call = function (func, args) {
var __args = this.__php.serialize(args);
if ((this.__encrypt !== false) && (this.encrypt > 0)) {
__args = xxtea_encrypt(__args, this.__encrypt['k']);
}
__args = base64encode(__args);
var request = ['phprpc_func=', func,
'&phprpc_args=', __args,
'&phprpc_encode=false',
'&phprpc_encrypt=', this.encrypt];
var ref = eval([this.__name, ".", func, ".ref"].join(''));
if (!ref) {
request[request.length] = '&phprpc_ref=false';
}
var xmlhttp = this.__create_xmlhttp();
var session = {'args': args, 'ref': ref, 'encrypt': this.encrypt};
if (this.async) {
var __rpc = this;
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (xmlhttp.responseText) {
__rpc.__get_result(xmlhttp, session);
if (typeof(eval([__rpc.__name, ".", func, "_callback"].join(''))) == "function") {
eval([__rpc.__name, ".", func, "_callback(phprpc_result, phprpc_args, phprpc_output, phprpc_warning);"].join(''));
}
}
delete(xmlhttp);
}
}
}
xmlhttp.open("post", this.__url, this.async);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xmlhttp.send(request.join('').replace(/\+/g, '%2B'));
if (!this.async) {
if (xmlhttp.responseText) {
this.__get_result(xmlhttp, session);
this.output = phprpc_output;
this.args = phprpc_args;
this.warning = phprpc_warning;
return phprpc_result;
}
else {
return new phprpc_error(1, "No data received from server");
}
delete(xmlhttp);
}
};
this.__get_result = function (xmlhttp, session) {
eval(xmlhttp.responseText);
phprpc_warning = null;
if ((phprpc_errno != 1) && (phprpc_errno != 16) &&
(phprpc_errno != 64) && (phprpc_errno != 256)) {
if ((this.__encrypt !== false) && (session.encrypt > 0)) {
if (session.encrypt > 1) {
phprpc_result = xxtea_decrypt(phprpc_result, this.__encrypt['k']);
}
if (session.ref) {
phprpc_args = xxtea_decrypt(phprpc_args, this.__encrypt['k']);
}
}
phprpc_result = this.__php.unserialize(phprpc_result);
if (session.ref) {
phprpc_args = this.__php.unserialize(phprpc_args);
}
else {
phprpc_args = this.args;
}
phprpc_warning = new phprpc_error(phprpc_errno, phprpc_errstr);
}
else {
phprpc_result = new phprpc_error(phprpc_errno, phprpc_errstr);
phprpc_args = null;
}
}
// the function __create_xmlhttp modified from
// http://webfx.eae.net/dhtml/xmlextras/xmlextras.html and
// http://www.ugia.cn/?p=85
this.__create_xmlhttp = function() {
if (window.XMLHttpRequest) {
var objXMLHttp = new XMLHttpRequest();
// some older versions of Moz did not support the readyState property
// and the onreadystate event so we patch it!
if (objXMLHttp.readyState == null) {
objXMLHttp.readyState = 0;
objXMLHttp.addEventListener(
"load",
function () {
objXMLHttp.readyState = 4;
if (typeof(objXMLHttp.onreadystatechange) == "function") {
objXMLHttp.onreadystatechange();
}
},
false
);
}
return objXMLHttp;
}
else {
var MSXML = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
for(var n = 0; n < MSXML.length; n ++) {
try {
return objXMLHttp = new ActiveXObject(MSXML[n]);
}
catch(e) {}
}
throw new Error("Your browser does not support xmlhttp objects");
}
};
this.__args_to_array = function (args) {
argArray = [];
for (i = 0; i < args.length; i++) {
argArray[i] = args[i];
}
return argArray;
}
}
phprpc_client.create = function (name, encrypt) {
eval([name, ' = new phprpc_client();', name, '.__name = "', name, '";'].join(''));
if (encrypt) {
encrypt = true;
eval([name, '.__encrypt = ', encrypt, ';'].join(''));
}
}