diff --git a/building/main.cpp b/building/main.cpp index 128ee14..163f3e8 100644 --- a/building/main.cpp +++ b/building/main.cpp @@ -159,6 +159,7 @@ struct CAWebChat { "backend_logic/when_api_getchatmemberlist.cpp", "backend_logic/when_api_getuserinfo.cpp", "backend_logic/when_api_getmessageinfo.cpp", + "backend_logic/when_api_getmessageneighbours.cpp", }; for (std::string& u: T.units) u = "web_chat/iu9_ca_web_chat_lib/" + u; diff --git a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp index c02a744..fb2f5e6 100644 --- a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp +++ b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp @@ -111,7 +111,7 @@ namespace een9 { status = -1; return status; } - res.body.reserve(body_size); + res.body.reserve(std::min(100000ul, body_size)); } } if (!res.has_body) { diff --git a/src/http_server/engine_engine_number_9/http_structures/cookies.cpp b/src/http_server/engine_engine_number_9/http_structures/cookies.cpp index dee5ba4..b7bc294 100644 --- a/src/http_server/engine_engine_number_9/http_structures/cookies.cpp +++ b/src/http_server/engine_engine_number_9/http_structures/cookies.cpp @@ -43,7 +43,7 @@ namespace een9 { pos++; return hv.substr(S, pos - S); }; - auto read_to_space_or_dq_or_semc = [&]() -> std::string { + auto read_to_space_or_semc = [&]() -> std::string { size_t S = pos; while (hv.size() > pos && !isSPACE(hv[pos]) && hv[pos] != '"' && hv[pos] != ';') pos++; @@ -68,16 +68,7 @@ namespace een9 { THROW("Incorrect Cookie header line, missing ="); pos++; skip_ows(); - std::string value_of_pechenye; - if (isThis('"')) { - pos++; - value_of_pechenye = read_to_space_or_dq_or_semc(); - if (!isThis('"')) - THROW("Incorrect Cookie header line, missing \""); - pos++; - } else { - value_of_pechenye = read_to_space_or_dq_or_semc(); - } + std::string value_of_pechenye = read_to_space_or_semc(); // ASSERT(isCookieValue(value_of_pechenye), "Incorrect Cookie value"); result.emplace_back(name_of_pechenye, value_of_pechenye); skip_ows(); diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.cpp index 75cfd5a..7cf9d48 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.cpp @@ -80,12 +80,32 @@ namespace iu9cawebchat { int status = sqlite_stmt_step(req, {{0, &previousId}, {1, &senderUserId}, {2, &exists}, {3, &isSystem}}, {{4, &msg_text}}); if (status == SQLITE_ROW) { + if (!(bool)exists.value) + een9_THROW("Message existed, but now it isn't"); return {(bool)isSystem.value, msg_text.value, senderUserId.exist ? senderUserId.value : -1, previousId.exist ? previousId.value : -1}; } een9_THROW("No such message"); } + std::pair lookup_message_content_rev_side(SqliteConnection& conn, int64_t chatId, int64_t prevMsgId) { + een9_ASSERT(prevMsgId >= 0, "V durku dobro pozhalovat"); + SqliteStatement req(conn, + "SELECT `id`, `senderUserId`, `exists`, `isSystem`, `text` FROM `message` WHERE " + "`chatId` = ?1 AND `previous` = ?2", {{1, chatId}, {2, prevMsgId}}, {}); + fsql_integer_or_null id, senderUserId, exists, isSystem; + fsql_text8_or_null msg_text; + int status = sqlite_stmt_step(req, {{0, &id}, {1, &senderUserId}, {2, &exists}, {3, &isSystem}}, + {{4, &msg_text}}); + if (status == SQLITE_ROW) { + een9_ASSERT_pl(exists.value == 1); + return {id.value, + {(bool)isSystem.value, msg_text.value, senderUserId.exist ? senderUserId.value : -1, prevMsgId}}; + } + return {-1, {}}; + } + + int64_t get_role_of_user_in_chat(SqliteConnection& conn, int64_t userId, int64_t chatId) { SqliteStatement req(conn, "SELECT `role` FROM `user_chat_membership` WHERE `userId` = ?1 AND `chatId` = ?2", diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.h b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.h index 2f2bdfa..9dad7f5 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.h +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/server_data_interact.h @@ -41,6 +41,9 @@ namespace iu9cawebchat { RowMessage_Content lookup_message_content(SqliteConnection& conn, int64_t chatId, int64_t msgId); + /* If prevMsgId is id of the last message in chat, and there is no message ahead of it, .first = -1 */ + std::pair lookup_message_content_rev_side(SqliteConnection& conn, int64_t chatId, int64_t prevMsgId); + int64_t get_role_of_user_in_chat(SqliteConnection& conn, int64_t userId, int64_t chatId); /* ============================= API ====================================*/ @@ -50,6 +53,7 @@ namespace iu9cawebchat { json::JSON internalapi_getChatMemberList(SqliteConnection& conn, int64_t uid, const json::JSON& Sent); json::JSON internalapi_getUserInfo(SqliteConnection& conn, int64_t uid, const json::JSON& Sent); json::JSON internalapi_getMessageInfo(SqliteConnection& conn, int64_t uid, const json::JSON& Sent); + json::JSON internalapi_getMessageNeighbours(SqliteConnection& conn, int64_t uid, const json::JSON& Sent); // todo: complete the list } diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_api_getmessageinfo.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_api_getmessageinfo.cpp index 3a71a53..e095fb9 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_api_getmessageinfo.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_api_getmessageinfo.cpp @@ -2,7 +2,6 @@ #include namespace iu9cawebchat { - /* This is literally the most dumb and useless query */ json::JSON internalapi_getMessageInfo(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) { int64_t chatId = Sent["chatId"].g().asInteger().get_int(); int64_t msgId = Sent["id"].g().asInteger().get_int(); diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_api_getmessageneighbours.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_api_getmessageneighbours.cpp new file mode 100644 index 0000000..5db5ff2 --- /dev/null +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_api_getmessageneighbours.cpp @@ -0,0 +1,52 @@ +#include "server_data_interact.h" +#include + +namespace iu9cawebchat { + /* This is literally the most dumb and useless query */ + json::JSON internalapi_getMessageNeighbours(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) { + int64_t chatId = Sent["chatId"].g().asInteger().get_int(); + if (get_role_of_user_in_chat(conn, uid, chatId) == user_chat_role_deleted) + een9_THROW("Authentication failure"); + bool dir_forward = Sent["direction"].g().asString() == "forward"; + int64_t amount = Sent["amount"].g().asInteger().get_int(); + if (amount < 0) + een9_THROW("Incorrect amount"); + json::JSON Recv; + Recv["status"] = json::JSON(0l); + Recv["messages"] = json::JSON(json::array); + std::vector& messages = Recv["messages"].g().asArray(); + if (dir_forward) { + int64_t curMsg = Sent["id"].g().asInteger().get_int(); + if (curMsg < 0) + een9_THROW("forward message lookup from the beginning of chat is not supported yet"); + while (true) { + /* At this point, curMsg is non-negative */ + std::pair nxt = lookup_message_content_rev_side(conn, chatId, curMsg); + if (nxt.first < 0) + break; + messages.emplace_back(); + json::JSON& message = messages.back(); + message["id"] = json::JSON(nxt.first); + message["previous"] = json::JSON(curMsg); + message["content"]["text"] = json::JSON(nxt.second.text); + message["content"]["isSystem"] = json::JSON(nxt.second.isSystem); + message["content"]["sender"] = json::JSON(nxt.second.senderUserId); + curMsg = nxt.first; + } + } else { + int64_t curMsg = Sent["previousMsgId"].g().asInteger().get_int(); + while (curMsg >= 0) { + RowMessage_Content curRow = lookup_message_content(conn, chatId, curMsg); + messages.emplace_back(); + json::JSON& message = messages.back(); + message["id"] = json::JSON(curMsg); + message["previous"] = json::JSON(curRow.previous); + message["content"]["text"] = json::JSON(curRow.text); + message["content"]["isSystem"] = json::JSON(curRow.isSystem); + message["content"]["sender"] = json::JSON(curRow.senderUserId); + curMsg = curRow.previous; + } + } + return Recv; + } +} diff --git a/src/web_chat/iu9_ca_web_chat_lib/run.cpp b/src/web_chat/iu9_ca_web_chat_lib/run.cpp index 1863a21..f8f77d6 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/run.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/run.cpp @@ -96,6 +96,9 @@ namespace iu9cawebchat { if (req.uri_path == "/internalapi/getMessageInfo") { return when_internalapi_getmessageinfo(wgd, req, logged_in_user); } + // if (req.uri_path == "/internalapi/getMessageNeighbours") { + // return when + // } // todo: write all the other interfaces } catch (const std::exception& e) { guard_.rollback = true;