#pragma once #include #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 void addResourceHandler(std::string name, T* instance, ResponseTask* (T::*callback)(Request& req, Response& resp)); template 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 mRequests; }; // implementations template 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 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); } }