libnavajo
web server for static and dynamic pages developement in C++
WebServer.hh
Go to the documentation of this file.
1 //********************************************************
12 //********************************************************
13 
14 #ifndef WEBSERVER_HH_
15 #define WEBSERVER_HH_
16 
17 
18 #include <stdio.h>
19 #include <sys/types.h>
20 #ifdef LINUX
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #endif
24 
25 #include <queue>
26 #include <string>
27 #include <map>
28 #include <openssl/ssl.h>
29 #include <openssl/err.h>
30 
31 #include "libnavajo/LogRecorder.hh"
32 #include "libnavajo/IpAddress.hh"
34 #include "libnavajo/nvjThread.h"
35 
36 
37 class WebSocket;
38 class WebServer
39 {
40  pthread_t threadWebServer;
41  SSL_CTX *sslCtx;
42  int s_server_session_id_context;
43  static char *certpass;
44 
45  std::queue<ClientSockData *> clientsQueue;
46  pthread_cond_t clientsQueue_cond;
47  pthread_mutex_t clientsQueue_mutex;
48 
49  void initialize_ctx(const char *certfile, const char *cafile, const char *password);
50  static int password_cb(char *buf, int num, int rwflag, void *userdata);
51 
52  bool isUserAllowed(const std::string &logpassb64, std::string &username);
53  bool isAuthorizedDN(const std::string str);
54 
55  size_t recvLine(int client, char *bufLine, size_t);
56  bool accept_request(ClientSockData* client);
57  void fatalError(const char *);
58  static std::string getHttpHeader(const char *messageType, const size_t len=0, const bool keepAlive=true, const bool zipped=false, HttpResponse* response=NULL);
59  static const char* get_mime_type(const char *name);
60  u_short init();
61 
62  static std::string getNoContentErrorMsg();
63  static std::string getBadRequestErrorMsg();
64  static std::string getNotFoundErrorMsg();
65  static std::string getInternalServerErrorMsg();
66  static std::string getNotImplementedErrorMsg();
67 
68  void initPoolThreads();
69  inline static void *startPoolThread(void *t)
70  {
71  static_cast<WebServer *>(t)->poolThreadProcessing();
72  pthread_exit(NULL);
73  return NULL;
74  };
75  void poolThreadProcessing();
76 
77  bool httpdAuth;
78 
79  volatile bool exiting;
80  volatile size_t exitedThread;
81  volatile int server_sock [ 3 ];
82  volatile size_t nbServerSock;
83 
84  const static char authStr[];
85 
86  std::map<std::string,time_t> usersAuthHistory;
87  pthread_mutex_t usersAuthHistory_mutex;
88  std::map<IpAddress,time_t> peerIpHistory;
89  std::map<std::string,time_t> peerDnHistory;
90  pthread_mutex_t peerDnHistory_mutex;
91  void updatePeerIpHistory(IpAddress&);
92  void updatePeerDnHistory(std::string);
93  static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx);
94  static const int verify_depth;
95 
96  static void* startThread(void* );
97  void threadProcessing();
98  void exit();
99 
100  static std::string webServerName;
101  bool disableIpV4, disableIpV6;
102  ushort tcpPort;
103  size_t threadsPoolSize;
104  std::string device;
105 
106  std::string mutipartTempDirForFileUpload;
107  long mutipartMaxCollectedDataLength;
108 
109  bool sslEnabled;
110  std::string sslCertFile, sslCaFile, sslCertPwd;
111  std::vector<std::string> authLoginPwdList;
112  bool authPeerSsl;
113  std::vector<std::string> authDnList;
114  std::vector<IpNetwork> hostsAllowed;
115  std::vector<WebRepository *> webRepositories;
116  static inline bool is_base64(unsigned char c)
117  { return (isalnum(c) || (c == '+') || (c == '/')); };
118  static const std::string base64_chars;
119  static std::string base64_decode(const std::string& encoded_string);
120  static std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
121  static void closeSocket(ClientSockData* client);
122  std::map<std::string, WebSocket *> webSocketEndPoints;
123  static std::string SHA1_encode(const std::string& input);
124  static const std::string webSocketMagicString;
125  static std::string generateWebSocketServerKey(std::string webSocketKey);
126  static std::string getHttpWebSocketHeader(const char *messageType, const char* webSocketClientKey, const bool webSocketDeflate);
127 
128  public:
129  WebServer();
130 
135  inline void setWebServerName(const std::string& name) { webServerName = name; }
136 
141  inline void setThreadsPoolSize(const size_t nbThread) { threadsPoolSize = nbThread; };
142 
147  inline void setServerPort(const ushort p) { tcpPort = p; };
148 
153  inline void setDevice(const char* d) { device = d; };
154 
161  inline void setUseSSL(bool ssl, const char* certFile = "", const char* certPwd = "")
162  { sslEnabled = ssl; sslCertFile = certFile; sslCertPwd = certPwd; };
163 
169  inline void setAuthPeerSSL(const bool a = true, const char* caFile = "") { authPeerSsl = a; sslCaFile = caFile; };
170 
175  inline void addAuthPeerDN(const char* dn) { authDnList.push_back(std::string(dn)); };
176 
182  inline void addLoginPass(const char* login, const char* pass) { authLoginPwdList.push_back(std::string(login)+':'+std::string(pass)); };
183 
188  inline void setMutipartTempDirForFileUpload(const std::string& pathdir) { mutipartTempDirForFileUpload = pathdir; };
189 
200  inline void setMutipartMaxCollectedDataLength(const long& max) { mutipartMaxCollectedDataLength = max; };
201 
206  void addRepository(WebRepository* repo) { webRepositories.push_back(repo); };
207 
213  void addWebSocket(const std::string endPoint, WebSocket* websocket) { webSocketEndPoints[endPoint]=websocket; };
214 
218  inline void listenIpV4only() { disableIpV6=true; };
219 
223  inline void listenIpV6only() { disableIpV4=true; };
224 
229  inline void addHostsAllowed(const IpNetwork &ipnet) { hostsAllowed.push_back(ipnet); };
230 
235  inline std::map<IpAddress,time_t>& getPeerIpHistory() { return peerIpHistory; };
236 
241  inline std::map<std::string,time_t>& getPeerDnHistory() { return peerDnHistory; };
242 
247  {
248  NVJ_LOG->append(NVJ_INFO, "WebServer: Service is starting !");
249  create_thread( &threadWebServer, WebServer::startThread, this );
250  };
251 
255  void stopService()
256  {
257  NVJ_LOG->append(NVJ_INFO, "WebServer: Service is stopping !");
258  exit();
259  threadWebServer=0;
260  };
261 
265  void wait()
266  {
267  wait_for_thread(threadWebServer);
268  };
269 
273  bool isRunning()
274  {
275  return threadWebServer != 0;
276  }
277 
278  static bool httpSend(ClientSockData *client, const void *buf, size_t len);
279 
280  inline static void freeClientSockData(ClientSockData *c)
281  {
282  if (c == NULL) return;
283  closeSocket(c);
284  if (c->peerDN != NULL) { delete c->peerDN; c->peerDN=NULL; }
285  free(c);
286  c=NULL;
287  };
288 };
289 
290 #endif
291 
Definition: WebRepository.hh:21
Definition: IpAddress.hh:64
void addWebSocket(const std::string endPoint, WebSocket *websocket)
Definition: WebServer.hh:213
Definition: WebServer.hh:38
std::map< IpAddress, time_t > & getPeerIpHistory()
Definition: WebServer.hh:235
Log Manager class.
void listenIpV4only()
Definition: WebServer.hh:218
Web Repository handler (abstract class)
void setServerPort(const ushort p)
Definition: WebServer.hh:147
void setAuthPeerSSL(const bool a=true, const char *caFile="")
Definition: WebServer.hh:169
void stopService()
Definition: WebServer.hh:255
void setWebServerName(const std::string &name)
Definition: WebServer.hh:135
void addAuthPeerDN(const char *dn)
Definition: WebServer.hh:175
void setUseSSL(bool ssl, const char *certFile="", const char *certPwd="")
Definition: WebServer.hh:161
void setDevice(const char *d)
Definition: WebServer.hh:153
std::map< std::string, time_t > & getPeerDnHistory()
Definition: WebServer.hh:241
void setMutipartTempDirForFileUpload(const std::string &pathdir)
Definition: WebServer.hh:188
void addLoginPass(const char *login, const char *pass)
Definition: WebServer.hh:182
Definition: IpAddress.hh:211
void setMutipartMaxCollectedDataLength(const long &max)
Definition: WebServer.hh:200
Definition: WebSocket.hh:27
void startService()
Definition: WebServer.hh:246
void setThreadsPoolSize(const size_t nbThread)
Definition: WebServer.hh:141
void addHostsAllowed(const IpNetwork &ipnet)
Definition: WebServer.hh:229
Definition: HttpResponse.hh:18
Ip Address (V4 and V6) class definition.
Definition: HttpRequest.hh:32
void wait()
Definition: WebServer.hh:265
thread&#39;s facilities
void listenIpV6only()
Definition: WebServer.hh:223
bool isRunning()
Definition: WebServer.hh:273
void addRepository(WebRepository *repo)
Definition: WebServer.hh:206