-
Notifications
You must be signed in to change notification settings - Fork 145
/
Server.h
333 lines (243 loc) · 11.2 KB
/
Server.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#pragma once
#define NO_INTERFACE
#ifdef _WIN32
# include <thread>
#else
# include <pthread.h>
#endif
#include "Interface/Server.h"
#include "Interface/Action.h"
#include "Interface/Mutex.h"
#include "Interface/Condition.h"
#include "Interface/SharedMutex.h"
#include "LookupService.h"
#include <vector>
#include <fstream>
#include <memory>
typedef void(*LOADACTIONS)(IServer*);
typedef void(*UNLOADACTIONS)(void);
#ifdef _WIN32
#include <windows.h>
#else
typedef void *HMODULE;
#endif
class FCGIRequest;
class IDatabaseInt;
class IDatabaseFactory;
class CSessionMgr;
class CServiceAcceptor;
class CThreadPool;
class IOutputStream;
struct SDatabase
{
SDatabase(IDatabaseFactory *factory, const std::string &file)
: factory(factory), file(file), allocation_chunk_size(std::string::npos)
{}
IDatabaseFactory *factory;
std::string file;
std::map<THREAD_ID, IDatabaseInt*> tmap;
std::vector<std::pair<std::string,std::string> > attach;
size_t allocation_chunk_size;
std::unique_ptr<ISharedMutex> single_user_mutex;
std::unique_ptr<IMutex> lock_mutex;
std::unique_ptr<int> lock_count;
std::unique_ptr<ICondition> unlock_cond;
str_map params;
private:
SDatabase(const SDatabase& other) {}
void operator=(const SDatabase& other){}
};
class CServer : public IServer
{
public:
CServer();
~CServer();
void setup(void);
void setServerParameters(const str_map &pServerParams);
virtual std::string getServerParameter(const std::string &key);
virtual std::string getServerParameter(const std::string &key, const std::string &def);
virtual void setServerParameter(const std::string &key, const std::string &value);
virtual void setLogLevel(int LogLevel);
virtual void setLogFile(const std::string &plf, std::string chown_user="");
virtual void setLogCircularBufferSize(size_t size);
virtual std::vector<SCircularLogEntry> getCicularLogBuffer(size_t minid);
virtual void Log(const std::string &pStr, int LogLevel=LL_INFO);
virtual void setLogRotationFiles(size_t n);
virtual bool Write(THREAD_ID tid, const std::string &str, bool cached=true);
virtual bool WriteRaw(THREAD_ID tid, const char *buf, size_t bsize, bool cached=true);
virtual void setContentType(THREAD_ID tid, const std::string &str);
virtual void addHeader(THREAD_ID tid, const std::string &str);
THREAD_ID Execute(const std::string &action, const std::string &context, str_map &GET, str_map &POST, str_map &PARAMS, IOutputStream *req);
std::string Execute(const std::string &action, const std::string &context, str_map &GET, str_map &POST, str_map &PARAMS);
virtual void AddAction(IAction *action);
virtual bool RemoveAction(IAction *action);
virtual void setActionContext(std::string context);
virtual void resetActionContext(void);
virtual void addWebSocket(IWebSocket* websocket);
virtual THREAD_ID ExecuteWebSocket(const std::string& name, str_map& GET, str_map& PARAMS, IPipe* pipe, const std::string& endpoint_name);
virtual int64 getTimeSeconds(void);
virtual int64 getTimeMS(void);
virtual bool LoadDLL(const std::string &name);
virtual bool UnloadDLL(const std::string &name);
void LoadStaticPlugins();
virtual void destroy(IObject *obj);
virtual void wait(unsigned int ms);
virtual ITemplate* createTemplate(std::string pFile);
virtual IMutex* createMutex(void);
virtual ISharedMutex* createSharedMutex();
virtual ICondition* createCondition(void);
virtual IPipe *createMemoryPipe(void);
virtual bool createThread(IThread *thread, const std::string& name = std::string(), CreateThreadFlags flags = CreateThreadFlags_None);
virtual void setCurrentThreadName(const std::string& name);
virtual IThreadPool *getThreadPool(void);
virtual ISettingsReader* createFileSettingsReader(const std::string& pFile);
virtual ISettingsReader* createDBSettingsReader(THREAD_ID tid, DATABASE_ID pIdentifier, const std::string &pTable, const std::string &pSQL="");
virtual ISettingsReader* createDBSettingsReader(IDatabase *db, const std::string &pTable, const std::string &pSQL="");
virtual ISettingsReader* createDBMemSettingsReader(THREAD_ID tid, DATABASE_ID pIdentifier, const std::string &pTable, const std::string &pSQL = "");
virtual ISettingsReader* createDBMemSettingsReader(IDatabase *db, const std::string &pTable, const std::string &pSQL = "");
virtual ISettingsReader* createMemorySettingsReader(const std::string &pData);
virtual IPipeThrottler* createPipeThrottler(size_t bps, bool percent_max);
virtual IPipeThrottler* createPipeThrottler(IPipeThrottlerUpdater* updater);
virtual IThreadPool* createThreadPool(size_t max_threads, size_t max_waiting_threads, const std::string& idle_name);
virtual bool openDatabase(std::string pFile, DATABASE_ID pIdentifier, const str_map& params = str_map(), std::string pEngine="sqlite");
virtual IDatabase* getDatabase(THREAD_ID tid, DATABASE_ID pIdentifier);
virtual void destroyAllDatabases(void);
virtual void destroyDatabases(THREAD_ID tid);
virtual ISessionMgr *getSessionMgr(void);
virtual IPlugin* getPlugin(THREAD_ID tid, PLUGIN_ID pIdentifier);
virtual THREAD_ID getThreadID(void);
virtual std::string ConvertToUTF16(const std::string &input);
virtual std::string ConvertToUTF32(const std::string &input);
virtual std::wstring ConvertToWchar(const std::string &input);
virtual std::string ConvertFromWchar(const std::wstring &input);
virtual std::string ConvertFromUTF16(const std::string &input);
virtual std::string ConvertFromUTF32(const std::string &input);
virtual std::string GenerateHexMD5(const std::string &input);
virtual std::string GenerateBinaryMD5(const std::string &input);
virtual void StartCustomStreamService(IService *pService, std::string pServiceName, unsigned short pPort, int pMaxClientsPerThread=-1, IServer::BindTarget bindTarget=IServer::BindTarget_All);
virtual IPipe* ConnectStream(std::string pServer, unsigned short pPort, unsigned int pTimeoutms);
virtual IPipe* ConnectSslStream(const std::string& pServer, unsigned short pPort, unsigned int pTimeoutms);
virtual IPipe *PipeFromSocket(SOCKET pSocket);
virtual void DisconnectStream(IPipe *pipe);
virtual std::string LookupHostname(const std::string& pIp);
virtual bool RegisterPluginPerThreadModel(IPluginMgr *pPluginMgr, std::string pName);
virtual bool RegisterPluginThreadsafeModel(IPluginMgr *pPluginMgr, std::string pName);
virtual PLUGIN_ID StartPlugin(std::string pName, str_map ¶ms);
virtual bool RestartPlugin(PLUGIN_ID pIdentifier);
virtual unsigned int getNumRequests(void);
virtual void addRequest(void);
virtual IFsFile* openFile(std::string pFilename, int pMode=0);
virtual IFsFile* openFileFromHandle(void *handle, const std::string& pFilename);
virtual IFsFile* openTemporaryFile(void);
virtual IMemFile* openMemoryFile(const std::string& name, bool mlock_mem);
virtual bool deleteFile(std::string pFilename);
virtual bool fileExists(std::string pFilename);
virtual POSTFILE_KEY getPostFileKey();
virtual void addPostFile(POSTFILE_KEY pfkey, const std::string &name, const SPostfile &pf);
virtual SPostfile getPostFile(POSTFILE_KEY pfkey, const std::string &name);
virtual void clearPostFiles(POSTFILE_KEY pfkey);
virtual std::string getServerWorkingDir(void);
void setServerWorkingDir(const std::string &wdir);
void ShutdownPlugins(void);
void setTemporaryDirectory(const std::string &dir);
virtual void registerDatabaseFactory(const std::string &pEngineName, IDatabaseFactory *factory);
virtual bool hasDatabaseFactory(const std::string &pEngineName);
virtual bool attachToDatabase(const std::string &pFile, const std::string &pName, DATABASE_ID pIdentifier);
virtual bool setDatabaseAllocationChunkSize(DATABASE_ID pIdentifier, size_t allocation_chunk_size);
static int WriteDump(void* pExceptionPointers);
virtual void waitForStartupComplete(void);
void startupComplete(void);
void shutdown(void);
void initRandom(unsigned int seed);
virtual unsigned int getRandomNumber(void);
virtual std::vector<unsigned int> getRandomNumbers(size_t n);
virtual void randomFill(char *buf, size_t blen);
virtual unsigned int getSecureRandomNumber(void);
virtual std::vector<unsigned int> getSecureRandomNumbers(size_t n);
virtual void secureRandomFill(char *buf, size_t blen);
virtual std::string secureRandomString(size_t len);
virtual void setFailBit(size_t failbit);
virtual void clearFailBit(size_t failbit);
virtual size_t getFailBits(void);
virtual void clearDatabases(THREAD_ID tid);
void setLogRotationFilesize(size_t filesize);
void setLogRotationNumFiles(size_t numfiles);
void setLogConsoleTime(bool b);
#ifdef _WIN32
void setSocketWindowSizes(int p_send_window_size, int p_recv_window_size);
virtual int getSendWindowSize();
virtual int getRecvWindowSize();
#endif
void mallocFlushTcache();
private:
void logToCircularBuffer(const std::string& msg, int loglevel);
bool UnloadDLLs(void);
void UnloadDLLs2(void);
void rotateLogfile();
IPipe* ConnectStream(const SLookupBlockingResult& lookup_result, unsigned short pPort, unsigned int pTimeoutms);
int loglevel;
bool logfile_a;
std::fstream logfile;
IMutex* log_mutex;
IMutex* action_mutex;
IMutex* web_socket_mutex;
IMutex* requests_mutex;
IMutex* outputs_mutex;
IMutex* db_mutex;
IMutex* thread_mutex;
IMutex* plugin_mutex;
IMutex* rps_mutex;
IMutex* postfiles_mutex;
IMutex* param_mutex;
IMutex* startup_complete_mutex;
IMutex* rnd_mutex;
ICondition *startup_complete_cond;
bool startup_complete;
std::map< std::string, std::map<std::string, IAction*> > actions;
std::map<std::string, IWebSocket*> web_sockets;
std::map<std::string, UNLOADACTIONS> unload_functs;
std::vector<HMODULE> unload_handles;
std::map<THREAD_ID, IOutputStream*> current_requests;
std::map<THREAD_ID, std::pair<bool, std::string> > current_outputs;
THREAD_ID curr_thread_id;
#ifdef _WIN32
std::map<std::thread::id, THREAD_ID> threads;
#else
std::map<pthread_t, THREAD_ID> threads;
#endif
std::map<DATABASE_ID, SDatabase*> databases;
CSessionMgr *sessmgr;
std::vector<CServiceAcceptor*> stream_services;
std::map<PLUGIN_ID, std::map<THREAD_ID, IPlugin*> > perthread_plugins;
std::map<std::string, IPluginMgr*> perthread_pluginmgrs;
std::map<PLUGIN_ID, std::pair<IPluginMgr*,str_map> > perthread_pluginparams;
std::map<std::string, IPluginMgr*> threadsafe_pluginmgrs;
std::map<PLUGIN_ID, IPlugin*> threadsafe_plugins;
std::map<POSTFILE_KEY, std::map<std::string, SPostfile > > postfiles;
POSTFILE_KEY curr_postfilekey;
str_map server_params;
PLUGIN_ID curr_pluginid;
unsigned int num_requests;
CThreadPool* threadpool;
std::string action_context;
std::string workingdir;
std::string tmpdir;
std::map<std::string, IDatabaseFactory*> database_factories;
size_t circular_log_buffer_id;
std::vector<SCircularLogEntry> circular_log_buffer;
size_t circular_log_buffer_idx;
bool has_circular_log_buffer;
size_t failbits;
std::string logfile_fn;
std::string logfile_chown_user;
size_t log_rotation_size;
bool log_console_time;
size_t log_rotation_files;
#ifdef _WIN32
int send_window_size;
int recv_window_size;
#endif
};
#ifndef DEF_SERVER
extern IServer *Server;
#endif