/
Shymer123
/
Messenger
Обзор
Документация
Войти
/
Shymer123
/
Messenger
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Server/SourceFiles/ClientHandler/ClientHandler.cpp
145 строк
4 KB
Shymer123
compiler warnings removed
30 мар 2025, 08:30
30 мар 2025, 08:30
e6e7e55
Код
Авторство
О чём код?
#include "ClientHandler.h" #include "JsonHandler/JsonHandler.h" #include "Logger/Logger.h" #include "MainServer/Server.h" #include "Utils/Utils.h" #include "FileHandler/FileHandler.h" #include <cstring> #include <netinet/in.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <string> #include <nlohmann/json.hpp> using json = nlohmann::json; ClientHandler::ClientHandler(int socket, Server* server) : server(server), clientSocket(socket) {} std::vector<char> ClientHandler::receiveRequest() { std::vector<char> requestData; uint8_t messageType = 0; uint32_t messageSize = 0; if(!receiveExactBytes(clientSocket, &messageType, sizeof(messageType)) || !receiveExactBytes(clientSocket, &messageSize, sizeof(messageSize))) { return {}; } messageSize = ntohl(messageSize); Logger::getInstance().logError("Expecting " + std::to_string(messageSize) + " bytes", Logger::logLevel::Info); std::vector<char> buffer(messageSize); if(!receiveExactBytes(clientSocket, buffer.data(), messageSize)) { return {}; } requestData = std::move(buffer); if(messageType == 0x02) { Logger::getInstance().logError("Receiving file data...", Logger::logLevel::Info); json files; files = FileHandler::receiveFile(clientSocket); std::string filesStr = files.dump(); requestData.insert(requestData.end(), filesStr.begin(), filesStr.end()); } return requestData; } bool ClientHandler::receiveExactBytes(int clientSocket, void* buffer, size_t size) { size_t totalBytesRead = 0; char* buf = static_cast<char*>(buffer); while(totalBytesRead < size) { int bytesRead = recv(clientSocket, buf + totalBytesRead, size - totalBytesRead, 0); if(bytesRead == 0) { Logger::getInstance().logError("Client disconnected while receiving data", Logger::logLevel::Error); return false; } else if(bytesRead < 0) { if(errno == EAGAIN || errno == EWOULDBLOCK) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); continue; } Logger::getInstance().logError("Error receiving data: " + std::string(strerror(errno)), Logger::logLevel::Error); return false; } totalBytesRead += bytesRead; } return true; } bool ClientHandler::processRequest(const std::vector<char>& requestData) { std::string rawRequest(requestData.begin(), requestData.end()); size_t jsonStart = rawRequest.find("{"); json parsedRequest; std::string extractedJson; while (jsonStart != std::string::npos) { extractedJson = rawRequest.substr(jsonStart); try { parsedRequest = json::parse(extractedJson); break; } catch (const json::parse_error& e) { jsonStart = rawRequest.find("{", jsonStart + 1); } } std::vector<char> decompressedRequest = Utils::decompressData(requestData); std::string decompressedStr(decompressedRequest.data(), decompressedRequest.size()); json request = json::parse(decompressedStr); if (!extractedJson.empty()) { try { request["files"] = parsedRequest; } catch (const json::parse_error& e) { Logger::getInstance().logError("Failed to parse extracted JSON: " + std::string(e.what()), Logger::logLevel::Error); return false; } } Logger::getInstance().logError(decompressedStr.substr(0, 100).c_str(), Logger::logLevel::Info); std::string jsonResponse = JsonHandler::processJson(clientSocket, request); size_t responseSize = std::min(jsonResponse.size(), size_t(100)); Logger::getInstance().logError(jsonResponse.substr(0, responseSize).c_str(), Logger::logLevel::Info); if (jsonResponse == "ADD") { Logger::getInstance().logError("Data has been successfully inserted", Logger::logLevel::Info); } else if (jsonResponse == "ERROR") { Logger::getInstance().logError("General Error in processRequest: Unknown request", Logger::logLevel::Error); } else { std::vector<char> compressedResponse = Utils::compressData( std::vector<char>(jsonResponse.begin(), jsonResponse.end())); server->safeSend(clientSocket, 0x01, compressedResponse); } return true; }