First step to improve een9: guest function for http trafixc returns een9::ServerResponse structure instead of string

This commit is contained in:
Andreev Gregory 2024-09-15 14:09:59 +03:00
parent bc2c7d31c9
commit 43da7fddf9
15 changed files with 84 additions and 100 deletions

View File

@ -95,7 +95,7 @@ struct CAWebChat {
"thread_synchronization.h", "thread_synchronization.h",
"os_utils.h", "os_utils.h",
"connecting_assets/static_asset_manager.h", "connecting_assets/static_asset_manager.h",
"http_structures/client_request.h", "http_structures/messages.h",
"http_structures/cookies.h", "http_structures/cookies.h",
"http_structures/response_gen.h", "http_structures/response_gen.h",
"http_structures/accept_language.h", "http_structures/accept_language.h",

View File

@ -4,7 +4,7 @@
/* Do not export this file */ /* Do not export this file */
#include "../baza.h" #include "../baza.h"
#include "client_request.h" #include "messages.h"
#include <libregexis024vm/libregexis024vm_interface.h> #include <libregexis024vm/libregexis024vm_interface.h>
namespace een9 { namespace een9 {

View File

@ -17,6 +17,13 @@ namespace een9 {
bool has_body = false; bool has_body = false;
std::string body; std::string body;
}; };
struct ServerResponse {
std::string code;
std::string msg;
std::vector<std::pair<std::string, std::string>> headers;
std::string body;
};
} }
#endif #endif

View File

@ -5,50 +5,26 @@
namespace een9 { namespace een9 {
std::string form_http_server_response_header(const char* code, ServerResponse form_http_server_response_200(const std::string& Content_Type, const std::string& body) {
return een9::ServerResponse{"200", "OK",
{{"Content-Type", Content_Type}, {"Content-Length", std::to_string(body.size())}}, body};
}
ServerResponse form_http_server_response_404(const std::string& Content_Type, const std::string& body) {
return een9::ServerResponse{"404", "ERROR",
{{"Content-Type", Content_Type}, {"Content-Length", std::to_string(body.size())}}, body};
}
ServerResponse form_http_server_response_303(const std::string& Location) {
return een9::ServerResponse{"303", "Go here", {{"Location", Location}}, ""};
}
ServerResponse form_http_server_response_303_spec_head(const std::string &Location,
const std::vector<std::pair<std::string, std::string>>& headers) { const std::vector<std::pair<std::string, std::string>>& headers) {
assert(strlen(code) == 3); ServerResponse r{"303", "Go here", {{"Location", Location}}, ""};
std::string result = std::string("HTTP/1.0 ") + code + " " + (code[0] < '4' ? "OK" : "ERROR") + "\r\n"; for (auto& hl: headers)
for (auto& p: headers) r.headers.push_back(hl);
result += (p.first + ": " + p.second + "\r\n"); return r;
return result;
}
std::string form_http_server_response_header_only(const char* code,
const std::vector<std::pair<std::string, std::string>>& headers) {
return form_http_server_response_header(code, headers) + "\r\n";
}
std::string form_http_server_response_with_body(const char* code,
const std::vector<std::pair<std::string, std::string>>& headers,
const std::string& body)
{
std::string result = form_http_server_response_header(code, headers)
+ "Content-Length: " + std::to_string(body.size()) + "\r\n\r\n" + body;
return result;
}
/* Message from server to client */
std::string form_http_server_response_200(const std::string& Content_Type, const std::string& body) {
return form_http_server_response_with_body("200", {
{"Content-Type", Content_Type}
}, body);
}
std::string form_http_server_response_404(const std::string& Content_Type, const std::string& body) {
return form_http_server_response_with_body("404", {
{"Content-Type", Content_Type}
}, body);
}
std::string form_http_server_response_303(const std::string& Location) {
return form_http_server_response_header_only("303", {{"Location", Location}});
}
std::string form_http_server_response_303_spec_head(const std::string &Location,
const std::vector<std::pair<std::string, std::string>>& headers) {
std::vector<std::pair<std::string, std::string>> cp = headers;
cp.emplace_back("Location", Location);
return form_http_server_response_header_only("303", cp);
} }
} }

View File

