/**
* @author Ma Bingyao(andot@ujn.edu.cn)
* @copyright CoolCode.CN
* @package JAVA_PHPRPC_CLIENT
* @version 2.1
* @last_update 2006-08-09
* @link http://www.coolcode.cn/?p=205
*
* Example usage:
import java.lang.*;
import PHPRPC.*;
public class SinTest
{
public static void main(String[] args) {
PHPRPCClient rpc = new PHPRPCClient();
rpc.useService("http://localhost:8080/phprpc_2.1/sample/server.jsp", true);
rpc.setEncrypt(2);
System.out.println(rpc.invoke("sin", new Double(args[0])));
}
}
*
*/
package coolcode.phprpc;
import java.lang.*;
import java.io.*;
import java.util.*;
import java.math.*;
import java.net.*;
class PHPRPCError {
private int __errno;
private String __errstr;
protected PHPRPCError(int errno, String errstr)
{
this.__errno = errno;
this.__errstr = errstr;
}
public int getNumber() {
return this.__errno;
}
public String getMessage() {
return this.__errstr;
}
public override String toString() {
return this.__error + ":" + this.__errstr;
}
}
public class PHPRPCClient {
private String __uri;
private String __charset;
private String __cookies;
private String __output;
private byte __encrypt;
private PHPRPCError __warning;
private byte[] __key;
private HashMap __proxy = null;
public PHPRPCClient()
{
this.__uri = null;
this.__proxy = null;
this.__encrypt = 0;
this.__user = null;
this.__pass = null;
}
public String getOutput() {
return __output;
}
public byte getEncrypt() {
return __encrypt;
}
public void setEncrypt(byte value) {
__encrypt = value;
}
public PHPRPCError getWarning() {
return __warning;
}
public void setProxy(String host, int port) {
this.__proxy = new HashMap();
this.__proxy.put("host", host);
this.__proxy.put("port", port);
}
public void setProxy(String host, int port, String user, String pass) {
this.__proxy = new HashMap();
this.__proxy.put("host", host);
this.__proxy.put("port", port);
this.__proxy.put("user", user);
this.__proxy.put("pass", pass);
}
public void setProxy(HashMap proxy) {
this.__proxy = proxy;
}
public void setAuth(String user, String pass) {
this.__user = user;
this.__pass = pass;
}
public bool useService(String requestUriString)
{
return useService(requestUriString, false);
}
public bool useService(String requestUriString, boolean encrypt)
{
this.__uri = requestUriString;
this.__warning = null;
this.__output = "";
this.__cookies = null;
this.__charset = null;
this.__key = null;
if (encrypt)
{
return SwitchKey();
}
else
{
Socket socket = this.__request("", "GET");
InputStream is = socket.getInputStream();
HashMap header = this.__getHeader(is);
is.close();
socket.close();
this.__charset = this.__getCharset(header);
return true;
}
}
private String __getCharset(HashMap header) {
if (header.containsKey("Content-Type")) {
String charset = (String)header.get("Content-Type");
if (charset.startsWith("text/plain; charset=")) {
return charset.substring(20);
}
}
return "UTF-8";
}
private Socket __request(String requestString, String method) {
URL url = new URL(this.__uri);
String host = url.getHost();
int port = url.getPort();
if (port == -1) {
port = url.getDefaultPort();
}
Socket socket;
try {
if (this.__proxy != null) {
socket = new Socket(this.__proxy.get("host"), this.__proxy.get("port"));
} else {
socket = new Socket(host , port);
}
} catch (Exception e)
{
return null;
}
String proxy = "";
if (this.__proxy != null) {
proxy = "Proxy-Connection: Keep-Alive\r\n";
if (this.__proxy.containsKey('user') && this.__proxy.containsKey('pass')) {
proxy += "Proxy-Authorization: Basic "
+ Base64.encode(this.__proxy.get("user") + ":" + this.__proxy.get("pass"))
+ "\r\n";
}
}
String auth = "";
if (this.__user != null && this.__pass != null) {
auth = "Authorization: Basic " + Base64.encode(this.__user + ":" + this.__pass) + "\r\n";
}
String cookie = "";
if (this.__cookie != null) {
cookie = "Cookie: " + this.__cookie + "\r\n";
}
OutputStream os = socket.getOutputStream();
String httpHead;
if (method.toUpperCase().equals("GET")) {
httpHead = "GET " + new URL(url, requestString).toString() + " HTTP/1.0\r\n" +
"User-Agent: PHPRPC Client/2.1\r\n" +
"Host: " + host + ":" + port + "\r\n" +
proxy + auth + cookie +
"\r\n";
os.write(httpHead.getBytes());
}
else {
byte[] content = requestString.getBytes(this.charset);
httpHead = "POST " + url.toString() + " HTTP/1.0\r\n" +
"User-Agent: PHPRPC Client/2.1\r\n" +
"Host: " + host + ":" + port + "\r\n" +
proxy + auth + cookie +
"Content-Type: application/x-www-form-urlencoded; charset=" + this.charset + "\r\n" +
"Content-Length: " + content.length + "\r\n" +
"\r\n";
os.write(httpHead.getBytes());
os.write(content);
}
os.close();
return socket;
}
private HashMap __getHeader(InputStream is) {
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String buf;
HashMap header = new HashMap();
while ((buf = in.readLine()) != "") {
if (buf.startsWith("HTTP/")) {
header.put("Version", buf.substring(5, 8));
header.put("StatusCode", buf.substring(9, 12));
header.put("Status", buf.substring(13));
}
else {
int pos = buf.indexOf(": ");
header.put(buf.substring(0, pos), buf.substring(pos + 2));
}
}
}
private bool SwitchKey()
{
HttpWebResponse response = this.GET("phprpc_encrypt=true");
this.__encoding = this.GetEncoding(response);
this.__cookies = response.Cookies;
Stream s = response.GetResponseStream();
StreamReader sr = new StreamReader(s, this.__encoding);
string[] body = Regex.Split(sr.ReadToEnd(), "\r\n");
response.Close();
if (body[0].StartsWith("phprpc_encrypt"))
{
Hashtable kp = (Hashtable)PHPSerializer.UnSerialize(Convert.FromBase64String(body[0].Substring(16, body[0].Length - 18)));
BigInteger p = BigInteger.Parse(kp["p"] as string);
BigInteger g = BigInteger.Parse(kp["g"] as string);
BigInteger y = BigInteger.Parse(kp["y"] as string);
BigInteger x = BigInteger.GenerateRandom(127);
this.__key = new byte[16];
byte[] key = y.ModPow(x, p).GetBytes();
for (int i = 1, n = key.Length; i <= n; i++)
{
this.__key[16 - i] = key[n - i];
}
this.GET(String.Concat("phprpc_encrypt=", (g.ModPow(x, p)).ToString())).Close();
return true;
}
else
{
this.__warning = new Error(2, "PHPRPC Server can't support encrypt");
return false;
}
}
private void SetWarning(string errno, string errstr)
{
int number = Int32.Parse(errno.Substring(14, errno.Length - 16));
if (number != 0)
{
this.__warning = new Error(number, this.__encoding.GetString(Convert.FromBase64String(errstr.Substring(15, errstr.Length - 17))));
}
}
private void SetOutput(string output)
{
this.__output = this.__encoding.GetString(Convert.FromBase64String(output.Substring(15, output.Length - 17)));
}
public object Invoke(string function, params object[] args)
{
bool byref = false;
return this.Invoke(ref byref, function, ref args);
}
public object Invoke(string function, ref object[] args)
{
bool byref = true;
return this.Invoke(ref byref, function, ref args);
}
private object Invoke(ref bool byref, string function, ref object[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append("phprpc_func=");
sb.Append(function);
if (args.Length > 0)
{
byte[] arguments = PHPSerializer.Serialize(args);
if (this.__key != null && this.__encrypt > 0)
{
arguments = XXTEA.Encrypt(arguments, this.__key);
}
sb.Append("&phprpc_args=");
sb.Append(Convert.ToBase64String(arguments).Replace("+", "%2B"));
if (!byref)
{
sb.Append("&phprpc_ref=false");
}
}
if (this.__key != null)
{
sb.Append("&phprpc_encrypt=");
sb.Append(this.__encrypt);
}
HttpWebResponse response = this.POST(sb.ToString());
Stream s = response.GetResponseStream();
StreamReader sr = new StreamReader(s, this.__encoding);
string[] body = Regex.Split(sr.ReadToEnd(), "\r\n");
response.Close();
this.__warning = null;
if (body[0].StartsWith("phprpc_errno"))
{
throw new Exception(this.__encoding.GetString(Convert.FromBase64String(body[1].Substring(15, body[1].Length - 17))));
}
if (body[0].StartsWith("phprpc_result"))
{
byte[] result = Convert.FromBase64String(body[0].Substring(15, body[0].Length - 17));
byte[] arguments = null;
bool has_args = body[1].StartsWith("phprpc_args");
if (has_args)
{
arguments = Convert.FromBase64String(body[1].Substring(13, body[1].Length - 15));
this.SetWarning(body[2], body[3]);
this.SetOutput(body[4]);
}
else
{
this.SetWarning(body[1], body[2]);
this.SetOutput(body[3]);
}
if ((this.__key != null) && (this.__encrypt > 0))
{
if (this.__encrypt > 1)
{
result = XXTEA.Decrypt(result, this.__key);
}
if (has_args)
{
arguments = XXTEA.Decrypt(arguments, this.__key);
}
}
if (has_args)
{
args = (object[])PHPSerializer.UnSerialize(arguments, typeof(object[]));
}
return PHPSerializer.UnSerialize(result);
}
else
{
throw new Exception("Wrong PHPRPC Server!");
}
}
}
}