~aleteoryx/muditaos

ref: c58c8568d31deca7c3ccf403986a266ee676c0c0 muditaos/module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.cpp -rw-r--r-- 2.7 KiB
c58c8568 — Pawel Olejniczak [CP-143] Set 204 code for responses with empty body 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "FilesystemEndpoint.hpp"
#include "service-desktop/DesktopMessages.hpp"
#include "service-desktop/ServiceDesktop.hpp"
#include <purefs/filesystem_paths.hpp>

using namespace parserFSM;

auto FilesystemEndpoint::handle(Context &context) -> void
{
    LOG_DEBUG("handle");
    switch (context.getMethod()) {
    case http::Method::post:
        run(context);
        break;
    default:
        break;
    }
}
static bool isWritable(const fs::path &file)
{
    auto lamb = [](std::FILE *stream) { std::fclose(stream); };

    std::unique_ptr<std::FILE, decltype(lamb)> sf(std::fopen(file.c_str(), "w"), lamb);

    return static_cast<bool>(sf);
}

auto FilesystemEndpoint::run(Context &context) -> sys::ReturnCodes
{
    LOG_DEBUG("running");
    sys::ReturnCodes returnCode = sys::ReturnCodes::Failure;
    std::string cmd             = context.getBody()[parserFSM::json::filesystem::command].string_value();

    context.setResponseBody(
        json11::Json::object({{json::status, std::to_string(static_cast<int>(sys::ReturnCodes::Failure))}}));

    auto owner = static_cast<ServiceDesktop *>(ownerServicePtr);

    if (cmd == parserFSM::json::filesystem::commands::download) {
        fs::path filePath    = context.getBody()[parserFSM::json::fileName].string_value();
        fs::path tmpFilePath = purefs::dir::getUpdatesOSPath() / filePath;

        uint32_t fileSize = context.getBody()[parserFSM::json::fileSize].int_value();

        LOG_DEBUG("got owner, file %s", tmpFilePath.c_str());

        if (isWritable(tmpFilePath)) {
            LOG_INFO("download %" PRIu32 " bytes to: %s", fileSize, tmpFilePath.c_str());

            if (owner->desktopWorker->startDownload(tmpFilePath, fileSize) == sys::ReturnCodes::Success) {
                context.setResponseStatus(parserFSM::http::Code::Accepted);
                returnCode = sys::ReturnCodes::Success;
            }
        }
        else {
            LOG_ERROR("download command failed, can't write %" PRIu32 " bytes to: %s", fileSize, tmpFilePath.c_str());
        }
    }
    else if (cmd == parserFSM::json::filesystem::commands::checkFile) {
        fs::path filePath = context.getBody()[parserFSM::json::fileName].string_value();
        LOG_DEBUG("Checking file: %s", filePath.c_str());

        context.setResponseBody(json11::Json::object{{json::fileExists, std::filesystem::exists(filePath)}});
        returnCode = sys::ReturnCodes::Success;
    }
    else {
        LOG_ERROR("unknown command: %s", cmd.c_str());
    }

    MessageHandler::putToSendQueue(context.createSimpleResponse());
    return returnCode;
}