@ -3,26 +3,16 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "messages.h"
namespace een9 { namespace een9 {
std::string form_http_server_response_header(const char* code, ServerResponse form_http_server_response_200(const std::string& Content_Type, const std::string& body);
const std::vector<std::pair<std::string, std::string>>& headers);
std::string form_http_server_reponse_header_only(const char* code, ServerResponse form_http_server_response_404(const std::string& Content_Type, const std::string& body);
const std::vector<std::pair<std::string, std::string>>& headers);
std::string form_http_server_response_with_body(const char* code, ServerResponse form_http_server_response_303(const std::string& Location);
const std::vector<std::pair<std::string, std::string>>& headers,
const std::string& body);
std::string form_http_server_response_200(const std::string& Content_Type, const std::string& body); ServerResponse form_http_server_response_303_spec_head(const std::string &Location,
std::string form_http_server_response_404(const std::string& Content_Type, const std::string& body);
std::string form_http_server_response_303(const std::string& Location);
std::string form_http_server_response_303_spec_head(const std::string &Location,
const std::vector<std::pair<std::string, std::string>>& headers); const std::vector<std::pair<std::string, std::string>>& headers);
} }

View File

@ -149,12 +149,22 @@ namespace een9 {
return pctx.body; return pctx.body;
} }
std::string server_response_to_str(const ServerResponse& cont) {
std::string result = "HTTP/1.0 " + cont.code + " " + cont.msg + "\r\n";
for (const std::pair<std::string, std::string>& hl: cont.headers) {
result += hl.first + ": " + hl.second + "\r\n";
}
result += "\r\n" + cont.body;
return result;
}
void process_connection(const SlaveTask& task, WorkersEnv& wte) { void process_connection(const SlaveTask& task, WorkersEnv& wte) {
if (task.conn_info.type == 0) { if (task.conn_info.type == 0) {
printf("%d::Got http reuest\n", wte.id); printf("%d::Got http reuest\n", wte.id);
ClientRequest client_request = process_http_connection_input(task.fd(), task.s_tips, wte); ClientRequest client_request = process_http_connection_input(task.fd(), task.s_tips, wte);
printf("%d::Http request has been read\n", wte.id); printf("%d::Http request has been read\n", wte.id);
std::string server_response = wte.wtec.guest_core(task, client_request, wte.id); ServerResponse server_response_content = wte.wtec.guest_core(task, client_request, wte.id);
std::string server_response = server_response_to_str(server_response_content);
process_connection_output(task.fd(), server_response); process_connection_output(task.fd(), server_response);
printf("%d::Http response has been sent\n", wte.id); printf("%d::Http response has been sent\n", wte.id);
} else if (task.conn_info.type == 1) { } else if (task.conn_info.type == 1) {

View File

@ -5,7 +5,7 @@
#include <functional> #include <functional>
#include <sys/time.h> #include <sys/time.h>
#include "os_utils.h" #include "os_utils.h"
#include "http_structures/client_request.h" #include "http_structures/messages.h"
#include <stdint.h> #include <stdint.h>
#include "socket_address.h" #include "socket_address.h"
@ -34,7 +34,7 @@ namespace een9 {
typedef int worker_id_t; typedef int worker_id_t;
/* guest_core function must not throw anything that is not derived from std::exception */ /* guest_core function must not throw anything that is not derived from std::exception */
typedef std::function<std::string(const SlaveTask&, const ClientRequest&, worker_id_t worker_id)> guest_core_t; typedef std::function<ServerResponse(const SlaveTask&, const ClientRequest&, worker_id_t worker_id)> guest_core_t;
/* same as gurst_core_t, but it used not for http, but for een9 specific "admin-cmd" protocol */ /* same as gurst_core_t, but it used not for http, but for een9 specific "admin-cmd" protocol */
typedef std::function<std::string(const SlaveTask&, const std::string&, worker_id_t)> guest_core_admin_control_t; typedef std::function<std::string(const SlaveTask&, const std::string&, worker_id_t)> guest_core_admin_control_t;

View File

@ -25,7 +25,7 @@ namespace iu9cawebchat {
} }
} }
std::string http_R200(const std::string &el_name, WorkerGuestData &wgd, een9::ServerResponse http_R200(const std::string &el_name, WorkerGuestData &wgd,
const std::vector<const json::JSON *> &args) { const std::vector<const json::JSON *> &args) {
std::string page = wgd.templater->render(el_name, args); std::string page = wgd.templater->render(el_name, args);
return een9::form_http_server_response_200("text/html", page); return een9::form_http_server_response_200("text/html", page);
@ -40,52 +40,52 @@ namespace iu9cawebchat {
return jmessages; return jmessages;
} }
std::string page_E404(WorkerGuestData &wgd) { een9::ServerResponse page_E404(WorkerGuestData &wgd) {
return een9::form_http_server_response_404("text/html", return een9::form_http_server_response_404("text/html",
wgd.templater->render("err-404", {})); wgd.templater->render("err-404", {}));
} }
/* ========================= API =========================*/ /* ========================= API =========================*/
std::string when_internalapi(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid, een9::ServerResponse when_internalapi(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid,
const std::function<json::JSON(SqliteConnection&, int64_t, const json::JSON&)>& F) { const std::function<json::JSON(SqliteConnection&, int64_t, const json::JSON&)>& F) {
const json::JSON& Sent = json::parse_str_flawless(req.body); const json::JSON& Sent = json::parse_str_flawless(req.body);
std::string result = json::generate_str(F(*wgd.db, uid, Sent), json::print_pretty); std::string result = json::generate_str(F(*wgd.db, uid, Sent), json::print_pretty);
return een9::form_http_server_response_200("text/json", result); return een9::form_http_server_response_200("text/json", result);
} }
std::string when_internalapi_chatpollevents(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid) { een9::ServerResponse when_internalapi_chatpollevents(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_chatPollEvents); return when_internalapi(wgd, req, uid, internalapi_chatPollEvents);
} }
std::string when_internalapi_chatlistpollevents(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_chatlistpollevents(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_chatListPollEvents); return when_internalapi(wgd, req, uid, internalapi_chatListPollEvents);
} }
std::string when_internalapi_getmessageneighbours(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_getmessageneighbours(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_getMessageNeighbours); return when_internalapi(wgd, req, uid, internalapi_getMessageNeighbours);
} }
std::string when_internalapi_sendmessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_sendmessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_sendMessage); return when_internalapi(wgd, req, uid, internalapi_sendMessage);
} }
std::string when_internalapi_deletemessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_deletemessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_deleteMessage); return when_internalapi(wgd, req, uid, internalapi_deleteMessage);
} }
std::string when_internalapi_addmembertochat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_addmembertochat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_addMemberToChat); return when_internalapi(wgd, req, uid, internalapi_addMemberToChat);
} }
std::string when_internalapi_removememberfromchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_removememberfromchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_removeMemberFromChat); return when_internalapi(wgd, req, uid, internalapi_removeMemberFromChat);
} }
std::string when_internalapi_createchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_createchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_createChat); return when_internalapi(wgd, req, uid, internalapi_createChat);
} }
std::string when_internalapi_leavechat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) { een9::ServerResponse when_internalapi_leavechat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid) {
return when_internalapi(wgd, req, uid, internalapi_leaveChat); return when_internalapi(wgd, req, uid, internalapi_leaveChat);
} }
} }

