#include "responses.h" #define srv conn->server #define LOGGER srv->logger #define LOG_FUNC srv->log_func #define LOG_CONTEXT log_ctx declare_RequestHandler(SendMessage) { Deferral(4); logInfo("requested %s", req_type_name); // receive request SendMessageRequest req; try_void(PacketHeader_validateContentSize(req_head, sizeof(req))); try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req)); if(!conn->authorized){ try_void(sendErrorMessage(log_ctx, conn, res_head, LogSeverity_Warn, STR("not authorized") )); Return RESULT_VOID; } // validate content size if(req.data_size < MESSAGE_SIZE_MIN || req.data_size > MESSAGE_SIZE_MAX){ try_void(sendErrorMessage(log_ctx, conn, res_head, LogSeverity_Warn, STR("invalid message size") )); // close socket connection to reject incoming data Return RESULT_ERROR_CODE_FMT(TcpChat, TcpChatError_RejectIncoming, "invalid message size: %u", req.data_size); } // receive message data try_void(EncryptedSocketTCP_recv(&conn->sock, conn->message_content, SocketRecvFlag_WholeBuffer)); // validate channel id try(bool channel_exists, i, Channel_exists(conn->queries.common, req.channel_id)); if(!channel_exists){ try_void(sendErrorMessage(log_ctx, conn, res_head, LogSeverity_Warn, STR("invalid channel id") )); Return RESULT_VOID; } // save message to channel DateTime timestamp; try(i64 message_id, i, Channel_saveMessage(conn->queries.common, req.channel_id, conn->user_id, conn->message_content, ×tamp)); // send response SendMessageResponse res; SendMessageResponse_construct(&res, res_head, message_id, timestamp); try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head)); try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res)); Return RESULT_VOID; }