ultimatepp/uppdev/XmlRpc/XmlRpc.h
cxl 4a1c627474 Adding uppdev....
git-svn-id: svn://ultimatepp.org/upp/trunk@328 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-08-15 08:36:24 +00:00

287 lines
9.5 KiB
C++

#ifndef _XmlRpc_XmlRpc_h
#define _XmlRpc_XmlRpc_h
#include <Core/Core.h>
#include <ValueMap/ValueMap.h>
#include <Web/Web.h>
#include <Web/SSL/WebSSL.h>
/**
* Base class that converts Values to XML. This base class is used for XmlRpcCall and XmlRpcServer to
* convert their Values to the corresponding XML string to send to the other side.
*/
class ValueXmlConvert {
public:
typedef ValueXmlConvert CLASSNAME;
void PrimitiveToXml(XmlNode& xml,const Value& v) const;
void ValueToXml(XmlNode& xml, Value& v) const;
};
/**
* Class to create calls to a Xml Server. This class is used by XmlRpcClient to generate calls and send them
* to the server. A XmlRpcCall is passed to XmlRpcClient::Execute() to be sent to the server.
*/
class XmlRpcCall : ValueXmlConvert {
private:
String method;
ValueArray va;
VectorMap<int,int> NumberToValue;
public:
typedef XmlRpcCall CLASSNAME;
XmlRpcCall();
XmlRpcCall(String _method);
XmlRpcCall(const char *_method);
XmlRpcCall& operator() (const Value& v);
void Clear();
String ToXml() const;
};
/**
* Class that parses the Xml answers. XmlRpcParser is used by XmlRpcClient and XmlRpcServer to parse the
* incomming traffic and convert it to a Value that can be used to respond (at the server side) or
* returned to the user (client side).
*/
class XmlRpcParser {
protected:
Value ParsePrimitive(XmlParser& p);
Value ParseStruct(XmlParser& p);
Value ParseArray(XmlParser& p);
Value Parse(XmlParser& p);
public:
typedef XmlRpcParser CLASSNAME;
XmlRpcParser();
Value ParseMethodCall(String s);
Value ParseMethodResponse(String s);
};
/**
* Client class used to connect to a server. This base class is used for XmlRpcClient and XmlRpcServer to
* convert their Values to the corresponding XML string to send to the other side.
*/
class XmlRpcClient {
private:
HttpClient http;
String rawReply;
XmlRpcParser xmlReply;
SSLContext sslcontext;
bool usessl;
public:
typedef XmlRpcClient CLASSNAME;
XmlRpcClient();
XmlRpcClient(String host, String path, int Port);
/**
* enable the use of ssl encryption. enable the use of ssl encryption,
* the default setting is off
* @param ssl set the use on if true
* @warning if no ssl context is set it sets the method to TLS
* and does NOT verify the peer
*/
void UseSSl(bool ssl=true) {usessl=ssl;}
XmlRpcClient& Host(String h);
XmlRpcClient& Path(String p);
XmlRpcClient& Port(int p);
/**
* get the ssl context. get the ssl context
*/
SSLContext& GetSSLContext() {return sslcontext;}
//HttpClient& Get();
/*
* returns the raw reply. returns the raw(= non parsed) reply of the server
*/
const String& GetRawReply() const {return rawReply;}
Value Execute(const XmlRpcCall& call);
};
/**
* Server Methods-Class. This is the base class of Methods that are used by the server to response
* to questions of any clients.
*/
class XmlRpcMethod {
protected:
String name;
public:
typedef XmlRpcMethod CLASSNAME;
/**
* constructs a method without a name. constructs a method without a name, should not be used!
*/
XmlRpcMethod() {name.Clear();}
/**
* create a named method. create a method with name \p s. it will be called
* if the call includes \p s as method name and the signature of the call
* and the method are the same.
* @param s the name of the method
* @see Execute(), Signature()
*/
XmlRpcMethod(String s) {name = s;}
/**
* called if executed. this has to be implemented by any method that should be used.
* it is called if one of the signatures of the method and the name match
* @param result a reference to a Value in which after execution the result has to be
* @param params a ValueArray containing only the parameters, not the methodname.
* @param ipadd the ip address of the calling client
* @see Signature()
*/
virtual void Execute(Value& result, ValueArray params, dword ipadd) {}
/**
* return help of the message. this method just has to set the String \p help
* to availeable help. no xml tags are allowed within this help.
* @param help string to store the help for the message in
*/
virtual void Help(String& help) {}
/**
* setting the signature. this method has to set the signature(s) of the methodcall:
* each Value in the ValueArray \p sig is a signature, which also is a ValueArray, so
* for each signature one has to add a ValueArray to \p sig.
* if for example a functions looks like this int something(int x,double y) or
* like int something(double x, string y, int z), the result would be:
* @code
* ValueArray first, second;
* first.Add(1); //1 is an int, return value
* first.Add(1); //1 is an int, x
* first.Add(1.1); //1.1 is a double, y
*
* second.Add(1);
* second.Add(1.1);
* second.Add("abc");
* second.Add(1);
*
* sig.Add(first);
* sig.Add(second);
* @endcode
*/
virtual void Signature(ValueArray& sig) {}
String GetName() {return name;}
};
/**
* Server class used to run a Xml-Rpc Server. This class implements a complete Server with extendeable functionality.
* a new Method is Added by creating a new class derived from XmlRpcMethod and add it by using the Add() function.
*/
class XmlRpcServer : ValueXmlConvert {
public:
/**
* base class of server system methods. Internal Methods of the server should be derived from this class.
* it is pretty the same as the XmlRpcMethod (actually it is derived from it) with two exceptions:
* a "system." is added to the method name, the pointer to the method array is passed to this methods.
* they can only be loaded within the server, not from external, like user methods.
* @see loadSysMethods(), XmlRpcMethod
*/
class XmlRpcSysMethod : public XmlRpcMethod {
protected:
Vector<XmlRpcMethod *> *methods;
public:
XmlRpcSysMethod() {}
XmlRpcSysMethod(String s, Vector<XmlRpcMethod *>* _methods) : XmlRpcMethod("system."+s) {methods=_methods;}
};
/**
* connection information. connection informations are stored in this struct
* @param ipadd ip address of the client
* @param timeout max time to wait [ms]
*/
struct XmlRpcConnectionInfo {
dword ipadd;
int timeout;
};
protected:
Vector<XmlRpcMethod *> methods;
int server_port,listen;
bool use_ssl,sysMethodsLoaded,sysMethods;
SSLContext sslcontext;
Socket socket;
void CheckHttpHeader(String& s);
void CheckSignatureAndRun(Socket& s, XmlRpcMethod* m, ValueArray params, dword ipadd);
String Response(Value& v);
void SendResponse(Socket &s, String s);
/*
* send http response. call SendResponse() avter calling Response() for value \p v.
* @param s socket the connection is on
* @param v value to be sent (non error)
*/
void SendResponse(Socket &s, Value& v) {SendResponse(s,Response(v));}
void Error(Socket& s, int code, String desc);
void loadSysMethods(bool load=true);
public:
typedef XmlRpcServer CLASSNAME;
XmlRpcServer();
XmlRpcServer& Add(XmlRpcMethod* m);
void Clear();
/**
* get the ssl context. get the ssl context
*/
SSLContext& GetSSLContext() {return sslcontext;}
bool Open(int port, int listen_count = 5, bool ssl=false);
bool Reopen();
void Close();
void RunOnce(int msec);
void Run();
void SysMethods(bool on=true);
/**
* return wether the system methods are loaded.return wether the system methods are loaded
*/
bool IsSysMethodsLoaded() {return sysMethodsLoaded;}
void HandleRequest(Socket &s, Value &v);
/**
* return wether socket is open.return wether socket is open
*/
bool IsOpen() const { return socket.IsOpen(); }
/**
* return wether socket had an error.return wether socket had an error
*/
bool IsError() const { return socket.IsError(); }
/**
* return the port listening on.return the port listening on
*/
int GetPort() const { return server_port; }
/**
* get the server socket. get the server socket
*/
Socket& GetSocket() { return socket; }
};
/**
* @mainpage XML Remote Procedure Call implementation
* @version R23
*
* this is a XML rpc implementation for <a href="http://www.ultimatepp.org">Ultimate++</a>, the implementation follows the specification
* found at http://www.xmlrpc.com/spec
* @section Server
* a server can be created by using the XmlRpcServer class and its methods:
* @code
* //small server (NOT WORKING because XmlRpcMethod needs to be implemented)
* CONSOLE_APP_MAIN {
* XmlRpcMethod m("hello"); //create the hello method (in this case with NO FUNCTIONALITY and wrong signature
* XmlRpcServer server; //create the server
* server.SysMethods(); //switch on sys methods
* server.Add(&m); //add the method "hello"
* server.Open(8080); //listen on port 8080
* server.Run(); //and run
* }
* @endcode
* @see XmlRpcServer, XmlRpcMethod
*
* @section Client
* a client can be implemented by using the XmlRpcClient class.
* @code
* //function checking for methods on the server side
* void CheckForMethods(Value &v) {
* XmlRpcClient xmlClient; //client
* XmlRpcCall call("system.listMethods"); //call with sys method "listMethods"
*
* xmlClient.Host("www.ultimatepp.org"); //set Host
* xmlClient.Path("/server/index.php"); //set path
* xmlClient.Port(80); //and port to connect to
* v = xmlClient.Execute(call); //run the call
* }
* @endcode
* @see XmlRpcClient, XmlRpcCall
*/
#endif