View File

@ -4,7 +4,7 @@
#include "server_data_interact.h" #include "server_data_interact.h"
#include "../sqlite3_wrapper.h" #include "../sqlite3_wrapper.h"
#include <engine_engine_number_9/http_structures/client_request.h> #include <engine_engine_number_9/http_structures/messages.h>
#include <engine_engine_number_9/http_structures/response_gen.h> #include <engine_engine_number_9/http_structures/response_gen.h>
#include "../login_cookie.h" #include "../login_cookie.h"
@ -29,7 +29,7 @@ namespace iu9cawebchat {
int64_t& ret_logged_in_user int64_t& ret_logged_in_user
); );
std::string http_R200(const std::string& el_name, WorkerGuestData& wgd, een9::ServerResponse http_R200(const std::string& el_name, WorkerGuestData& wgd,
const std::vector<const json::JSON*>& args); const std::vector<const json::JSON*>& args);
struct HtmlMsgBox { struct HtmlMsgBox {
@ -39,43 +39,43 @@ namespace iu9cawebchat {
json::JSON jsonify_html_message_list(const std::vector<HtmlMsgBox>& messages); json::JSON jsonify_html_message_list(const std::vector<HtmlMsgBox>& messages);
std::string page_E404(WorkerGuestData& wgd); een9::ServerResponse page_E404(WorkerGuestData& wgd);
/* ========================== PAGES ================================== */ /* ========================== PAGES ================================== */
std::string when_page_list_rooms(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_list_rooms(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const json::JSON& userinfo); const een9::ClientRequest& req, const json::JSON& userinfo);
std::string when_page_login(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_login(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo); const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo);
std::string when_page_chat(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_chat(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const json::JSON& userinfo); const een9::ClientRequest& req, const json::JSON& userinfo);
std::string when_page_user(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_user(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo); const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo);
std::string when_page_register(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_register(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const json::JSON& userinfo); const een9::ClientRequest& req, const json::JSON& userinfo);
/* ======================== API ============================== */ /* ======================== API ============================== */
std::string when_internalapi_chatpollevents(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid); een9::ServerResponse when_internalapi_chatpollevents(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid);
std::string when_internalapi_chatlistpollevents(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid); een9::ServerResponse when_internalapi_chatlistpollevents(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid);
std::string when_internalapi_getmessageneighbours(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid); een9::ServerResponse when_internalapi_getmessageneighbours(WorkerGuestData& wgd, const een9::ClientRequest& req, int64_t uid);
std::string when_internalapi_sendmessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid); een9::ServerResponse when_internalapi_sendmessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid);
std::string when_internalapi_deletemessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid); een9::ServerResponse when_internalapi_deletemessage(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid);
std::string when_internalapi_addmembertochat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid); een9::ServerResponse when_internalapi_addmembertochat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid);
std::string when_internalapi_removememberfromchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid); een9::ServerResponse when_internalapi_removememberfromchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid);
std::string when_internalapi_createchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid); een9::ServerResponse when_internalapi_createchat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid);
std::string when_internalapi_leavechat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid); een9::ServerResponse when_internalapi_leavechat(WorkerGuestData &wgd, const een9::ClientRequest &req, int64_t uid);
} }
#endif #endif

