From e36c6351a3ded2d1915d7d275d711b603c91c464 Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Sat, 15 Apr 2023 18:53:33 +0800 Subject: [PATCH 1/9] fix bug line 7343, ">" to "<" --- common/mongoose.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/mongoose.c b/common/mongoose.c index 3a7ed94..474b484 100644 --- a/common/mongoose.c +++ b/common/mongoose.c @@ -7340,7 +7340,7 @@ MG_INTERNAL void mg_send_http_file(struct mg_connection *nc, char *path, } /* If we have path_info, the only way to handle it is CGI. */ - if (path_info->len > 0 && !is_cgi) { + if (path_info->len < 0 && !is_cgi) { mg_http_send_error(nc, 501, NULL); MG_FREE(index_file); return; From 4d70c9482154eec258514dd87eecb6c359a1d135 Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Sat, 15 Apr 2023 19:06:15 +0800 Subject: [PATCH 2/9] Update http_client.cpp --- httpclient/http_client.cpp | 426 +++++++++++++++++++++++++++++++++---- 1 file changed, 380 insertions(+), 46 deletions(-) diff --git a/httpclient/http_client.cpp b/httpclient/http_client.cpp index c94dac8..bf75065 100644 --- a/httpclient/http_client.cpp +++ b/httpclient/http_client.cpp @@ -1,64 +1,398 @@ -#include "http_client.h" +#include +#include "http_server.h" +#include +#include +#include +#include "time.h" +#include "../common/functions.h" +#define cookielen 8 -// 初始化client静态变量 -int HttpClient::s_exit_flag = 0; -ReqCallback HttpClient::s_req_callback; +using namespace std; -// 客户端的网络请求响应 -void HttpClient::OnHttpEvent(mg_connection *connection, int event_type, void *event_data) +int counting_req = 0; + +struct requestMessage { + string keywords[20] = {}; + string Fn = "", url, httpVersion; + string reqinfo[40] = {}; + char body[]; + + string findInfo(string Name_info) { + + } + + void readIn(string req) { + int i = 0; + while (req[i] != ' ') { + this->Fn += req[i]; + i++; + } + cout << this->Fn; + i+=url.length()+2; + while (req[i] != '\r') { + this->httpVersion += req[i]; + i++; + } + int flag = 0, black = 0; + for (; i < req.length(); i++) { + if (req[i] == '\r') { + if (black == 0) { + break; + } + black = 0; + flag++; + i++; + continue; + } + black++; + this->reqinfo[flag] += req[i]; + } + if (this->Fn == "POST") { + + } + } +}; + + +long long time_now_sec() { - http_message *hm = (struct http_message *)event_data; - int connect_status; + time_t tv; + tv = time(NULL);//time(&tv); get current time; + //std::cout << tv << std::endl;//璺濈1970-01-01 00:00:00缁忓巻鐨勭鏁 + return tv; +} - switch (event_type) - { - case MG_EV_CONNECT: - connect_status = *(int *)event_data; - if (connect_status != 0) - { - printf("Error connecting to server, error code: %d\n", connect_status); - s_exit_flag = 1; +string time_now_str() { + time_t tv; + tv = time(NULL);//time(&tv); get current time; + return ctime(&tv); +} + +struct user { + /* + *level: 0==guest,1==user,2==admin,3==root + * User can not use this website if tis able == false; + */ + string name = ""; + string password = ""; + int ID = 0; + string cookie = ""; + string time_str_creation_cookie = ""; + long long time_num_creation_cookie = 0; + bool able = false; + int level = -1; + string level_str = ""; + + bool logined = false; + bool time_login = ""; + int login(string username, string password) { + /*If the funcution returns 0,username or password can't be matched. + * If -1 is returned ,the user has been disabled. + * If 1 is returned ,login is allowed. + * If 2 is returned ,the user is logined. + */ + + if (username == this->name && password == this->password) { + if (this->logined == true) { + return 2; + } + if (this->able) { + this->logined = true; + return 1; + }else{ + return -1; + } + }else{ + return 0; } - break; - case MG_EV_HTTP_REPLY: + } + bool login_cookie(string cookie) { + if (cookie == this->cookie && this->able&&this->time_num_creation_cookie <= time_now_sec()) { + this->logined = true; + return true; + } + else if(this->time_num_creation_cookie > time_now_sec()){ + this->cookie = ""; + } + return false; + } + + void read_in( + int ID, + string name, + int level, + string password, + string cookie, + bool creation_time_cookie + + ) { + switch (level) { + case 0: + this->level_str += "Guset"; + break; + case 1: + this->level_str += "User"; + break; + case 2: + this->level_str += "Admin"; + break; + case 3: + this->level_str += "Root"; + break; + default: + this->level_str += "Error"; + } + this->cookie += cookie; + this->time_str_creation_cookie += creation_time_cookie; + this->ID = ID; + this->name += name; + this->password += password; + } +}users[44]; + +void readin() { + int ID; + string name; + int level; + string password; + string cookie; + bool creation_time_cookie; + FILE* stream1; + freopen_s(&stream1, "userinfo.dba", "r", stdin); + for (int i = 0; i < 44; i++) { + cin >> ID >> name >> level >> password >> cookie >> creation_time_cookie; + users[i].read_in(ID, name, level, password, cookie, creation_time_cookie); + } + fclose(stdin); +} + + + + +void HttpServer::Init(const std::string& port) +{ + m_port = port; + s_server_option.enable_directory_listing = "yes"; + s_server_option.document_root = s_web_dir.c_str(); + + // 锟斤拷锟斤拷http锟斤拷锟斤拷 + + // 锟斤拷锟斤拷 CORS锟斤拷锟斤拷锟斤拷只锟斤拷锟斤拷锟揭筹拷锟斤拷锟斤拷锟叫 + // s_server_option.extra_headers = "Access-Control-Allow-Origin: *"; +} + +bool HttpServer::Start() +{ + mg_mgr_init(&m_mgr, NULL); + mg_connection* connection = mg_bind(&m_mgr, m_port.c_str(), HttpServer::OnHttpWebsocketEvent); + if (connection == NULL) + return false; + + thread stat01(readin); + + // for both http and websocket + thread stat02(mg_set_protocol_http_websocket,connection); + + printf("starting http server at port: %s\n", m_port.c_str()); + + stat01.join(); + stat02.join(); + + // loop + while (true) + mg_mgr_poll(&m_mgr, 500); // ms + + return true; +} + +void HttpServer::OnHttpWebsocketEvent(mg_connection* connection, int event_type, void* event_data) +{ + // 锟斤拷锟斤拷http锟斤拷websocket + if (event_type == MG_EV_HTTP_REQUEST) + { + http_message* http_req = (http_message*)event_data; + std::thread HandleHttpEvent(HttpServer::HandleHttpEvent, connection, http_req); + HandleHttpEvent.join(); + //HandleHttpEvent(connection, http_req); + } + else if (event_type == MG_EV_WEBSOCKET_HANDSHAKE_DONE || + event_type == MG_EV_WEBSOCKET_FRAME || + event_type == MG_EV_CLOSE) + { + websocket_message* ws_message = (struct websocket_message*)event_data; + HandleWebsocketMessage(connection, event_type, ws_message); + } + +} + +// ---- simple http ---- // +static bool route_check(http_message* http_msg, char* route_prefix) +{ + if (mg_vcmp(&http_msg->uri, route_prefix) == 0) + return true; + else + return false; + + // TODO: 锟斤拷锟斤拷锟斤拷锟叫讹拷 GET, POST, PUT, DELTE锟饺凤拷锟斤拷 + //mg_vcmp(&http_msg->method, "GET"); + //mg_vcmp(&http_msg->method, "POST"); + //mg_vcmp(&http_msg->method, "PUT"); + //mg_vcmp(&http_msg->method, "DELETE"); +} + +void HttpServer::AddHandler(const std::string& url, ReqHandler req_handler) +{ + if (s_handler_map.find(url) != s_handler_map.end()) + return; + + s_handler_map.insert(std::make_pair(url, req_handler)); +} + +void HttpServer::RemoveHandler(const std::string& url) +{ + auto it = s_handler_map.find(url); + if (it != s_handler_map.end()) + s_handler_map.erase(it); +} + +void HttpServer::SendHttpRsp(mg_connection* connection, std::string rsp) +{ + // --- 未锟斤拷锟斤拷CORS + // 锟斤拷锟斤拷锟饺凤拷锟斤拷header, 锟斤拷时锟斤拷锟斤拷锟斤拷锟斤拷HTTP/2.0 + mg_printf(connection, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); + // 锟斤拷json锟斤拷式锟斤拷锟斤拷 + mg_printf_http_chunk(connection, "{ \"result\": %s }", rsp.c_str()); + // 锟斤拷锟酵空帮拷锟街凤拷锟届,锟斤拷锟斤拷锟斤拷前锟斤拷应 + mg_send_http_chunk(connection, "", 0); + + // --- 锟斤拷锟斤拷CORS + /*mg_printf(connection, "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\n" + "Cache-Control: no-cache\n" + "Content-Length: %d\n" + "Access-Control-Allow-Origin: *\n\n" + "%s\n", rsp.length(), rsp.c_str()); */ +} + +void HttpServer::HandleHttpEvent(mg_connection* connection, http_message* http_req) +{ + std::string req_str = std::string(http_req->message.p, http_req->message.len); + counting_req++; + cout << "Time:" << time_now_sec()<<" counting:"<uri.p, http_req->uri.len); + std::string body = std::string(http_req->body.p, http_req->body.len); + auto it = s_handler_map.find(url); + if (it != s_handler_map.end()) { - printf("Got reply:\n%.*s\n", (int)hm->body.len, hm->body.p); - std::string rsp = std::string(hm->body.p, hm->body.len); - connection->flags |= MG_F_SEND_AND_CLOSE; - s_exit_flag = 1; // 每次收到请求后关闭本次连接,重置标记 - - // 回调处理 - s_req_callback(rsp); + ReqHandler handle_func = it->second; + handle_func(url, body, connection, &HttpServer::SendHttpRsp); } + + // 锟斤拷锟斤拷锟斤拷锟斤拷 + + requestMessage req; + + req.url.resize(url.length()); + req.url = url; + req.readIn(req_str); + + switch (hash_(url.c_str())) + { + case "/a"_hash: + SendHttpRsp(connection, "AAAAA"); break; - case MG_EV_CLOSE: - if (s_exit_flag == 0) - { - printf("Server closed connection\n"); - s_exit_flag = 1; - }; + case "/api/hello"_hash: + SendHttpRsp(connection, "welcome to httpserver"); break; - default: + case "/api/sum"_hash: + // 锟斤拷post锟斤拷锟襟,加凤拷锟斤拷锟斤拷锟斤拷锟 + char n1[100], n2[100]; + double result; + /* Get form variables */ + mg_get_http_var(&http_req->body, "n1", n1, sizeof(n1)); + mg_get_http_var(&http_req->body, "n2", n2, sizeof(n2)); + /* Compute the result and send it back as a JSOt object */ + result = strtod(n1, NULL) + strtod(n2, NULL); + SendHttpRsp(connection, std::to_string(result)); break; + case "/server.html"_hash: + mg_serve_http(connection, http_req, s_server_option); + break; + default: + mg_serve_http(connection, http_req, s_server_option); } + + //mg_printf( + //connection, + //:"%s", + //"HTTP/1.1 501 Not Implemented\r\n" + //"Content-Length: 0\r\n\r\n"); } -// 发送一次请求,并回调处理,然后关闭本次连接 -void HttpClient::SendReq(const std::string &url, ReqCallback req_callback) +// ---- websocket ---- // +int HttpServer::isWebsocket(const mg_connection* connection) { - // 给回调函数赋值 - s_req_callback = req_callback; - mg_mgr mgr; - mg_mgr_init(&mgr, NULL); - auto connection = mg_connect_http(&mgr, OnHttpEvent, url.c_str(), NULL, NULL); - mg_set_protocol_http_websocket(connection); + return connection->flags & MG_F_IS_WEBSOCKET; +} - printf("Send http request %s\n", url.c_str()); +void HttpServer::HandleWebsocketMessage(mg_connection* connection, int event_type, websocket_message* ws_msg) +{ + if (event_type == MG_EV_WEBSOCKET_HANDSHAKE_DONE) + { + printf("client websocket connected\n"); + // 锟斤拷取锟斤拷锟接客伙拷锟剿碉拷IP锟酵端匡拷 + char addr[32]; + mg_sock_addr_to_str(&connection->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); + printf("client addr: %s\n", addr); - // loop - while (s_exit_flag == 0) - mg_mgr_poll(&mgr, 500); + // 锟斤拷锟 session + s_websocket_session_set.insert(connection); - mg_mgr_free(&mgr); -} \ No newline at end of file + SendWebsocketMsg(connection, "client websocket connected"); + } + else if (event_type == MG_EV_WEBSOCKET_FRAME) + { + mg_str received_msg = { + (char*)ws_msg->data, ws_msg->size + }; + + char buff[1024] = { 0 }; + strncpy(buff, received_msg.p, received_msg.len); // must use strncpy, specifiy memory pointer and length + + // do sth to process request + printf("received msg: %s\n", buff); + SendWebsocketMsg(connection, "send your msg back: " + std::string(buff)); + //BroadcastWebsocketMsg("broadcast msg: " + std::string(buff)); + } + else if (event_type == MG_EV_CLOSE) + { + if (isWebsocket(connection)) + { + printf("client websocket closed\n"); + // 锟狡筹拷session + if (s_websocket_session_set.find(connection) != s_websocket_session_set.end()) + s_websocket_session_set.erase(connection); + } + } +} + +void HttpServer::SendWebsocketMsg(mg_connection* connection, std::string msg) +{ + mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, msg.c_str(), strlen(msg.c_str())); +} + +void HttpServer::BroadcastWebsocketMsg(std::string msg) +{ + for (mg_connection* connection : s_websocket_session_set) + mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, msg.c_str(), strlen(msg.c_str())); +} + +bool HttpServer::Close() +{ + mg_mgr_free(&m_mgr); + return true; +} From 876918f6f1c0d1501cacd112a7597764367df461 Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Sat, 15 Apr 2023 19:06:55 +0800 Subject: [PATCH 3/9] Update http_client.h --- httpclient/http_client.h | 54 ++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/httpclient/http_client.h b/httpclient/http_client.h index 0370998..55d5a59 100644 --- a/httpclient/http_client.h +++ b/httpclient/http_client.h @@ -1,19 +1,51 @@ #pragma once + #include +#include +#include +#include #include #include "../common/mongoose.h" +#include "../common/winini.h" -// 此处必须用function类,typedef再后面函数指针赋值无效 -using ReqCallback = std::function; +// 锟斤拷锟斤拷http锟斤拷锟斤拷callback +typedef void OnRspCallback(mg_connection *c, std::string); +// 锟斤拷锟斤拷http锟斤拷锟斤拷handler +using ReqHandler = std::function; -class HttpClient +class HttpServer { public: - HttpClient() {} - ~HttpClient() {} - - static void SendReq(const std::string &url, ReqCallback req_callback); - static void OnHttpEvent(mg_connection *connection, int event_type, void *event_data); - static int s_exit_flag; - static ReqCallback s_req_callback; -}; \ No newline at end of file + HttpServer() { + CMyINI* ini = new CMyINI(); + ini->ReadINI("D:/C++/Projects/Network/Server/x64/Debug/regedit.ini"); + s_web_dir = ini->GetValue("dir", "web");} + ~HttpServer() {} + void Init(const std::string &port); // 锟斤拷始锟斤拷锟斤拷锟斤拷 + bool Start(); // 锟斤拷锟絟ttpserver + bool Close(); // 锟截憋拷 + void AddHandler(const std::string &url, ReqHandler req_handler); // 注锟斤拷锟铰硷拷锟斤拷锟斤拷锟斤拷锟 + void RemoveHandler(const std::string &url); // 锟狡筹拷时锟戒处锟斤拷锟斤拷锟 + //static std::string s_web_dir; // 锟斤拷页锟斤拷目录 + + static mg_serve_http_opts s_server_option; // web锟斤拷锟斤拷锟斤拷选锟斤拷 + static std::unordered_map s_handler_map; // 锟截碉拷锟斤拷锟斤拷映锟斤拷锟 +private: + // 锟斤拷态锟铰硷拷锟斤拷应锟斤拷锟斤拷 + std::string s_web_dir; + + static void OnHttpWebsocketEvent(mg_connection *connection, int event_type, void *event_data); + + static void HandleHttpEvent(mg_connection *connection, http_message *http_req); + static void SendHttpRsp(mg_connection *connection, std::string rsp); + + static int isWebsocket(const mg_connection *connection); // 锟叫讹拷锟角凤拷锟斤拷websoket锟斤拷锟斤拷锟斤拷锟斤拷 + static void HandleWebsocketMessage(mg_connection *connection, int event_type, websocket_message *ws_msg); + static void SendWebsocketMsg(mg_connection *connection, std::string msg); // 锟斤拷锟斤拷锟斤拷息锟斤拷指锟斤拷锟斤拷锟斤拷 + static void BroadcastWebsocketMsg(std::string msg); // 锟斤拷锟斤拷锟斤拷锟斤拷锟接广播锟斤拷息 + static std::unordered_set s_websocket_session_set; // 锟斤拷锟斤拷websocket锟斤拷锟斤拷 + + std::string m_port; // 锟剿匡拷 + mg_mgr m_mgr; // 锟斤拷锟接癸拷锟斤拷锟斤拷 +}; + From 3e840a0bc131988d426b8eab29b33a30d68c06a7 Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Sat, 15 Apr 2023 20:04:06 +0800 Subject: [PATCH 4/9] Update http_server.h --- httpserver/http_server.h | 85 ++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/httpserver/http_server.h b/httpserver/http_server.h index c8f8adf..c287c10 100644 --- a/httpserver/http_server.h +++ b/httpserver/http_server.h @@ -7,9 +7,60 @@ #include #include "../common/mongoose.h" -// 定义http返回callback +// 瀹氫箟http杩斿洖callback +typedef void OnRspCallback(mg_connection *c, std::string);#pragma once + +#include +#include +#include +#include +#include +#include "../common/mongoose.h" +#include "../common/winini.h" + +// 瀹氫箟http杩斿洖callback typedef void OnRspCallback(mg_connection *c, std::string); -// 定义http请求handler +// 瀹氫箟http璇锋眰handler +using ReqHandler = std::function; + +class HttpServer +{ +public: + HttpServer() { + CMyINI* ini = new CMyINI(); + ini->ReadINI("D:/C++/Projects/Network/Server/x64/Debug/regedit.ini"); + s_web_dir = ini->GetValue("dir", "web");} + ~HttpServer() {} + void Init(const std::string &port); // 鍒濆鍖栬缃 + bool Start(); // 鍚姩httpserver + bool Close(); // 鍏抽棴 + void AddHandler(const std::string &url, ReqHandler req_handler); // 娉ㄥ唽浜嬩欢澶勭悊鍑芥暟 + void RemoveHandler(const std::string &url); // 绉婚櫎鏃堕棿澶勭悊鍑芥暟 + //static std::string s_web_dir; // 缃戦〉鏍圭洰褰 + + static mg_serve_http_opts s_server_option; // web鏈嶅姟鍣ㄩ夐」 + static std::unordered_map s_handler_map; // 鍥炶皟鍑芥暟鏄犲皠琛 +private: + // 闈欐佷簨浠跺搷搴斿嚱鏁 + std::string s_web_dir; + + static void OnHttpWebsocketEvent(mg_connection *connection, int event_type, void *event_data); + + static void HandleHttpEvent(mg_connection *connection, http_message *http_req); + static void SendHttpRsp(mg_connection *connection, std::string rsp); + + static int isWebsocket(const mg_connection *connection); // 鍒ゆ柇鏄惁鏄痺ebsoket绫诲瀷杩炴帴 + static void HandleWebsocketMessage(mg_connection *connection, int event_type, websocket_message *ws_msg); + static void SendWebsocketMsg(mg_connection *connection, std::string msg); // 鍙戦佹秷鎭埌鎸囧畾杩炴帴 + static void BroadcastWebsocketMsg(std::string msg); // 缁欐墍鏈夎繛鎺ュ箍鎾秷鎭 + static std::unordered_set s_websocket_session_set; // 缂撳瓨websocket杩炴帴 + + std::string m_port; // 绔彛 + mg_mgr m_mgr; // 杩炴帴绠$悊鍣 +}; + + +// 瀹氫箟http璇锋眰handler using ReqHandler = std::function; class HttpServer @@ -17,29 +68,29 @@ class HttpServer public: HttpServer() {} ~HttpServer() {} - void Init(const std::string &port); // 初始化设置 - bool Start(); // 启动httpserver - bool Close(); // 关闭 - void AddHandler(const std::string &url, ReqHandler req_handler); // 注册事件处理函数 - void RemoveHandler(const std::string &url); // 移除时间处理函数 - static std::string s_web_dir; // 网页根目录 - static mg_serve_http_opts s_server_option; // web服务器选项 - static std::unordered_map s_handler_map; // 回调函数映射表 + void Init(const std::string &port); // 鍒濆鍖栬缃 + bool Start(); // 鍚姩httpserver + bool Close(); // 鍏抽棴 + void AddHandler(const std::string &url, ReqHandler req_handler); // 娉ㄥ唽浜嬩欢澶勭悊鍑芥暟 + void RemoveHandler(const std::string &url); // 绉婚櫎鏃堕棿澶勭悊鍑芥暟 + static std::string s_web_dir; // 缃戦〉鏍圭洰褰 + static mg_serve_http_opts s_server_option; // web鏈嶅姟鍣ㄩ夐」 + static std::unordered_map s_handler_map; // 鍥炶皟鍑芥暟鏄犲皠琛 private: - // 静态事件响应函数 + // 闈欐佷簨浠跺搷搴斿嚱鏁 static void OnHttpWebsocketEvent(mg_connection *connection, int event_type, void *event_data); static void HandleHttpEvent(mg_connection *connection, http_message *http_req); static void SendHttpRsp(mg_connection *connection, std::string rsp); - static int isWebsocket(const mg_connection *connection); // 判断是否是websoket类型连接 + static int isWebsocket(const mg_connection *connection); // 鍒ゆ柇鏄惁鏄痺ebsoket绫诲瀷杩炴帴 static void HandleWebsocketMessage(mg_connection *connection, int event_type, websocket_message *ws_msg); - static void SendWebsocketMsg(mg_connection *connection, std::string msg); // 发送消息到指定连接 - static void BroadcastWebsocketMsg(std::string msg); // 给所有连接广播消息 - static std::unordered_set s_websocket_session_set; // 缓存websocket连接 + static void SendWebsocketMsg(mg_connection *connection, std::string msg); // 鍙戦佹秷鎭埌鎸囧畾杩炴帴 + static void BroadcastWebsocketMsg(std::string msg); // 缁欐墍鏈夎繛鎺ュ箍鎾秷鎭 + static std::unordered_set s_websocket_session_set; // 缂撳瓨websocket杩炴帴 - std::string m_port; // 端口 - mg_mgr m_mgr; // 连接管理器 + std::string m_port; // 绔彛 + mg_mgr m_mgr; // 杩炴帴绠$悊鍣 }; From ac73c6a17673ec572fe22f30e677a7ffaacf2a9a Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Sat, 15 Apr 2023 20:24:20 +0800 Subject: [PATCH 5/9] Update http_server.cpp --- httpserver/http_server.cpp | 300 ++++++++++++++++++++++++++++++------- 1 file changed, 245 insertions(+), 55 deletions(-) diff --git a/httpserver/http_server.cpp b/httpserver/http_server.cpp index 551a69e..4a0b5f7 100644 --- a/httpserver/http_server.cpp +++ b/httpserver/http_server.cpp @@ -1,28 +1,203 @@ #include #include "http_server.h" +#include +#include +#include +#include "time.h" +#include "../common/functions.h" +#define cookielen 8 -void HttpServer::Init(const std::string &port) +using namespace std; + +int counting_req = 0; + +struct requestMessage { + string keywords[20] = {}; + string Fn = "", url, httpVersion; + string reqinfo[40] = {}; + char body[]; + + string findInfo(string Name_info) { + + } + + void readIn(string req) { + int i = 0; + while (req[i] != ' ') { + this->Fn += req[i]; + i++; + } + cout << this->Fn; + i+=url.length()+2; + while (req[i] != '\r') { + this->httpVersion += req[i]; + i++; + } + int flag = 0, black = 0; + for (; i < req.length(); i++) { + if (req[i] == '\r') { + if (black == 0) { + break; + } + black = 0; + flag++; + i++; + continue; + } + black++; + this->reqinfo[flag] += req[i]; + } + if (this->Fn == "POST") { + + } + } +}; + + +long long time_now_sec() +{ + time_t tv; + tv = time(NULL);//time(&tv); get current time; + //std::cout << tv << std::endl;//璺濈1970-01-01 00:00:00缁忓巻鐨勭鏁 + return tv; +} + +string time_now_str() { + time_t tv; + tv = time(NULL);//time(&tv); get current time; + return ctime(&tv); +} + +struct user { + /* + *level: 0==guest,1==user,2==admin,3==root + * User can not use this website if tis able == false; + */ + string name = ""; + string password = ""; + int ID = 0; + string cookie = ""; + string time_str_creation_cookie = ""; + long long time_num_creation_cookie = 0; + bool able = false; + int level = -1; + string level_str = ""; + + bool logined = false; + bool time_login = ""; + int login(string username, string password) { + /*If the funcution returns 0,username or password can't be matched. + * If -1 is returned ,the user has been disabled. + * If 1 is returned ,login is allowed. + * If 2 is returned ,the user is logined. + */ + + if (username == this->name && password == this->password) { + if (this->logined == true) { + return 2; + } + if (this->able) { + this->logined = true; + return 1; + }else{ + return -1; + } + }else{ + return 0; + } + } + bool login_cookie(string cookie) { + if (cookie == this->cookie && this->able&&this->time_num_creation_cookie <= time_now_sec()) { + this->logined = true; + return true; + } + else if(this->time_num_creation_cookie > time_now_sec()){ + this->cookie = ""; + } + return false; + } + + void read_in( + int ID, + string name, + int level, + string password, + string cookie, + bool creation_time_cookie + + ) { + switch (level) { + case 0: + this->level_str += "Guset"; + break; + case 1: + this->level_str += "User"; + break; + case 2: + this->level_str += "Admin"; + break; + case 3: + this->level_str += "Root"; + break; + default: + this->level_str += "Error"; + } + this->cookie += cookie; + this->time_str_creation_cookie += creation_time_cookie; + this->ID = ID; + this->name += name; + this->password += password; + } +}users[44]; + +void readin() { + int ID; + string name; + int level; + string password; + string cookie; + bool creation_time_cookie; + FILE* stream1; + freopen_s(&stream1, "userinfo.dba", "r", stdin); + for (int i = 0; i < 44; i++) { + cin >> ID >> name >> level >> password >> cookie >> creation_time_cookie; + users[i].read_in(ID, name, level, password, cookie, creation_time_cookie); + } + fclose(stdin); +} + + + + +void HttpServer::Init(const std::string& port) { m_port = port; s_server_option.enable_directory_listing = "yes"; s_server_option.document_root = s_web_dir.c_str(); - // 其他http设置 + // 鍏朵粬http璁剧疆 - // 开启 CORS,本项只针对主页加载有效 + // 寮鍚 CORS锛屾湰椤瑰彧閽堝涓婚〉鍔犺浇鏈夋晥 // s_server_option.extra_headers = "Access-Control-Allow-Origin: *"; } bool HttpServer::Start() { mg_mgr_init(&m_mgr, NULL); - mg_connection *connection = mg_bind(&m_mgr, m_port.c_str(), HttpServer::OnHttpWebsocketEvent); + mg_connection* connection = mg_bind(&m_mgr, m_port.c_str(), HttpServer::OnHttpWebsocketEvent); if (connection == NULL) return false; + + thread stat01(readin); + // for both http and websocket - mg_set_protocol_http_websocket(connection); + thread stat02(mg_set_protocol_http_websocket,connection); printf("starting http server at port: %s\n", m_port.c_str()); + + stat01.join(); + stat02.join(); + // loop while (true) mg_mgr_poll(&m_mgr, 500); // ms @@ -30,39 +205,42 @@ bool HttpServer::Start() return true; } -void HttpServer::OnHttpWebsocketEvent(mg_connection *connection, int event_type, void *event_data) +void HttpServer::OnHttpWebsocketEvent(mg_connection* connection, int event_type, void* event_data) { - // 区分http和websocket + // 鍖哄垎http鍜寃ebsocket if (event_type == MG_EV_HTTP_REQUEST) { - http_message *http_req = (http_message *)event_data; - HandleHttpEvent(connection, http_req); + http_message* http_req = (http_message*)event_data; + std::thread HandleHttpEvent(HttpServer::HandleHttpEvent, connection, http_req); + HandleHttpEvent.join(); + //HandleHttpEvent(connection, http_req); } else if (event_type == MG_EV_WEBSOCKET_HANDSHAKE_DONE || - event_type == MG_EV_WEBSOCKET_FRAME || - event_type == MG_EV_CLOSE) + event_type == MG_EV_WEBSOCKET_FRAME || + event_type == MG_EV_CLOSE) { - websocket_message *ws_message = (struct websocket_message *)event_data; + websocket_message* ws_message = (struct websocket_message*)event_data; HandleWebsocketMessage(connection, event_type, ws_message); } + } // ---- simple http ---- // -static bool route_check(http_message *http_msg, char *route_prefix) +static bool route_check(http_message* http_msg, char* route_prefix) { if (mg_vcmp(&http_msg->uri, route_prefix) == 0) return true; else return false; - // TODO: 还可以判断 GET, POST, PUT, DELTE等方法 + // TODO: 杩樺彲浠ュ垽鏂 GET, POST, PUT, DELTE绛夋柟娉 //mg_vcmp(&http_msg->method, "GET"); //mg_vcmp(&http_msg->method, "POST"); //mg_vcmp(&http_msg->method, "PUT"); //mg_vcmp(&http_msg->method, "DELETE"); } -void HttpServer::AddHandler(const std::string &url, ReqHandler req_handler) +void HttpServer::AddHandler(const std::string& url, ReqHandler req_handler) { if (s_handler_map.find(url) != s_handler_map.end()) return; @@ -70,24 +248,24 @@ void HttpServer::AddHandler(const std::string &url, ReqHandler req_handler) s_handler_map.insert(std::make_pair(url, req_handler)); } -void HttpServer::RemoveHandler(const std::string &url) +void HttpServer::RemoveHandler(const std::string& url) { auto it = s_handler_map.find(url); if (it != s_handler_map.end()) s_handler_map.erase(it); } -void HttpServer::SendHttpRsp(mg_connection *connection, std::string rsp) +void HttpServer::SendHttpRsp(mg_connection* connection, std::string rsp) { - // --- 未开启CORS - // 必须先发送header, 暂时还不能用HTTP/2.0 + // --- 鏈紑鍚疌ORS + // 蹇呴』鍏堝彂閫乭eader, 鏆傛椂杩樹笉鑳界敤HTTP/2.0 mg_printf(connection, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); - // 以json形式返回 + // 浠son褰㈠紡杩斿洖 mg_printf_http_chunk(connection, "{ \"result\": %s }", rsp.c_str()); - // 发送空白字符快,结束当前响应 + // 鍙戦佺┖鐧藉瓧绗﹀揩锛岀粨鏉熷綋鍓嶅搷搴 mg_send_http_chunk(connection, "", 0); - // --- 开启CORS + // --- 寮鍚疌ORS /*mg_printf(connection, "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\n" "Cache-Control: no-cache\n" @@ -96,12 +274,14 @@ void HttpServer::SendHttpRsp(mg_connection *connection, std::string rsp) "%s\n", rsp.length(), rsp.c_str()); */ } -void HttpServer::HandleHttpEvent(mg_connection *connection, http_message *http_req) +void HttpServer::HandleHttpEvent(mg_connection* connection, http_message* http_req) { std::string req_str = std::string(http_req->message.p, http_req->message.len); - printf("got request: %s\n", req_str.c_str()); + counting_req++; + cout << "Time:" << time_now_sec()<<" counting:"<uri.p, http_req->uri.len); std::string body = std::string(http_req->body.p, http_req->body.len); auto it = s_handler_map.find(url); @@ -111,55 +291,65 @@ void HttpServer::HandleHttpEvent(mg_connection *connection, http_message *http_r handle_func(url, body, connection, &HttpServer::SendHttpRsp); } - // 其他请求 - if (route_check(http_req, "/")) // index page - mg_serve_http(connection, http_req, s_server_option); - else if (route_check(http_req, "/api/hello")) + // 鍏朵粬璇锋眰 + + requestMessage req; + + req.url.resize(url.length()); + req.url = url; + req.readIn(req_str); + + switch (hash_(url.c_str())) { - // 直接回传 + case "/a"_hash: + SendHttpRsp(connection, "AAAAA"); + break; + case "/api/hello"_hash: SendHttpRsp(connection, "welcome to httpserver"); - } - else if (route_check(http_req, "/api/sum")) - { - // 简单post请求,加法运算测试 + break; + case "/api/sum"_hash: + // 绠鍗昿ost璇锋眰锛屽姞娉曡繍绠楁祴璇 char n1[100], n2[100]; double result; - /* Get form variables */ mg_get_http_var(&http_req->body, "n1", n1, sizeof(n1)); mg_get_http_var(&http_req->body, "n2", n2, sizeof(n2)); - - /* Compute the result and send it back as a JSON object */ + /* Compute the result and send it back as a JSOt object */ result = strtod(n1, NULL) + strtod(n2, NULL); SendHttpRsp(connection, std::to_string(result)); + break; + case "/server.html"_hash: + mg_serve_http(connection, http_req, s_server_option); + break; + default: + mg_serve_http(connection, http_req, s_server_option); } - else - { - mg_printf( - connection, - "%s", - "HTTP/1.1 501 Not Implemented\r\n" - "Content-Length: 0\r\n\r\n"); - } + + //mg_printf( + //connection, + //:"%s", + //"HTTP/1.1 501 Not Implemented\r\n" + //"Content-Length: 0\r\n\r\n"); } + // ---- websocket ---- // -int HttpServer::isWebsocket(const mg_connection *connection) +int HttpServer::isWebsocket(const mg_connection* connection) { return connection->flags & MG_F_IS_WEBSOCKET; } -void HttpServer::HandleWebsocketMessage(mg_connection *connection, int event_type, websocket_message *ws_msg) +void HttpServer::HandleWebsocketMessage(mg_connection* connection, int event_type, websocket_message* ws_msg) { if (event_type == MG_EV_WEBSOCKET_HANDSHAKE_DONE) { printf("client websocket connected\n"); - // 获取连接客户端的IP和端口 + // 鑾峰彇杩炴帴瀹㈡埛绔殑IP鍜岀鍙 char addr[32]; mg_sock_addr_to_str(&connection->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); printf("client addr: %s\n", addr); - // 添加 session + // 娣诲姞 session s_websocket_session_set.insert(connection); SendWebsocketMsg(connection, "client websocket connected"); @@ -167,10 +357,10 @@ void HttpServer::HandleWebsocketMessage(mg_connection *connection, int event_typ else if (event_type == MG_EV_WEBSOCKET_FRAME) { mg_str received_msg = { - (char *)ws_msg->data, ws_msg->size + (char*)ws_msg->data, ws_msg->size }; - char buff[1024] = {0}; + char buff[1024] = { 0 }; strncpy(buff, received_msg.p, received_msg.len); // must use strncpy, specifiy memory pointer and length // do sth to process request @@ -183,21 +373,21 @@ void HttpServer::HandleWebsocketMessage(mg_connection *connection, int event_typ if (isWebsocket(connection)) { printf("client websocket closed\n"); - // 移除session + // 绉婚櫎session if (s_websocket_session_set.find(connection) != s_websocket_session_set.end()) s_websocket_session_set.erase(connection); } } } -void HttpServer::SendWebsocketMsg(mg_connection *connection, std::string msg) +void HttpServer::SendWebsocketMsg(mg_connection* connection, std::string msg) { mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, msg.c_str(), strlen(msg.c_str())); } void HttpServer::BroadcastWebsocketMsg(std::string msg) { - for (mg_connection *connection : s_websocket_session_set) + for (mg_connection* connection : s_websocket_session_set) mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, msg.c_str(), strlen(msg.c_str())); } @@ -205,4 +395,4 @@ bool HttpServer::Close() { mg_mgr_free(&m_mgr); return true; -} \ No newline at end of file +} From b224812b54df2ac8ba6ccd862aea8748ad594801 Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Sat, 15 Apr 2023 20:25:28 +0800 Subject: [PATCH 6/9] Update main.cpp --- httpserver/main.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/httpserver/main.cpp b/httpserver/main.cpp index 3e3df52..6914fbe 100644 --- a/httpserver/main.cpp +++ b/httpserver/main.cpp @@ -1,11 +1,13 @@ #include #include #include "http_server.h" +#define cookielen 8 + +// 锟斤拷始锟斤拷HttpServer锟斤拷态锟斤拷锟皆 -// 初始化HttpServer静态类成员 mg_serve_http_opts HttpServer::s_server_option; -std::string HttpServer::s_web_dir = "./web"; std::unordered_map HttpServer::s_handler_map; + std::unordered_set HttpServer::s_websocket_session_set; bool handle_fun1(std::string url, std::string body, mg_connection *c, OnRspCallback rsp_callback) @@ -34,14 +36,17 @@ bool handle_fun2(std::string url, std::string body, mg_connection *c, OnRspCallb int main(int argc, char *argv[]) { - std::string port = "7999"; + CMyINI* ini = new CMyINI(); + ini->ReadINI("D:/C++/Projects/Network/Server/x64/Debug/regedit.ini"); + std::string port = ini->GetValue("web", "port"); auto http_server = std::shared_ptr(new HttpServer); http_server->Init(port); // add handler http_server->AddHandler("/api/fun1", handle_fun1); http_server->AddHandler("/api/fun2", handle_fun2); + http_server->Start(); return 0; -} \ No newline at end of file +} From 8ad49e0782324dda40e0f8afad9a987caa631152 Mon Sep 17 00:00:00 2001 From: Tommy Zhang <3079048471@qq.com> Date: Sat, 15 Apr 2023 20:26:52 +0800 Subject: [PATCH 7/9] Add files via upload --- common/functions.h | 56 ++++++++++ common/winini.cpp | 209 ++++++++++++++++++++++++++++++++++++++ common/winini.example.cpp | 12 +++ common/winini.h | 56 ++++++++++ 4 files changed, 333 insertions(+) create mode 100644 common/functions.h create mode 100644 common/winini.cpp create mode 100644 common/winini.example.cpp create mode 100644 common/winini.h diff --git a/common/functions.h b/common/functions.h new file mode 100644 index 0000000..a032c03 --- /dev/null +++ b/common/functions.h @@ -0,0 +1,56 @@ +#pragma once + +//---------------------------------------------------------------------- + +static char* U2G(const char* utf8) { + int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); + wchar_t* wstr = new wchar_t[len + 1]; + memset(wstr, 0, len + 1); + MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len); + len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); + char* str = new char[len + 1]; + memset(str, 0, len + 1); + WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); + if (wstr) delete[] wstr; + return str; +} +/* +* blog.csdn.net/weixin_42165585/article/details/81385047 +*/ +//-------------------------------------------------------------------- +//-------------------------------------------------------------------- + +/* +* 锟剿达拷锟斤拷锟斤拷CSDN锟斤拷锟斤拷源锟斤拷 +*原锟斤拷锟斤拷锟接o拷https ://blog.csdn.net/yozidream/article/details/22789147 +*/ + +typedef std::uint64_t hash_t; + +constexpr hash_t prime = 0x100000001B3ull; +constexpr hash_t basis = 0xCBF29CE484222325ull; + +hash_t hash_(char const* str) +{ + hash_t ret{ basis }; + + while (*str) { + ret ^= *str; + ret *= prime; + str++; + } + + return ret; +} + +constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis) +{ + return *str ? hash_compile_time(str + 1, (*str ^ last_value) * prime) : last_value; +} + +constexpr unsigned long long operator "" _hash(char const* p, size_t) +{ + return hash_compile_time(p); +} + +//----------------------------------------------------------------- \ No newline at end of file diff --git a/common/winini.cpp b/common/winini.cpp new file mode 100644 index 0000000..4f91064 --- /dev/null +++ b/common/winini.cpp @@ -0,0 +1,209 @@ +#include "winini.h" + +#define INIDEBUG + +CMyINI::CMyINI() +{ +} + + +CMyINI::~CMyINI() +{ +} + +//************************************************************************ +// 鍑芥暟鍚嶇О: TrimString +// 璁块棶鏉冮檺: public +// 鍒涘缓鏃ユ湡: 2017/01/05 +// 鍒 寤 浜: +// 鍑芥暟璇存槑: 鍘婚櫎绌烘牸 +// 鍑芥暟鍙傛暟: string & str 杈撳叆鐨勫瓧绗︿覆 +// 杩 鍥 鍊: std::string & 缁撴灉瀛楃涓 +//************************************************************************ +string &TrimString(string &str) +{ + string::size_type pos = 0; + while (str.npos != (pos = str.find(" "))) + str = str.replace(pos, pos + 1, ""); + return str; +} + +//************************************************************************ +// 鍑芥暟鍚嶇О: ReadINI +// 璁块棶鏉冮檺: public +// 鍒涘缓鏃ユ湡: 2017/01/05 +// 鍒 寤 浜: +// 鍑芥暟璇存槑: 璇诲彇INI鏂囦欢锛屽苟灏嗗叾淇濆瓨鍒癿ap缁撴瀯涓 +// 鍑芥暟鍙傛暟: string path INI鏂囦欢鐨勮矾寰 +// 杩 鍥 鍊: int +//************************************************************************ +int CMyINI::ReadINI(string path) +{ + ifstream in_conf_file(path.c_str()); + if (!in_conf_file) return 0; + string str_line = ""; + string str_root = ""; + vector vec_ini; + while (getline(in_conf_file, str_line)) + { + string::size_type left_pos = 0; + string::size_type right_pos = 0; + string::size_type equal_div_pos = 0; + string str_key = ""; + string str_value = ""; + if ((str_line.npos != (left_pos = str_line.find("["))) && (str_line.npos != (right_pos = str_line.find("]")))) + { + //cout << str_line.substr(left_pos+1, right_pos-1) << endl; + str_root = str_line.substr(left_pos + 1, right_pos - 1); + } + + if (str_line.npos != (equal_div_pos = str_line.find("="))) + { + str_key = str_line.substr(0, equal_div_pos); + str_value = str_line.substr(equal_div_pos + 1, str_line.size() - 1); + str_key = TrimString(str_key); + str_value = TrimString(str_value); + //cout << str_key << "=" << str_value << endl; + } + + if ((!str_root.empty()) && (!str_key.empty()) && (!str_value.empty())) + { + ININode ini_node(str_root, str_key, str_value); + vec_ini.push_back(ini_node); + //cout << vec_ini.size() << endl; + } + } + in_conf_file.close(); + in_conf_file.clear(); + + //vector convert to map + map map_tmp; + for (vector::iterator itr = vec_ini.begin(); itr != vec_ini.end(); ++itr) + { + map_tmp.insert(pair(itr->root, "")); + } //鎻愬彇鍑烘牴鑺傜偣 + for (map::iterator itr = map_tmp.begin(); itr != map_tmp.end(); ++itr) + { +#ifdef INIDEBUG + //cout << "鏍硅妭鐐癸細 " << itr->first << endl; +#endif //INIDEBUG + SubNode sn; + for (vector::iterator sub_itr = vec_ini.begin(); sub_itr != vec_ini.end(); ++sub_itr) + { + if (sub_itr->root == itr->first) + { +#ifdef INIDEBUG + //cout << "閿煎锛 " << sub_itr->key << "=" << sub_itr->value << endl; +#endif //INIDEBUG + sn.InsertElement(sub_itr->key, sub_itr->value); + } + } + map_ini.insert(pair(itr->first, sn)); + } + return 1; +} + +//************************************************************************ +// 鍑芥暟鍚嶇О: GetValue +// 璁块棶鏉冮檺: public +// 鍒涘缓鏃ユ湡: 2017/01/05 +// 鍒 寤 浜: +// 鍑芥暟璇存槑: 鏍规嵁缁欏嚭鐨勬牴缁撶偣鍜岄敭鍊兼煡鎵鹃厤缃」鐨勫 +// 鍑芥暟鍙傛暟: string root 閰嶇疆椤圭殑鏍圭粨鐐 +// 鍑芥暟鍙傛暟: string key 閰嶇疆椤圭殑閿 +// 杩 鍥 鍊: std::string 閰嶇疆椤圭殑鍊 +//************************************************************************ +string CMyINI::GetValue(string root, string key) +{ + map::iterator itr = map_ini.find(root); + map::iterator sub_itr = itr->second.sub_node.find(key); + if (!(sub_itr->second).empty()) + return sub_itr->second; + return ""; +} + +//************************************************************************ +// 鍑芥暟鍚嶇О: WriteINI +// 璁块棶鏉冮檺: public +// 鍒涘缓鏃ユ湡: 2017/01/05 +// 鍒 寤 浜: +// 鍑芥暟璇存槑: 淇濆瓨XML鐨勪俊鎭埌鏂囦欢涓 +// 鍑芥暟鍙傛暟: string path INI鏂囦欢鐨勪繚瀛樿矾寰 +// 杩 鍥 鍊: int +//************************************************************************ +int CMyINI::WriteINI(string path) +{ + ofstream out_conf_file(path.c_str()); + if (!out_conf_file) + return -1; + //cout << map_ini.size() << endl; + for (map::iterator itr = map_ini.begin(); itr != map_ini.end(); ++itr) + { + //cout << itr->first << endl; + out_conf_file << "[" << itr->first << "]" << endl; + for (map::iterator sub_itr = itr->second.sub_node.begin(); sub_itr != itr->second.sub_node.end(); ++sub_itr) + { + //cout << sub_itr->first << "=" << sub_itr->second << endl; + out_conf_file << sub_itr->first << "=" << sub_itr->second << endl; + } + } + + out_conf_file.close(); + out_conf_file.clear(); + + return 1; +} + + +//************************************************************************ +// 鍑芥暟鍚嶇О: SetValue +// 璁块棶鏉冮檺: public +// 鍒涘缓鏃ユ湡: 2017/01/05 +// 鍒 寤 浜: +// 鍑芥暟璇存槑: 璁剧疆閰嶇疆椤圭殑鍊 +// 鍑芥暟鍙傛暟: string root 閰嶇疆椤圭殑鏍硅妭鐐 +// 鍑芥暟鍙傛暟: string key 閰嶇疆椤圭殑閿 +// 鍑芥暟鍙傛暟: string value 閰嶇疆椤圭殑鍊 +// 杩 鍥 鍊: std::vector::size_type +//************************************************************************ +vector::size_type CMyINI::SetValue(string root, string key, string value) +{ + map::iterator itr = map_ini.find(root); //鏌ユ壘 + if (map_ini.end() != itr) + { + //itr->second.sub_node.insert(pair(key, value)); + itr->second.sub_node[key] = value; + } //鏍硅妭鐐瑰凡缁忓瓨鍦ㄤ簡锛屾洿鏂板 + else + { + SubNode sn; + sn.InsertElement(key, value); + map_ini.insert(pair(root, sn)); + } //鏍硅妭鐐逛笉瀛樺湪锛屾坊鍔犲 + + return map_ini.size(); +} + +//************************************************************************ +// 鍑芥暟鍚嶇О: Travel +// 璁块棶鏉冮檺: public +// 鍒涘缓鏃ユ湡: 2017/01/05 +// 鍑芥暟璇存槑: 閬嶅巻鎵撳嵃INI鏂囦欢 +// 杩 鍥 鍊: void +//************************************************************************ +void CMyINI::Travel() +{ + for (map::iterator itr = this->map_ini.begin(); itr!= this->map_ini.end(); ++itr) + { + //root + cout << "[" << itr->first << "]" << endl; + for (map::iterator itr1=itr->second.sub_node.begin(); itr1!=itr->second.sub_node.end(); + ++itr1) + { + cout << " " << itr1->first << " = " << itr1->second << endl; + } + } + +} + +//https://blog.csdn.net/m_buddy/article/details/54097131 \ No newline at end of file diff --git a/common/winini.example.cpp b/common/winini.example.cpp new file mode 100644 index 0000000..620f621 --- /dev/null +++ b/common/winini.example.cpp @@ -0,0 +1,12 @@ +CMyINI *p = new CMyINI(); + p->ReadINI("Setting.ini"); + cout << "\n鍘熷INI鏂囦欢鍐呭锛" << std::endl; + p->Travel(); + p->SetValue("setting", "hehe", "eheh"); + cout << "\n澧炲姞鑺傜偣涔嬪悗鐨勫唴瀹癸細" << std::endl; + p->Travel(); + cout << "\n淇敼鑺傜偣涔嬪悗鐨勫唴瀹癸細" << std::endl; + p->SetValue("kk", "kk", "2"); + p->Travel(); + p->WriteINI("Setting.ini"); +//https://blog.csdn.net/m_buddy/article/details/54097131 \ No newline at end of file diff --git a/common/winini.h b/common/winini.h new file mode 100644 index 0000000..39c419f --- /dev/null +++ b/common/winini.h @@ -0,0 +1,56 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +using namespace std; + +//INI鏂囦欢缁撶偣瀛樺偍缁撴瀯 +class ININode +{ +public: + ININode(string root, string key, string value) + { + this->root = root; + this->key = key; + this->value = value; + } + string root; + string key; + string value; +}; + +//閿煎缁撴瀯浣 +class SubNode +{ +public: + void InsertElement(string key, string value) + { + sub_node.insert(pair(key, value)); + } + map sub_node; +}; + +//INI鏂囦欢鎿嶄綔绫 +class CMyINI +{ +public: + CMyINI(); + ~CMyINI(); + +public: + int ReadINI(string path); //璇诲彇INI鏂囦欢 + string GetValue(string root, string key); //鐢辨牴缁撶偣鍜岄敭鑾峰彇鍊 + vector::size_type GetSize() { return map_ini.size(); } //鑾峰彇INI鏂囦欢鐨勭粨鐐规暟 + vector::size_type SetValue(string root, string key, string value); //璁剧疆鏍圭粨鐐瑰拰閿幏鍙栧 + int WriteINI(string path); //鍐欏叆INI鏂囦欢 + void Clear() { map_ini.clear(); } //娓呯┖ + void Travel(); //閬嶅巻鎵撳嵃INI鏂囦欢 +private: + map map_ini; //INI鏂囦欢鍐呭鐨勫瓨鍌ㄥ彉閲 +}; + +//http://blog.csdn.net/m_buddy/article/details/54097131 \ No newline at end of file From b244f8c6be228f7ae74ffc49f5c865e21e56b720 Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Sat, 15 Apr 2023 21:13:08 +0800 Subject: [PATCH 8/9] Delete httpclient directory --- httpclient/http_client.cpp | 398 ------------------------------------- httpclient/http_client.h | 51 ----- httpclient/main.cpp | 24 --- 3 files changed, 473 deletions(-) delete mode 100644 httpclient/http_client.cpp delete mode 100644 httpclient/http_client.h delete mode 100644 httpclient/main.cpp diff --git a/httpclient/http_client.cpp b/httpclient/http_client.cpp deleted file mode 100644 index bf75065..0000000 --- a/httpclient/http_client.cpp +++ /dev/null @@ -1,398 +0,0 @@ -#include -#include "http_server.h" -#include -#include -#include -#include "time.h" -#include "../common/functions.h" -#define cookielen 8 - -using namespace std; - -int counting_req = 0; - -struct requestMessage { - string keywords[20] = {}; - string Fn = "", url, httpVersion; - string reqinfo[40] = {}; - char body[]; - - string findInfo(string Name_info) { - - } - - void readIn(string req) { - int i = 0; - while (req[i] != ' ') { - this->Fn += req[i]; - i++; - } - cout << this->Fn; - i+=url.length()+2; - while (req[i] != '\r') { - this->httpVersion += req[i]; - i++; - } - int flag = 0, black = 0; - for (; i < req.length(); i++) { - if (req[i] == '\r') { - if (black == 0) { - break; - } - black = 0; - flag++; - i++; - continue; - } - black++; - this->reqinfo[flag] += req[i]; - } - if (this->Fn == "POST") { - - } - } -}; - - -long long time_now_sec() -{ - time_t tv; - tv = time(NULL);//time(&tv); get current time; - //std::cout << tv << std::endl;//璺濈1970-01-01 00:00:00缁忓巻鐨勭鏁 - return tv; -} - -string time_now_str() { - time_t tv; - tv = time(NULL);//time(&tv); get current time; - return ctime(&tv); -} - -struct user { - /* - *level: 0==guest,1==user,2==admin,3==root - * User can not use this website if tis able == false; - */ - string name = ""; - string password = ""; - int ID = 0; - string cookie = ""; - string time_str_creation_cookie = ""; - long long time_num_creation_cookie = 0; - bool able = false; - int level = -1; - string level_str = ""; - - bool logined = false; - bool time_login = ""; - int login(string username, string password) { - /*If the funcution returns 0,username or password can't be matched. - * If -1 is returned ,the user has been disabled. - * If 1 is returned ,login is allowed. - * If 2 is returned ,the user is logined. - */ - - if (username == this->name && password == this->password) { - if (this->logined == true) { - return 2; - } - if (this->able) { - this->logined = true; - return 1; - }else{ - return -1; - } - }else{ - return 0; - } - } - bool login_cookie(string cookie) { - if (cookie == this->cookie && this->able&&this->time_num_creation_cookie <= time_now_sec()) { - this->logined = true; - return true; - } - else if(this->time_num_creation_cookie > time_now_sec()){ - this->cookie = ""; - } - return false; - } - - void read_in( - int ID, - string name, - int level, - string password, - string cookie, - bool creation_time_cookie - - ) { - switch (level) { - case 0: - this->level_str += "Guset"; - break; - case 1: - this->level_str += "User"; - break; - case 2: - this->level_str += "Admin"; - break; - case 3: - this->level_str += "Root"; - break; - default: - this->level_str += "Error"; - } - this->cookie += cookie; - this->time_str_creation_cookie += creation_time_cookie; - this->ID = ID; - this->name += name; - this->password += password; - } -}users[44]; - -void readin() { - int ID; - string name; - int level; - string password; - string cookie; - bool creation_time_cookie; - FILE* stream1; - freopen_s(&stream1, "userinfo.dba", "r", stdin); - for (int i = 0; i < 44; i++) { - cin >> ID >> name >> level >> password >> cookie >> creation_time_cookie; - users[i].read_in(ID, name, level, password, cookie, creation_time_cookie); - } - fclose(stdin); -} - - - - -void HttpServer::Init(const std::string& port) -{ - m_port = port; - s_server_option.enable_directory_listing = "yes"; - s_server_option.document_root = s_web_dir.c_str(); - - // 锟斤拷锟斤拷http锟斤拷锟斤拷 - - // 锟斤拷锟斤拷 CORS锟斤拷锟斤拷锟斤拷只锟斤拷锟斤拷锟揭筹拷锟斤拷锟斤拷锟叫 - // s_server_option.extra_headers = "Access-Control-Allow-Origin: *"; -} - -bool HttpServer::Start() -{ - mg_mgr_init(&m_mgr, NULL); - mg_connection* connection = mg_bind(&m_mgr, m_port.c_str(), HttpServer::OnHttpWebsocketEvent); - if (connection == NULL) - return false; - - thread stat01(readin); - - // for both http and websocket - thread stat02(mg_set_protocol_http_websocket,connection); - - printf("starting http server at port: %s\n", m_port.c_str()); - - stat01.join(); - stat02.join(); - - // loop - while (true) - mg_mgr_poll(&m_mgr, 500); // ms - - return true; -} - -void HttpServer::OnHttpWebsocketEvent(mg_connection* connection, int event_type, void* event_data) -{ - // 锟斤拷锟斤拷http锟斤拷websocket - if (event_type == MG_EV_HTTP_REQUEST) - { - http_message* http_req = (http_message*)event_data; - std::thread HandleHttpEvent(HttpServer::HandleHttpEvent, connection, http_req); - HandleHttpEvent.join(); - //HandleHttpEvent(connection, http_req); - } - else if (event_type == MG_EV_WEBSOCKET_HANDSHAKE_DONE || - event_type == MG_EV_WEBSOCKET_FRAME || - event_type == MG_EV_CLOSE) - { - websocket_message* ws_message = (struct websocket_message*)event_data; - HandleWebsocketMessage(connection, event_type, ws_message); - } - -} - -// ---- simple http ---- // -static bool route_check(http_message* http_msg, char* route_prefix) -{ - if (mg_vcmp(&http_msg->uri, route_prefix) == 0) - return true; - else - return false; - - // TODO: 锟斤拷锟斤拷锟斤拷锟叫讹拷 GET, POST, PUT, DELTE锟饺凤拷锟斤拷 - //mg_vcmp(&http_msg->method, "GET"); - //mg_vcmp(&http_msg->method, "POST"); - //mg_vcmp(&http_msg->method, "PUT"); - //mg_vcmp(&http_msg->method, "DELETE"); -} - -void HttpServer::AddHandler(const std::string& url, ReqHandler req_handler) -{ - if (s_handler_map.find(url) != s_handler_map.end()) - return; - - s_handler_map.insert(std::make_pair(url, req_handler)); -} - -void HttpServer::RemoveHandler(const std::string& url) -{ - auto it = s_handler_map.find(url); - if (it != s_handler_map.end()) - s_handler_map.erase(it); -} - -void HttpServer::SendHttpRsp(mg_connection* connection, std::string rsp) -{ - // --- 未锟斤拷锟斤拷CORS - // 锟斤拷锟斤拷锟饺凤拷锟斤拷header, 锟斤拷时锟斤拷锟斤拷锟斤拷锟斤拷HTTP/2.0 - mg_printf(connection, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); - // 锟斤拷json锟斤拷式锟斤拷锟斤拷 - mg_printf_http_chunk(connection, "{ \"result\": %s }", rsp.c_str()); - // 锟斤拷锟酵空帮拷锟街凤拷锟届,锟斤拷锟斤拷锟斤拷前锟斤拷应 - mg_send_http_chunk(connection, "", 0); - - // --- 锟斤拷锟斤拷CORS - /*mg_printf(connection, "HTTP/1.1 200 OK\r\n" - "Content-Type: text/plain\n" - "Cache-Control: no-cache\n" - "Content-Length: %d\n" - "Access-Control-Allow-Origin: *\n\n" - "%s\n", rsp.length(), rsp.c_str()); */ -} - -void HttpServer::HandleHttpEvent(mg_connection* connection, http_message* http_req) -{ - std::string req_str = std::string(http_req->message.p, http_req->message.len); - counting_req++; - cout << "Time:" << time_now_sec()<<" counting:"<uri.p, http_req->uri.len); - std::string body = std::string(http_req->body.p, http_req->body.len); - auto it = s_handler_map.find(url); - if (it != s_handler_map.end()) - { - ReqHandler handle_func = it->second; - handle_func(url, body, connection, &HttpServer::SendHttpRsp); - } - - // 锟斤拷锟斤拷锟斤拷锟斤拷 - - requestMessage req; - - req.url.resize(url.length()); - req.url = url; - req.readIn(req_str); - - switch (hash_(url.c_str())) - { - case "/a"_hash: - SendHttpRsp(connection, "AAAAA"); - break; - case "/api/hello"_hash: - SendHttpRsp(connection, "welcome to httpserver"); - break; - case "/api/sum"_hash: - // 锟斤拷post锟斤拷锟襟,加凤拷锟斤拷锟斤拷锟斤拷锟 - char n1[100], n2[100]; - double result; - /* Get form variables */ - mg_get_http_var(&http_req->body, "n1", n1, sizeof(n1)); - mg_get_http_var(&http_req->body, "n2", n2, sizeof(n2)); - /* Compute the result and send it back as a JSOt object */ - result = strtod(n1, NULL) + strtod(n2, NULL); - SendHttpRsp(connection, std::to_string(result)); - break; - case "/server.html"_hash: - mg_serve_http(connection, http_req, s_server_option); - break; - default: - mg_serve_http(connection, http_req, s_server_option); - } - - //mg_printf( - //connection, - //:"%s", - //"HTTP/1.1 501 Not Implemented\r\n" - //"Content-Length: 0\r\n\r\n"); -} - - -// ---- websocket ---- // -int HttpServer::isWebsocket(const mg_connection* connection) -{ - return connection->flags & MG_F_IS_WEBSOCKET; -} - -void HttpServer::HandleWebsocketMessage(mg_connection* connection, int event_type, websocket_message* ws_msg) -{ - if (event_type == MG_EV_WEBSOCKET_HANDSHAKE_DONE) - { - printf("client websocket connected\n"); - // 锟斤拷取锟斤拷锟接客伙拷锟剿碉拷IP锟酵端匡拷 - char addr[32]; - mg_sock_addr_to_str(&connection->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); - printf("client addr: %s\n", addr); - - // 锟斤拷锟 session - s_websocket_session_set.insert(connection); - - SendWebsocketMsg(connection, "client websocket connected"); - } - else if (event_type == MG_EV_WEBSOCKET_FRAME) - { - mg_str received_msg = { - (char*)ws_msg->data, ws_msg->size - }; - - char buff[1024] = { 0 }; - strncpy(buff, received_msg.p, received_msg.len); // must use strncpy, specifiy memory pointer and length - - // do sth to process request - printf("received msg: %s\n", buff); - SendWebsocketMsg(connection, "send your msg back: " + std::string(buff)); - //BroadcastWebsocketMsg("broadcast msg: " + std::string(buff)); - } - else if (event_type == MG_EV_CLOSE) - { - if (isWebsocket(connection)) - { - printf("client websocket closed\n"); - // 锟狡筹拷session - if (s_websocket_session_set.find(connection) != s_websocket_session_set.end()) - s_websocket_session_set.erase(connection); - } - } -} - -void HttpServer::SendWebsocketMsg(mg_connection* connection, std::string msg) -{ - mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, msg.c_str(), strlen(msg.c_str())); -} - -void HttpServer::BroadcastWebsocketMsg(std::string msg) -{ - for (mg_connection* connection : s_websocket_session_set) - mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, msg.c_str(), strlen(msg.c_str())); -} - -bool HttpServer::Close() -{ - mg_mgr_free(&m_mgr); - return true; -} diff --git a/httpclient/http_client.h b/httpclient/http_client.h deleted file mode 100644 index 55d5a59..0000000 --- a/httpclient/http_client.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "../common/mongoose.h" -#include "../common/winini.h" - -// 锟斤拷锟斤拷http锟斤拷锟斤拷callback -typedef void OnRspCallback(mg_connection *c, std::string); -// 锟斤拷锟斤拷http锟斤拷锟斤拷handler -using ReqHandler = std::function; - -class HttpServer -{ -public: - HttpServer() { - CMyINI* ini = new CMyINI(); - ini->ReadINI("D:/C++/Projects/Network/Server/x64/Debug/regedit.ini"); - s_web_dir = ini->GetValue("dir", "web");} - ~HttpServer() {} - void Init(const std::string &port); // 锟斤拷始锟斤拷锟斤拷锟斤拷 - bool Start(); // 锟斤拷锟絟ttpserver - bool Close(); // 锟截憋拷 - void AddHandler(const std::string &url, ReqHandler req_handler); // 注锟斤拷锟铰硷拷锟斤拷锟斤拷锟斤拷锟 - void RemoveHandler(const std::string &url); // 锟狡筹拷时锟戒处锟斤拷锟斤拷锟 - //static std::string s_web_dir; // 锟斤拷页锟斤拷目录 - - static mg_serve_http_opts s_server_option; // web锟斤拷锟斤拷锟斤拷选锟斤拷 - static std::unordered_map s_handler_map; // 锟截碉拷锟斤拷锟斤拷映锟斤拷锟 -private: - // 锟斤拷态锟铰硷拷锟斤拷应锟斤拷锟斤拷 - std::string s_web_dir; - - static void OnHttpWebsocketEvent(mg_connection *connection, int event_type, void *event_data); - - static void HandleHttpEvent(mg_connection *connection, http_message *http_req); - static void SendHttpRsp(mg_connection *connection, std::string rsp); - - static int isWebsocket(const mg_connection *connection); // 锟叫讹拷锟角凤拷锟斤拷websoket锟斤拷锟斤拷锟斤拷锟斤拷 - static void HandleWebsocketMessage(mg_connection *connection, int event_type, websocket_message *ws_msg); - static void SendWebsocketMsg(mg_connection *connection, std::string msg); // 锟斤拷锟斤拷锟斤拷息锟斤拷指锟斤拷锟斤拷锟斤拷 - static void BroadcastWebsocketMsg(std::string msg); // 锟斤拷锟斤拷锟斤拷锟斤拷锟接广播锟斤拷息 - static std::unordered_set s_websocket_session_set; // 锟斤拷锟斤拷websocket锟斤拷锟斤拷 - - std::string m_port; // 锟剿匡拷 - mg_mgr m_mgr; // 锟斤拷锟接癸拷锟斤拷锟斤拷 -}; - diff --git a/httpclient/main.cpp b/httpclient/main.cpp deleted file mode 100644 index 4fc9da4..0000000 --- a/httpclient/main.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include "http_client.h" - -void handle_func(std::string rsp) -{ - // do sth according to rsp - std::cout << "http rsp1: " << rsp << std::endl; -} - -int main() -{ - // 拼完整url,带参数 - std::string url1 = "http://127.0.0.1:7999/api/hello"; - HttpClient::SendReq(url1, handle_func); - - std::string url2 = "http://127.0.0.1:7999/api/fun2"; - HttpClient::SendReq(url2, [](std::string rsp) { - std::cout << "http rsp2: " << rsp << std::endl; - }); - - system("pause"); - - return 0; -} \ No newline at end of file From 2ea454d5a1cea8970b8279c6e608006027425a8e Mon Sep 17 00:00:00 2001 From: Tommy Zhang Date: Thu, 27 Apr 2023 06:47:34 +0800 Subject: [PATCH 9/9] Create regedit.ini --- database/regedit.ini | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 database/regedit.ini diff --git a/database/regedit.ini b/database/regedit.ini new file mode 100644 index 0000000..4661cb5 --- /dev/null +++ b/database/regedit.ini @@ -0,0 +1,4 @@ +[dir] +web=D:/Git/Gitee/fyeleven +[web] +port=80