| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  | #ifndef HV_HTTP_SERVER_H_
 | 
					
						
							|  |  |  | #define HV_HTTP_SERVER_H_
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "hexport.h"
 | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  | #include "hssl.h"
 | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  | #include "HttpService.h"
 | 
					
						
							|  |  |  | // #include "WebSocketServer.h"
 | 
					
						
							|  |  |  | namespace hv { | 
					
						
							|  |  |  | struct WebSocketService; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | using hv::HttpService; | 
					
						
							|  |  |  | using hv::WebSocketService; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct http_server_s { | 
					
						
							|  |  |  |     char host[64]; | 
					
						
							|  |  |  |     int port; // http_port
 | 
					
						
							|  |  |  |     int https_port; | 
					
						
							|  |  |  |     int http_version; | 
					
						
							|  |  |  |     int worker_processes; | 
					
						
							|  |  |  |     int worker_threads; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  |     uint32_t worker_connections; // max_connections = workers * worker_connections
 | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  |     HttpService* service; // http service
 | 
					
						
							|  |  |  |     WebSocketService* ws; // websocket service
 | 
					
						
							|  |  |  |     void* userdata; | 
					
						
							|  |  |  |     int listenfd[2]; // 0: http, 1: https
 | 
					
						
							|  |  |  |     void* privdata; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  |     // hooks
 | 
					
						
							|  |  |  |     std::function<void()> onWorkerStart; | 
					
						
							|  |  |  |     std::function<void()> onWorkerStop; | 
					
						
							|  |  |  |     // SSL/TLS
 | 
					
						
							|  |  |  |     hssl_ctx_t  ssl_ctx; | 
					
						
							|  |  |  |     unsigned    alloced_ssl_ctx: 1; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  |     http_server_s() { | 
					
						
							|  |  |  |         strcpy(host, "0.0.0.0"); | 
					
						
							|  |  |  |         // port = DEFAULT_HTTP_PORT;
 | 
					
						
							|  |  |  |         // https_port = DEFAULT_HTTPS_PORT;
 | 
					
						
							|  |  |  |         // port = 8080;
 | 
					
						
							|  |  |  |         // https_port = 8443;
 | 
					
						
							|  |  |  |         port = https_port = 0; | 
					
						
							|  |  |  |         http_version = 1; | 
					
						
							|  |  |  |         worker_processes = 0; | 
					
						
							|  |  |  |         worker_threads = 0; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  |         worker_connections = 1024; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  |         service = NULL; | 
					
						
							|  |  |  |         ws = NULL; | 
					
						
							|  |  |  |         listenfd[0] = listenfd[1] = -1; | 
					
						
							|  |  |  |         userdata = NULL; | 
					
						
							|  |  |  |         privdata = NULL; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  |         // SSL/TLS
 | 
					
						
							|  |  |  |         ssl_ctx = NULL; | 
					
						
							|  |  |  |         alloced_ssl_ctx = 0; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } http_server_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // @param wait: Whether to occupy current thread
 | 
					
						
							|  |  |  | HV_EXPORT int http_server_run(http_server_t* server, int wait = 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NOTE: stop all loops and join all threads
 | 
					
						
							|  |  |  | HV_EXPORT int http_server_stop(http_server_t* server); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | #include "HttpServer.h"
 | 
					
						
							|  |  |  | using namespace hv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main() { | 
					
						
							|  |  |  |     HttpService service; | 
					
						
							|  |  |  |     service.GET("/ping", [](HttpRequest* req, HttpResponse* resp) { | 
					
						
							|  |  |  |         resp->body = "pong"; | 
					
						
							|  |  |  |         return 200; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     HttpServer server; | 
					
						
							|  |  |  |     server.registerHttpService(&service); | 
					
						
							|  |  |  |     server.setPort(8080); | 
					
						
							|  |  |  |     server.setThreadNum(4); | 
					
						
							|  |  |  |     server.run(); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace hv { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class HttpServer : public http_server_t { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  |     HttpServer(HttpService* service = NULL) | 
					
						
							|  |  |  |         : http_server_t() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         this->service = service; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  |     ~HttpServer() { stop(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void registerHttpService(HttpService* service) { | 
					
						
							|  |  |  |         this->service = service; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void setHost(const char* host = "0.0.0.0") { | 
					
						
							|  |  |  |         if (host) strcpy(this->host, host); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void setPort(int port = 0, int ssl_port = 0) { | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  |         if (port >= 0) this->port = port; | 
					
						
							|  |  |  |         if (ssl_port >= 0) this->https_port = ssl_port; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     void setListenFD(int fd = -1, int ssl_fd = -1) { | 
					
						
							|  |  |  |         if (fd >= 0) this->listenfd[0] = fd; | 
					
						
							|  |  |  |         if (ssl_fd >= 0) this->listenfd[1] = ssl_fd; | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void setProcessNum(int num) { | 
					
						
							|  |  |  |         this->worker_processes = num; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void setThreadNum(int num) { | 
					
						
							|  |  |  |         this->worker_threads = num; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-24 12:29:09 +08:00
										 |  |  |     // SSL/TLS
 | 
					
						
							|  |  |  |     int setSslCtx(hssl_ctx_t ssl_ctx) { | 
					
						
							|  |  |  |         this->ssl_ctx = ssl_ctx; | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     int newSslCtx(hssl_ctx_opt_t* opt) { | 
					
						
							|  |  |  |         // NOTE: hssl_ctx_free in http_server_stop
 | 
					
						
							|  |  |  |         hssl_ctx_t ssl_ctx = hssl_ctx_new(opt); | 
					
						
							|  |  |  |         if (ssl_ctx == NULL) return -1; | 
					
						
							|  |  |  |         this->alloced_ssl_ctx = 1; | 
					
						
							|  |  |  |         return setSslCtx(ssl_ctx); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-24 12:23:42 +08:00
										 |  |  |     int run(bool wait = true) { | 
					
						
							|  |  |  |         return http_server_run(this, wait); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int start() { | 
					
						
							|  |  |  |         return run(false); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int stop() { | 
					
						
							|  |  |  |         return http_server_stop(this); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // HV_HTTP_SERVER_H_
 |