View File

@ -4,7 +4,7 @@
#include "../str_fields.h" #include "../str_fields.h"
namespace iu9cawebchat { namespace iu9cawebchat {
std::string when_page_chat(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_chat(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const json::JSON& userinfo) { const een9::ClientRequest& req, const json::JSON& userinfo) {
std::vector<std::string> path_segs = {}; std::vector<std::string> path_segs = {};

View File

@ -1,7 +1,7 @@
#include "client_server_interact.h" #include "client_server_interact.h"
namespace iu9cawebchat { namespace iu9cawebchat {
std::string when_page_list_rooms(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_list_rooms(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const json::JSON& userinfo) { const een9::ClientRequest& req, const json::JSON& userinfo) {
if (userinfo.isNull()) { if (userinfo.isNull()) {
return een9::form_http_server_response_303("/login"); return een9::form_http_server_response_303("/login");

View File

@ -4,7 +4,7 @@
#include "../str_fields.h" #include "../str_fields.h"
namespace iu9cawebchat { namespace iu9cawebchat {
std::string when_page_login(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_login(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo) { const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo) {
if (req.method == "POST") { if (req.method == "POST") {
std::vector<std::pair<std::string, std::string>> query = een9::split_html_query(req.body); std::vector<std::pair<std::string, std::string>> query = een9::split_html_query(req.body);

View File

@ -5,7 +5,7 @@
#include "../str_fields.h" #include "../str_fields.h"
namespace iu9cawebchat { namespace iu9cawebchat {
std::string when_page_register(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_register(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const json::JSON& userinfo) { const een9::ClientRequest& req, const json::JSON& userinfo) {
const json::JSON& reg_pres = config_presentation["register"]; const json::JSON& reg_pres = config_presentation["register"];

View File

@ -7,7 +7,8 @@
namespace iu9cawebchat { namespace iu9cawebchat {
std::string get_user_bio(SqliteConnection& conn, int64_t userId) { std::string get_user_bio(SqliteConnection& conn, int64_t userId) {
een9_ASSERT(userId >= 0, "Are you crazy?"); if (userId < 0)
een9_THROW("Are you crazy?");
SqliteStatement sql_req(conn, "SELECT `bio` FROM `user` WHERE `id` = ?1", {{1, userId}}, {}); SqliteStatement sql_req(conn, "SELECT `bio` FROM `user` WHERE `id` = ?1", {{1, userId}}, {});
fsql_text8_or_null bio_col; fsql_text8_or_null bio_col;
int status = sqlite_stmt_step(sql_req, {}, {{0, &bio_col}}); int status = sqlite_stmt_step(sql_req, {}, {{0, &bio_col}});
@ -37,7 +38,7 @@ namespace iu9cawebchat {
}); });
} }
std::string when_page_user(WorkerGuestData& wgd, const json::JSON& config_presentation, een9::ServerResponse when_page_user(WorkerGuestData& wgd, const json::JSON& config_presentation,
const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo) { const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo) {
if (userinfo.isNull()) if (userinfo.isNull())
return een9::form_http_server_response_303("/"); return een9::form_http_server_response_303("/");

View File

@ -78,7 +78,7 @@ namespace iu9cawebchat {
een9::MainloopParameters params; een9::MainloopParameters params;
params.guest_core = [&samI, &worker_guest_data] params.guest_core = [&samI, &worker_guest_data]
(const een9::SlaveTask& task, const een9::ClientRequest& req, een9::worker_id_t worker_id) -> std::string { (const een9::SlaveTask& task, const een9::ClientRequest& req, een9::worker_id_t worker_id) -> een9::ServerResponse {
een9_ASSERT_pl(0 <= worker_id && worker_id < worker_guest_data.size()); een9_ASSERT_pl(0 <= worker_id && worker_id < worker_guest_data.size());
WorkerGuestData& wgd = worker_guest_data[worker_id]; WorkerGuestData& wgd = worker_guest_data[worker_id];
een9::StaticAsset sa; een9::StaticAsset sa;