M module-services/service-desktop/endpoints/CMakeLists.txt => module-services/service-desktop/endpoints/CMakeLists.txt +2 -2
@@ 50,11 50,11 @@ target_sources(
developerMode/Mode/UI_Helper.cpp
developerMode/event/ATRequest.cpp
developerMode/event/DomRequest.cpp
- developerMode/fs/FS_Helper.cpp
factoryReset/FactoryResetEndpoint.cpp
filesystem/FileContext.cpp
filesystem/FileOperations.cpp
filesystem/FilesystemEndpoint.cpp
+ filesystem/FS_Helper.cpp
nullEndpoint/NullEndpoint.cpp
restore/RestoreEndpoint.cpp
restore/RestoreHelper.cpp
@@ 74,11 74,11 @@ target_sources(
include/endpoints/developerMode/Mode/UI_Helper.hpp
include/endpoints/developerMode/event/ATRequest.hpp
include/endpoints/developerMode/event/DomRequest.hpp
- include/endpoints/developerMode/fs/FS_Helper.hpp
include/endpoints/factoryReset/FactoryResetEndpoint.hpp
include/endpoints/filesystem/FileContext.hpp
include/endpoints/filesystem/FileOperations.hpp
include/endpoints/filesystem/FilesystemEndpoint.hpp
+ include/endpoints/filesystem/FS_Helper.hpp
include/endpoints/nullEndpoint/NullEndpoint.hpp
include/endpoints/restore/RestoreEndpoint.hpp
include/endpoints/restore/RestoreHelper.hpp
M module-services/service-desktop/endpoints/developerMode/DeveloperModeEndpoint.cpp => module-services/service-desktop/endpoints/developerMode/DeveloperModeEndpoint.cpp +0 -3
@@ 37,9 37,6 @@ namespace sdesktop::endpoints
if (ctx.getBody()["ui"] == true) {
return *uiHelper;
}
- if (ctx.getBody()["fs"] == true) {
- return *fsHelper;
- }
return *helper;
}
D module-services/service-desktop/endpoints/developerMode/fs/FS_Helper.cpp => module-services/service-desktop/endpoints/developerMode/fs/FS_Helper.cpp +0 -95
@@ 1,95 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include <endpoints/developerMode/fs/FS_Helper.hpp>
-
-#include <log/log.hpp>
-#include <service-desktop/Constants.hpp>
-#include <service-desktop/DeveloperModeMessage.hpp>
-#include <endpoints/message/Sender.hpp>
-
-#include <filesystem>
-#include <system_error>
-
-namespace sdesktop::endpoints
-{
- using sender::putToSendQueue;
-
- void FS_Helper::preProcess(http::Method method, Context &context)
- {
- LOG_INFO("In FS helper - requesting %d", static_cast<int>(method));
- }
-
- auto FS_Helper::processGet(Context &context) -> ProcessResult
- {
- const auto &body = context.getBody();
- if (body[json::fs::listDir].is_string()) {
- const auto &dir = body[json::fs::listDir].string_value();
- auto response = requestListDir(dir);
- return {sent::no, std::move(response)};
- }
- else {
- return {sent::no, ResponseContext{.status = http::Code::BadRequest}};
- }
- }
-
- auto FS_Helper::processPut(Context &context) -> ProcessResult
- {
- auto body = context.getBody();
- auto code = http::Code::BadRequest;
- if (body[json::fs::removeFile].is_string()) {
- const auto &fileName = body[json::fs::removeFile].string_value();
- try {
- code = requestFileRemoval(fileName) ? http::Code::NoContent : http::Code::NotFound;
- }
- catch (const std::filesystem::filesystem_error &) {
- LOG_WARN("Can't remove requested file");
- code = http::Code::InternalServerError;
- }
- }
- else if (body[json::fs::renameFile].is_string()) {
- const auto &fileName = body[json::fs::renameFile].string_value();
- if (body[json::fs::destFileName].is_string()) {
- const auto &destFileName = body[json::fs::destFileName].string_value();
- code = requestFileRename(fileName, destFileName) ? http::Code::NoContent : http::Code::NotFound;
- }
- else {
- code = http::Code::NotFound;
- }
- }
- else {
- context.setResponseStatus(http::Code::BadRequest);
- putToSendQueue(context.createSimpleResponse());
- }
-
- return {sent::no, ResponseContext{.status = code}};
- }
-
- bool FS_Helper::requestFileRemoval(const std::string &fileName)
- {
- return std::filesystem::remove(fileName);
- }
-
- bool FS_Helper::requestFileRename(const std::string &fileName, const std::string &destFileName) noexcept
- {
- std::error_code ec;
- std::filesystem::rename(fileName, destFileName, ec);
- return (!ec) ? true : false;
- }
-
- ResponseContext FS_Helper::requestListDir(const std::string &directory)
- {
- std::vector<std::string> filesInDir;
- for (const auto &entry : std::filesystem::directory_iterator{directory}) {
- filesInDir.push_back(entry.path());
- }
- json11::Json::array jsonArr;
- jsonArr.reserve(filesInDir.size());
- for (const auto &path : filesInDir) {
- jsonArr.push_back(json11::Json::object{{json::fs::path, path}});
- }
- json11::Json::object response({{directory, jsonArr}});
- return ResponseContext{.status = http::Code::OK, .body = response};
- }
-
-} // namespace sdesktop::endpoints
A module-services/service-desktop/endpoints/filesystem/FS_Helper.cpp => module-services/service-desktop/endpoints/filesystem/FS_Helper.cpp +333 -0
@@ 0,0 1,333 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <endpoints/filesystem/FS_Helper.hpp>
+#include <endpoints/Context.hpp>
+#include <service-desktop/DesktopMessages.hpp>
+#include <service-desktop/ServiceDesktop.hpp>
+#include <endpoints/JsonKeyNames.hpp>
+#include <endpoints/message/Sender.hpp>
+#include <purefs/filesystem_paths.hpp>
+
+#include <filesystem>
+
+namespace sdesktop::endpoints
+{
+ using sender::putToSendQueue;
+ namespace fs = std::filesystem;
+
+ auto FS_Helper::processGet(Context &context) -> ProcessResult
+ {
+ LOG_DEBUG("Handling GET");
+ const auto &body = context.getBody();
+ ResponseContext response{};
+
+ if (body[json::fs::fileName].is_string()) {
+ response = startGetFile(context);
+ }
+ else if (body[json::fs::rxID].is_number()) {
+ response = getFileChunk(context);
+ }
+ else if (body[json::fs::listDir].is_string()) {
+ const auto &dir = body[json::fs::listDir].string_value();
+ response = requestListDir(dir);
+ }
+ else {
+ LOG_ERROR("unknown request");
+ response = {.status = http::Code::BadRequest};
+ }
+
+ return {sent::no, std::move(response)};
+ }
+
+ auto FS_Helper::processPut(Context &context) -> ProcessResult
+ {
+ LOG_DEBUG("Handling PUT");
+ const auto &body = context.getBody();
+ auto code = http::Code::BadRequest;
+ ResponseContext response{};
+
+ if (body[json::fs::fileName].is_string() && body[json::fs::fileSize].is_number() &&
+ body[json::fs::fileCrc32].is_string()) {
+ response = startSendFile(context);
+ }
+ else if (body[json::fs::txID].is_number() && body[json::fs::chunkNo].is_number() &&
+ body[json::fs::data].is_string()) {
+ response = sendFileChunk(context);
+ }
+ else if (body[json::fs::renameFile].is_string() && body[json::fs::destFilename].is_string()) {
+ const auto &fileName = body[json::fs::renameFile].string_value();
+ const auto &destFilename = body[json::fs::destFilename].string_value();
+ code = requestFileRename(fileName, destFilename) ? http::Code::NoContent : http::Code::NotFound;
+
+ response = ResponseContext{.status = code};
+ }
+ else {
+ LOG_ERROR("Bad request, missing or invalid argument");
+ response = ResponseContext{.status = http::Code::BadRequest};
+ }
+
+ return {sent::no, std::move(response)};
+ }
+
+ auto FS_Helper::processDelete(Context &context) -> ProcessResult
+ {
+ LOG_DEBUG("Handling DEL");
+ const auto &body = context.getBody();
+ auto code = http::Code::BadRequest;
+
+ if (body[json::fs::removeFile].is_string()) {
+ const auto &fileName = body[json::fs::removeFile].string_value();
+ try {
+ code = requestFileRemoval(fileName) ? http::Code::NoContent : http::Code::NotFound;
+ }
+ catch (const std::filesystem::filesystem_error &ex) {
+ LOG_ERROR("Can't remove requested file, error: %d", ex.code().value());
+ code = http::Code::InternalServerError;
+ }
+ }
+ else {
+ LOG_ERROR("Bad request, missing or invalid argument");
+ }
+
+ return {sent::no, ResponseContext{.status = code}};
+ }
+
+ auto FS_Helper::requestLogsFlush() const -> void
+ {
+ auto ownerService = dynamic_cast<ServiceDesktop *>(owner);
+ if (ownerService) {
+ ownerService->requestLogsFlush();
+ }
+ }
+
+ auto FS_Helper::startGetFile(Context &context) const -> ResponseContext
+ {
+ const std::filesystem::path filePath = context.getBody()[json::fs::fileName].string_value();
+
+ try {
+ requestLogsFlush();
+ }
+ catch (const std::runtime_error &e) {
+ LOG_ERROR("Logs flush exception: %s", e.what());
+
+ json11::Json::object response({{json::reason, e.what()}});
+ return ResponseContext{.status = http::Code::InternalServerError, .body = response};
+ }
+
+ if (!std::filesystem::exists(filePath)) {
+ LOG_ERROR("file not found");
+
+ json11::Json::object response({{json::reason, json::fs::fileDoesNotExist}});
+ return ResponseContext{.status = http::Code::NotFound, .body = response};
+ }
+
+ json11::Json::object response{};
+ auto code = http::Code::BadRequest;
+
+ LOG_DEBUG("Checking file");
+
+ try {
+ auto [rxID, fileSize] = fileOps.createReceiveIDForFile(filePath);
+
+ code = http::Code::OK;
+ response = json11::Json::object({{json::fs::rxID, static_cast<int>(rxID)},
+ {json::fs::fileSize, static_cast<int>(fileSize)},
+ {json::fs::chunkSize, static_cast<int>(FileOperations::ChunkSize)}});
+ }
+ catch (std::runtime_error &e) {
+ LOG_ERROR("FileOperations exception: %s", e.what());
+
+ code = http::Code::InternalServerError;
+ response = json11::Json::object({{json::reason, std::string(e.what())}});
+ }
+ catch (std::exception &e) {
+ LOG_ERROR("FileOperations exception: %s", e.what());
+
+ code = http::Code::BadRequest;
+ response = json11::Json::object({{json::reason, std::string(e.what())}});
+ }
+
+ return ResponseContext{.status = code, .body = response};
+ }
+
+ auto FS_Helper::getFileChunk(Context &context) const -> ResponseContext
+ {
+ const auto rxID = context.getBody()[json::fs::rxID].int_value();
+ const auto chunkNo = context.getBody()[json::fs::chunkNo].int_value();
+ FileOperations::DataWithCrc32 dataWithCrc32;
+
+ try {
+ dataWithCrc32 = fileOps.getDataForReceiveID(rxID, chunkNo);
+ }
+ catch (std::exception &e) {
+ LOG_ERROR("%s", e.what());
+
+ json11::Json::object response({{json::reason, e.what()}});
+ return ResponseContext{.status = http::Code::BadRequest, .body = response};
+ }
+
+ json11::Json::object response{};
+ auto code = http::Code::BadRequest;
+
+ if (dataWithCrc32.data.length()) {
+ code = http::Code::OK;
+ response = json11::Json::object({{json::fs::rxID, static_cast<int>(rxID)},
+ {json::fs::chunkNo, static_cast<int>(chunkNo)},
+ {json::fs::data, dataWithCrc32.data}});
+
+ if (dataWithCrc32.crc32.length()) {
+ response[json::fs::fileCrc32] = dataWithCrc32.crc32;
+ }
+ }
+ else {
+ std::ostringstream errorReason;
+ errorReason << "Invalid request rxID: " << std::to_string(rxID) << ", chunkNo: " << std::to_string(chunkNo);
+ LOG_ERROR("%s", errorReason.str().c_str());
+
+ code = http::Code::BadRequest;
+ response = json11::Json::object({{json::reason, errorReason.str()}});
+ }
+
+ return ResponseContext{.status = code, .body = response};
+ }
+
+ auto FS_Helper::startSendFile(Context &context) const -> ResponseContext
+ {
+ const auto &body = context.getBody();
+ std::filesystem::path filePath = body[json::fs::fileName].string_value();
+ const uint32_t fileSize = body[json::fs::fileSize].int_value();
+ const auto fileCrc32 = body[json::fs::fileCrc32].string_value();
+ auto code = http::Code::BadRequest;
+
+ LOG_DEBUG("Start sending of file: %s", filePath.c_str());
+
+ if (fileSize == 0 || fileCrc32.empty()) {
+ LOG_ERROR("File %s corrupted", filePath.c_str());
+
+ return ResponseContext{.status = code};
+ }
+
+ if (!std::filesystem::exists(filePath)) {
+ LOG_DEBUG("Creating file %s", filePath.c_str());
+
+ code = http::Code::Created;
+ }
+ else {
+ LOG_DEBUG("Overwriting file %s", filePath.c_str());
+ }
+
+ json11::Json::object response{};
+
+ try {
+ auto txID = fileOps.createTransmitIDForFile(filePath, fileSize, fileCrc32);
+
+ code = http::Code::OK;
+ response = json11::Json::object({{json::fs::txID, static_cast<int>(txID)},
+ {json::fs::chunkSize, static_cast<int>(FileOperations::ChunkSize)}});
+ }
+ catch (std::runtime_error &e) {
+ LOG_ERROR("FileOperations exception: %s", e.what());
+
+ code = http::Code::InternalServerError;
+ response = json11::Json::object({{json::reason, std::string(e.what())}});
+ }
+ catch (std::exception &e) {
+ LOG_ERROR("FileOperations exception: %s", e.what());
+
+ code = http::Code::BadRequest;
+ response = json11::Json::object({{json::reason, std::string(e.what())}});
+ }
+
+ return ResponseContext{.status = code, .body = response};
+ }
+
+ auto FS_Helper::sendFileChunk(Context &context) const -> ResponseContext
+ {
+ const auto &body = context.getBody();
+ const auto txID = body[json::fs::txID].int_value();
+ const auto chunkNo = body[json::fs::chunkNo].int_value();
+ const auto data = body[json::fs::data].string_value();
+
+ if (data.empty()) {
+ std::ostringstream errorReason;
+ errorReason << "Invalid request txID: " << std::to_string(txID) << ", chunkNo: " << std::to_string(chunkNo);
+ LOG_ERROR("%s", errorReason.str().c_str());
+
+ auto code = http::Code::BadRequest;
+ auto response = json11::Json::object({{json::reason, errorReason.str()}});
+
+ return ResponseContext{.status = code, .body = response};
+ }
+
+ auto returnCode = sys::ReturnCodes::Success;
+
+ try {
+ returnCode = fileOps.sendDataForTransmitID(txID, chunkNo, data);
+ }
+ catch (std::exception &e) {
+ LOG_ERROR("%s", e.what());
+
+ auto code = http::Code::NotAcceptable;
+ auto response = json11::Json::object({{json::reason, e.what()}});
+
+ return ResponseContext{.status = code, .body = response};
+ }
+
+ json11::Json::object response{};
+ auto code = http::Code::OK;
+
+ if (returnCode == sys::ReturnCodes::Success) {
+ LOG_DEBUG("FileOperations::sendDataForTransmitID success");
+
+ response = json11::Json::object(
+ {{json::fs::txID, static_cast<int>(txID)}, {json::fs::chunkNo, static_cast<int>(chunkNo)}});
+ }
+ else {
+ LOG_ERROR("FileOperations::sendDataForTransmitID failed");
+
+ code = http::Code::BadRequest;
+ response = json11::Json::object(
+ {{json::fs::txID, static_cast<int>(txID)}, {json::fs::chunkNo, static_cast<int>(chunkNo)}});
+ }
+
+ return ResponseContext{.status = code, .body = response};
+ }
+
+ auto FS_Helper::requestFileRemoval(const std::string &fileName) -> bool
+ {
+ return std::filesystem::remove(fileName);
+ }
+
+ auto FS_Helper::requestFileRename(const std::string &fileName, const std::string &destFilename) noexcept -> bool
+ {
+ std::error_code ec;
+ std::filesystem::rename(fileName, destFilename, ec);
+ if (!ec) {
+ LOG_ERROR("Failed to rename %s, error: %d", fileName.c_str(), ec.value());
+ }
+ return !ec;
+ }
+
+ auto FS_Helper::requestListDir(const std::string &directory) -> ResponseContext
+ {
+ if (!std::filesystem::exists(directory)) {
+ return ResponseContext{.status = http::Code::NotFound};
+ }
+
+ std::vector<std::string> filesInDir;
+ for (const auto &entry : std::filesystem::directory_iterator{directory}) {
+ filesInDir.push_back(entry.path());
+ }
+
+ json11::Json::array jsonArr;
+ jsonArr.reserve(filesInDir.size());
+
+ for (const auto &path : filesInDir) {
+ jsonArr.push_back(json11::Json::object{{json::fs::path, path}});
+ }
+
+ json11::Json::object response({{directory, jsonArr}});
+ return ResponseContext{.status = http::Code::OK, .body = response};
+ }
+} // namespace sdesktop::endpoints
M module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.cpp => module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.cpp +14 -300
@@ 2,320 2,34 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <endpoints/filesystem/FilesystemEndpoint.hpp>
-
-#include <service-desktop/DesktopMessages.hpp>
-#include <service-desktop/ServiceDesktop.hpp>
-#include <endpoints/JsonKeyNames.hpp>
+#include <endpoints/filesystem/FS_Helper.hpp>
#include <endpoints/message/Sender.hpp>
-#include <purefs/filesystem_paths.hpp>
-
-#include <filesystem>
namespace sdesktop::endpoints
{
-
- namespace fs = std::filesystem;
using sender::putToSendQueue;
auto FilesystemEndpoint::handle(Context &context) -> void
{
- auto returnCode = sys::ReturnCodes::Success;
- switch (context.getMethod()) {
- case http::Method::get:
- returnCode = runGet(context);
- break;
- case http::Method::post:
- returnCode = runPost(context);
- break;
- case http::Method::put:
- returnCode = runPut(context);
- break;
- default:
- LOG_ERROR("Unhandled method request: %u", static_cast<unsigned>(context.getMethod()));
- returnCode = sys::ReturnCodes::Failure;
- break;
- }
- LOG_DEBUG("returnCode: %u", static_cast<unsigned>(returnCode));
- }
-
- auto FilesystemEndpoint::requestLogsFlush() const -> void
- {
- auto owner = dynamic_cast<ServiceDesktop *>(ownerServicePtr);
- if (owner) {
- owner->requestLogsFlush();
- }
- }
-
- auto FilesystemEndpoint::startGetFile(Context &context) const -> sys::ReturnCodes
- {
- std::filesystem::path filePath = context.getBody()[json::fileName].string_value();
-
- try {
- requestLogsFlush();
- }
- catch (const std::runtime_error &e) {
- LOG_ERROR("Logs flush exception: %s", e.what());
+ const auto &[sent, response] = helper->process(context.getMethod(), context);
- context.setResponseStatus(http::Code::InternalServerError);
- context.setResponseBody(json11::Json::object({{json::reason, std::string(e.what())}}));
- return sys::ReturnCodes::Failure;
+ if (sent == sent::delayed) {
+ LOG_DEBUG("There is no proper delayed serving mechanism - depend on invisible context caching");
}
-
- if (!std::filesystem::exists(filePath)) {
- LOG_ERROR("file not found");
-
- context.setResponseStatus(http::Code::NotFound);
- context.setResponseBody(
- json11::Json::object({{json::reason, json::filesystem::reasons::fileDoesNotExist}}));
- return sys::ReturnCodes::Failure;
- }
-
- LOG_DEBUG("Checking file");
-
- try {
- auto [rxID, fileSize] = fileOps.createReceiveIDForFile(filePath);
-
- context.setResponseStatus(http::Code::OK);
- context.setResponseBody(
- json11::Json::object({{json::filesystem::rxID, static_cast<int>(rxID)},
- {json::fileSize, static_cast<int>(fileSize)},
- {json::filesystem::chunkSize, static_cast<int>(FileOperations::ChunkSize)}}));
- }
- catch (std::runtime_error &e) {
- LOG_ERROR("FileOperations exception: %s", e.what());
-
- context.setResponseStatus(http::Code::InternalServerError);
- context.setResponseBody(json11::Json::object({{json::reason, std::string(e.what())}}));
- return sys::ReturnCodes::Failure;
- }
- catch (std::exception &e) {
- LOG_ERROR("FileOperations exception: %s", e.what());
-
- context.setResponseStatus(http::Code::BadRequest);
- context.setResponseBody(json11::Json::object({{json::reason, std::string(e.what())}}));
- return sys::ReturnCodes::Failure;
- }
-
- return sys::ReturnCodes::Success;
- }
-
- auto FilesystemEndpoint::getFileChunk(Context &context) const -> sys::ReturnCodes
- {
- auto returnCode = sys::ReturnCodes::Failure;
- const auto rxID = context.getBody()[json::filesystem::rxID].int_value();
- const auto chunkNo = context.getBody()[json::filesystem::chunkNo].int_value();
- FileOperations::DataWithCrc32 dataWithCrc32;
-
- try {
- dataWithCrc32 = fileOps.getDataForReceiveID(rxID, chunkNo);
- }
- catch (std::exception &e) {
- LOG_ERROR("%s", e.what());
- context.setResponseStatus(http::Code::BadRequest);
- context.setResponseBody(json11::Json::object({{json::reason, e.what()}}));
-
- return sys::ReturnCodes::Failure;
- }
-
- if (dataWithCrc32.data.length()) {
- context.setResponseStatus(http::Code::OK);
- json11::Json::object contextJsonObject =
- json11::Json::object({{json::filesystem::rxID, static_cast<int>(rxID)},
- {json::filesystem::chunkNo, static_cast<int>(chunkNo)},
- {json::filesystem::data, dataWithCrc32.data}});
-
- if (dataWithCrc32.crc32.length()) {
- contextJsonObject[json::fileCrc32] = dataWithCrc32.crc32;
+ if (sent == sent::no) {
+ if (not response) {
+ LOG_ERROR("Response not sent & response not created : respond with error");
+ context.setResponseStatus(http::Code::NotAcceptable);
+ }
+ else {
+ context.setResponse(response.value());
}
- context.setResponseBody(contextJsonObject);
-
- returnCode = sys::ReturnCodes::Success;
- }
- else {
- std::ostringstream errorReason;
- errorReason << "Invalid request rxID: " << std::to_string(rxID) << ", chunkNo: " << std::to_string(chunkNo);
- LOG_ERROR("%s", errorReason.str().c_str());
-
- context.setResponseStatus(http::Code::BadRequest);
- context.setResponseBody(json11::Json::object({{json::reason, errorReason.str()}}));
- }
-
- return returnCode;
- }
-
- auto FilesystemEndpoint::runGet(Context &context) -> sys::ReturnCodes
- {
- LOG_DEBUG("Handling GET");
- auto returnCode = sys::ReturnCodes::Failure;
-
- if (context.getBody()[json::fileName].is_string()) {
- returnCode = startGetFile(context);
- }
- else if (context.getBody()[json::filesystem::rxID].is_number()) {
- returnCode = getFileChunk(context);
- }
- else {
- LOG_ERROR("unknown request");
- context.setResponseStatus(http::Code::BadRequest);
- returnCode = sys::ReturnCodes::Failure;
- }
-
- putToSendQueue(context.createSimpleResponse());
-
- return returnCode;
- }
-
- auto FilesystemEndpoint::runPost(Context &context) -> sys::ReturnCodes
- {
- LOG_DEBUG("Handling POST");
- sys::ReturnCodes returnCode = sys::ReturnCodes::Failure;
- std::string cmd = context.getBody()[json::filesystem::command].string_value();
-
- context.setResponseBody(
- json11::Json::object({{json::status, std::to_string(static_cast<int>(sys::ReturnCodes::Failure))}}));
-
- if (cmd == json::filesystem::commands::checkFile) {
- fs::path filePath = context.getBody()[json::fileName].string_value();
- LOG_DEBUG("Checking file");
-
- context.setResponseBody(json11::Json::object{{json::fileExists, std::filesystem::exists(filePath)}});
- returnCode = sys::ReturnCodes::Success;
- }
- else {
- LOG_ERROR("unknown command");
- context.setResponseStatus(http::Code::BadRequest);
- returnCode = sys::ReturnCodes::Failure;
- }
-
- putToSendQueue(context.createSimpleResponse());
- return returnCode;
- }
-
- auto FilesystemEndpoint::runPut(Context &context) -> sys::ReturnCodes
- {
- LOG_DEBUG("Handling PUT");
- auto returnCode = sys::ReturnCodes::Failure;
- const auto &requestBody = context.getBody();
-
- if (requestBody[json::fileName].is_string() && requestBody[json::fileSize].is_number() &&
- requestBody[json::fileCrc32].is_string()) {
- returnCode = startSendFile(context);
- }
- else if (requestBody[json::filesystem::txID].is_number() &&
- requestBody[json::filesystem::chunkNo].is_number() &&
- requestBody[json::filesystem::data].is_string()) {
- returnCode = sendFileChunk(context);
- }
- else {
- LOG_ERROR("unknown request");
- context.setResponseStatus(http::Code::BadRequest);
- returnCode = sys::ReturnCodes::Failure;
- }
-
- putToSendQueue(context.createSimpleResponse());
- return returnCode;
- }
-
- auto FilesystemEndpoint::startSendFile(Context &context) const -> sys::ReturnCodes
- {
- auto returnCode = sys::ReturnCodes::Failure;
- const auto &requestBody = context.getBody();
-
- std::filesystem::path filePath = requestBody[json::fileName].string_value();
- const uint32_t fileSize = requestBody[json::fileSize].int_value();
- const auto fileCrc32 = requestBody[json::fileCrc32].string_value();
-
- LOG_DEBUG("Start sending of file: %s", filePath.c_str());
-
- if (fileSize == 0 || fileCrc32.empty()) {
- LOG_ERROR("File %s corrupted", filePath.c_str());
-
- context.setResponseStatus(http::Code::BadRequest);
- return returnCode;
- }
-
- if (!std::filesystem::exists(filePath)) {
- LOG_DEBUG("Creating file %s", filePath.c_str());
-
- context.setResponseStatus(http::Code::Created);
- }
- else {
- LOG_DEBUG("Overwriting file %s", filePath.c_str());
- }
-
- try {
- auto txID = fileOps.createTransmitIDForFile(filePath, fileSize, fileCrc32);
-
- context.setResponseStatus(http::Code::OK);
- context.setResponseBody(
- json11::Json::object({{json::filesystem::txID, static_cast<int>(txID)},
- {json::filesystem::chunkSize, static_cast<int>(FileOperations::ChunkSize)}}));
- }
- catch (std::runtime_error &e) {
- LOG_ERROR("FileOperations exception: %s", e.what());
-
- context.setResponseStatus(http::Code::InternalServerError);
- context.setResponseBody(json11::Json::object({{json::reason, std::string(e.what())}}));
- return sys::ReturnCodes::Failure;
- }
- catch (std::exception &e) {
- LOG_ERROR("FileOperations exception: %s", e.what());
-
- context.setResponseStatus(http::Code::BadRequest);
- context.setResponseBody(json11::Json::object({{json::reason, std::string(e.what())}}));
- return sys::ReturnCodes::Failure;
- }
-
- return sys::ReturnCodes::Success;
- }
-
- auto FilesystemEndpoint::sendFileChunk(Context &context) const -> sys::ReturnCodes
- {
- auto returnCode = sys::ReturnCodes::Failure;
- const auto &requestBody = context.getBody();
- const auto txID = requestBody[json::filesystem::txID].int_value();
- const auto chunkNo = requestBody[json::filesystem::chunkNo].int_value();
- const auto data = requestBody[json::filesystem::data].string_value();
-
- if (data.empty()) {
- std::ostringstream errorReason;
- errorReason << "Invalid request txID: " << std::to_string(txID) << ", chunkNo: " << std::to_string(chunkNo);
- LOG_ERROR("%s", errorReason.str().c_str());
-
- context.setResponseStatus(http::Code::BadRequest);
- context.setResponseBody(json11::Json::object({{json::reason, errorReason.str()}}));
- return returnCode;
- }
-
- try {
- returnCode = fileOps.sendDataForTransmitID(txID, chunkNo, data);
- }
- catch (std::exception &e) {
- LOG_ERROR("%s", e.what());
- context.setResponseStatus(http::Code::NotAcceptable);
- context.setResponseBody(json11::Json::object({{json::reason, e.what()}}));
-
- return sys::ReturnCodes::Failure;
- }
- if (returnCode == sys::ReturnCodes::Success) {
- LOG_DEBUG("FileOperations::sendDataForTransmitID success");
- context.setResponseStatus(http::Code::OK);
- context.setResponseBody(json11::Json::object({
- {json::filesystem::txID, static_cast<int>(txID)},
- {json::filesystem::chunkNo, static_cast<int>(chunkNo)},
- }));
+ sender::putToSendQueue(context.createSimpleResponse());
}
- else {
- LOG_ERROR("FileOperations::sendDataForTransmitID failed");
- context.setResponseStatus(http::Code::BadRequest);
- context.setResponseBody(json11::Json::object({
- {json::filesystem::txID, static_cast<int>(txID)},
- {json::filesystem::chunkNo, static_cast<int>(chunkNo)},
- }));
+ if (sent == sent::yes and response) {
+ LOG_ERROR("Response set when we already handled response in handler");
}
-
- return returnCode;
}
} // namespace sdesktop::endpoints
M module-services/service-desktop/endpoints/include/endpoints/JsonKeyNames.hpp => module-services/service-desktop/endpoints/include/endpoints/JsonKeyNames.hpp +1 -26
@@ 24,9 24,7 @@ namespace sdesktop::endpoints::json
inline constexpr auto networkStatus = "networkStatus";
inline constexpr auto networkOperatorName = "networkOperatorName";
inline constexpr auto accessTechnology = "accessTechnology";
- inline constexpr auto fileName = "fileName";
- inline constexpr auto fileSize = "fileSize";
- inline constexpr auto fileCrc32 = "fileCrc32";
+
inline constexpr auto update = "update";
inline constexpr auto updateInfo = "updateInfo";
inline constexpr auto updateError = "updateError";
@@ 52,29 50,6 @@ namespace sdesktop::endpoints::json
inline constexpr auto files = "files";
inline constexpr auto backupLocation = "backupLocation";
- namespace filesystem
- {
- inline constexpr auto command = "command";
- inline constexpr auto chunkSize = "chunkSize";
- inline constexpr auto chunkNo = "chunkNo";
- inline constexpr auto data = "data";
- inline constexpr auto rxID = "rxID";
- inline constexpr auto txID = "txID";
-
- namespace commands
- {
- inline constexpr auto upload = "upload";
- inline constexpr auto rm = "rm";
- inline constexpr auto download = "download";
- inline constexpr auto checkFile = "checkFile";
- } // namespace commands
-
- namespace reasons
- {
- inline constexpr auto fileDoesNotExist = "file does not exist";
- }
- } // namespace filesystem
-
namespace updateprocess
{
inline constexpr auto command = "command";
M module-services/service-desktop/endpoints/include/endpoints/developerMode/DeveloperModeEndpoint.hpp => module-services/service-desktop/endpoints/include/endpoints/developerMode/DeveloperModeEndpoint.hpp +1 -4
@@ 6,7 6,6 @@
#include <endpoints/Endpoint.hpp>
#include "DeveloperModeHelper.hpp"
#include "Mode/UI_Helper.hpp"
-#include "fs/FS_Helper.hpp"
#include <memory>
@@ 18,13 17,11 @@ namespace sdesktop::endpoints
private:
const std::unique_ptr<DeveloperModeHelper> helper;
const std::unique_ptr<UI_Helper> uiHelper;
- const std::unique_ptr<FS_Helper> fsHelper;
public:
explicit DeveloperModeEndpoint(sys::Service *_ownerServicePtr)
: Endpoint(_ownerServicePtr), helper(std::make_unique<DeveloperModeHelper>(ownerServicePtr)),
- uiHelper(std::make_unique<UI_Helper>(ownerServicePtr)),
- fsHelper(std::make_unique<FS_Helper>(ownerServicePtr))
+ uiHelper(std::make_unique<UI_Helper>(ownerServicePtr))
{
debugName = "DeveloperModeEndpoint";
}
R module-services/service-desktop/endpoints/include/endpoints/developerMode/fs/FS_Helper.hpp => module-services/service-desktop/endpoints/include/endpoints/filesystem/FS_Helper.hpp +34 -15
@@ 4,33 4,52 @@
#pragma once
#include <endpoints/BaseHelper.hpp>
+#include "FileOperations.hpp"
namespace sdesktop::endpoints
{
+ namespace json::fs
+ {
+ inline constexpr auto removeFile = "removeFile";
+ inline constexpr auto renameFile = "renameFile";
+ inline constexpr auto destFilename = "destFilename";
+ inline constexpr auto listDir = "listDir";
+ inline constexpr auto path = "path";
+ inline constexpr auto fileName = "fileName";
+ inline constexpr auto fileSize = "fileSize";
+ inline constexpr auto fileCrc32 = "fileCrc32";
+ inline constexpr auto chunkSize = "chunkSize";
+ inline constexpr auto chunkNo = "chunkNo";
+ inline constexpr auto data = "data";
+ inline constexpr auto rxID = "rxID";
+ inline constexpr auto txID = "txID";
+
+ inline constexpr auto fileDoesNotExist = "file does not exist";
+ } // namespace json::fs
class FS_Helper : public BaseHelper
{
public:
- explicit FS_Helper(sys::Service *p) : BaseHelper(p)
+ explicit FS_Helper(sys::Service *p, FileOperations &fileOps) : BaseHelper(p), fileOps(fileOps)
{}
- private:
auto processGet(Context &context) -> ProcessResult final;
auto processPut(Context &context) -> ProcessResult final;
- void preProcess(http::Method method, Context &context) final;
+ auto processDelete(Context &context) -> ProcessResult final;
- bool requestFileRemoval(const std::string &fileName);
- bool requestFileRename(const std::string &fileName, const std::string &destFileName) noexcept;
- ResponseContext requestListDir(const std::string &directory);
- };
+ private:
+ auto startGetFile(Context &context) const -> ResponseContext;
+ auto getFileChunk(Context &context) const -> ResponseContext;
- namespace json::fs
- {
- inline constexpr auto removeFile = "removeFile";
- inline constexpr auto renameFile = "renameFile";
- inline constexpr auto destFileName = "destfilename";
- inline constexpr auto listDir = "listDir";
- inline constexpr auto path = "path";
- } // namespace json::fs
+ auto startSendFile(Context &context) const -> ResponseContext;
+ auto sendFileChunk(Context &context) const -> ResponseContext;
+
+ auto requestFileRemoval(const std::string &fileName) -> bool;
+ auto requestFileRename(const std::string &fileName, const std::string &destFileName) noexcept -> bool;
+ auto requestListDir(const std::string &directory) -> ResponseContext;
+ auto requestLogsFlush() const -> void;
+
+ FileOperations &fileOps;
+ };
} // namespace sdesktop::endpoints
M module-services/service-desktop/endpoints/include/endpoints/filesystem/FilesystemEndpoint.hpp => module-services/service-desktop/endpoints/include/endpoints/filesystem/FilesystemEndpoint.hpp +5 -16
@@ 4,6 4,7 @@
#pragma once
#include <endpoints/Endpoint.hpp>
+#include "FS_Helper.hpp"
#include <Service/Service.hpp>
#include "FileOperations.hpp"
@@ 12,6 13,8 @@ namespace sdesktop::endpoints
class FilesystemEndpoint : public Endpoint
{
+ const std::unique_ptr<FS_Helper> helper;
+
public:
static auto createInstance(sys::Service *ownerServicePtr) -> std::unique_ptr<Endpoint>
{
@@ 19,24 22,10 @@ namespace sdesktop::endpoints
}
explicit FilesystemEndpoint(sys::Service *ownerServicePtr, FileOperations &fileOps)
- : Endpoint(ownerServicePtr), fileOps(fileOps)
+ : Endpoint(ownerServicePtr), helper(std::make_unique<FS_Helper>(ownerServicePtr, fileOps))
{}
- auto handle(Context &context) -> void override;
- auto runGet(Context &context) -> sys::ReturnCodes;
- auto runPost(Context &context) -> sys::ReturnCodes;
- auto runPut(Context &context) -> sys::ReturnCodes;
- auto getUpdates(Context &context) -> sys::ReturnCodes;
-
- private:
- auto startGetFile(Context &context) const -> sys::ReturnCodes;
- auto getFileChunk(Context &context) const -> sys::ReturnCodes;
- auto startSendFile(Context &context) const -> sys::ReturnCodes;
- auto sendFileChunk(Context &context) const -> sys::ReturnCodes;
-
- auto requestLogsFlush() const -> void;
-
- FileOperations &fileOps;
+ auto handle(Context &context) -> void override;
};
} // namespace sdesktop::endpoints
M test/harness => test/harness +1 -1
@@ 1,1 1,1 @@
-Subproject commit 1e3d1ced82e8d94ce89d93f6d03378893c094731
+Subproject commit a7aee485bcb04307202a5439748d6cd56b496a2a