RetroShare/libresapi/src/api/ApiServer.h

111 lines
3.8 KiB
C++

#pragma once
#include <retroshare/rsplugin.h>
#include "ApiTypes.h"
#include "PeersHandler.h"
#include "IdentityHandler.h"
#include "ForumHandler.h"
#include "ServiceControlHandler.h"
#include "StateTokenServer.h"
#include "FileSearchHandler.h"
#include "TransfersHandler.h"
#include "LivereloadHandler.h"
#include "TmpBlobStore.h"
#include "ChatHandler.h"
namespace resource_api{
class ApiServerMainModules;
// main entry point for all resource_api calls
// general part of the api server
// should work with any http library or a different transport protocol (e.g. SSH)
// call chain is like this:
// HTTP server -> ApiServer -> different handlers
// or
// GUI -> ApiServer -> different handlers
// multiple clients can use the same ApiServer instance at the same time
// ALL public methods in this class are thread safe
// this allows differen threads to send requests
class ApiServer
{
public:
ApiServer();
~ApiServer();
class RequestId{
public:
RequestId(): done(false), task(0), request(0), response(0){}
bool operator ==(const RequestId& r){
const RequestId& l = *this;
return (l.done==r.done)&&(l.task==r.task)&&(l.request==r.request)&&(l.response&&r.response);
}
private:
friend class ApiServer;
bool done; // this flag will be set to true, to signal the task id is valid and the task is done
// (in case there was no ResponseTask and task was zero)
ResponseTask* task; // null when the task id is invalid or when there was no task
Request* request;
Response* response;
};
// process the requestgiven by request and return the response as json string
// blocks until the request was processed
std::string handleRequest(Request& request);
// request and response must stay valid until isRequestDone returns true
// this method may do some work but it does not block
RequestId handleRequest(Request& request, Response& response);
// ticks the request
// returns true if the request is done or the id is invalid
// this method may do some work but it does not block
bool isRequestDone(RequestId id);
// load the main api modules
void loadMainModules(const RsPlugInInterfaces& ifaces);
// allows to add more handlers
// make sure the livetime of the handlers is longer than the api server
template <class T>
void addResourceHandler(std::string name, T* instance, ResponseTask* (T::*callback)(Request& req, Response& resp));
template <class T>
void addResourceHandler(std::string name, T* instance, void (T::*callback)(Request& req, Response& resp));
StateTokenServer* getStateTokenServer(){ return &mStateTokenServer; }
TmpBlobStore* getTmpBlobStore(){ return &mTmpBlobStore; }
private:
RsMutex mMtx;
StateTokenServer mStateTokenServer; // goes first, as others may depend on it
// is always loaded, because it has no dependencies
LivereloadHandler mLivereloadhandler;
TmpBlobStore mTmpBlobStore;
// only pointers here, to load/unload modules at runtime
ApiServerMainModules* mMainModules; // loaded when RS is started
ResourceRouter mRouter;
std::vector<RequestId> mRequests;
};
// implementations
template <class T>
void ApiServer::addResourceHandler(std::string name, T* instance, ResponseTask* (T::*callback)(Request& req, Response& resp))
{
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mRouter.addResourceHandler(name, instance, callback);
}
template <class T>
void ApiServer::addResourceHandler(std::string name, T* instance, void (T::*callback)(Request& req, Response& resp))
{
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
mRouter.addResourceHandler(name, instance, callback);
}
}