diff options
Diffstat (limited to 'whiteboard.cpp')
-rw-r--r-- | whiteboard.cpp | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/whiteboard.cpp b/whiteboard.cpp index be8bcb0..6782385 100644 --- a/whiteboard.cpp +++ b/whiteboard.cpp @@ -8,11 +8,13 @@ #include <sys/types.h> #include <chrono> +#include <initializer_list> #include <iostream> #include <functional> #include <filesystem> #include <mutex> #include <regex> +#include <sstream> #include <string> #include <thread> #include <unordered_map> @@ -30,6 +32,8 @@ #include <boost/asio/connect.hpp> #include <boost/asio/ip/tcp.hpp> +#include <fmt/core.h> + #include "libreichwein/file.h" #include "config.h" @@ -76,6 +80,19 @@ void Whiteboard::storage_cleanup() } } +std::string make_xml(const std::initializer_list<std::pair<std::string, std::string>>& key_values) +{ + pt::ptree xml; + for (const auto& i: key_values) { + xml.put(fmt::format("serverinfo.{}", i.first), i.second); + } + + std::ostringstream oss; + // write_xml_element instead of write_xml to omit <!xml...> header + pt::xml_parser::write_xml_element(oss, {}, xml, -1, boost::property_tree::xml_writer_settings<pt::ptree::key_type>{}); + return oss.str(); +} + std::string Whiteboard::handle_request(const std::string& request) { try { @@ -93,7 +110,7 @@ std::string Whiteboard::handle_request(const std::string& request) std::string id {xml.get<std::string>("request.id")}; std::string data {xml.get<std::string>("request.data")}; m_storage->setDocument(id, data); - return {}; + return make_xml({{"type", "modify"}, {"revision", std::to_string(m_storage->getRevision(id)) }}); } else if (command == "getfile") { std::string id {xml.get<std::string>("request.id")}; @@ -102,20 +119,19 @@ std::string Whiteboard::handle_request(const std::string& request) if (filedata.size() > 30000000) throw std::runtime_error("File too big"); - return filedata; + return make_xml({{"type", "getfile"}, {"data", filedata}, {"revision", std::to_string(m_storage->getRevision(id)) }}); } else if (command == "checkupdate") { std::string id {xml.get<std::string>("request.id")}; - std::string checksum_s {xml.get<std::string>("request.checksum")}; - uint32_t checksum{static_cast<uint32_t>(stoul(checksum_s))}; + int request_revision {xml.get<int>("request.revision")}; - std::string filedata {m_storage->getDocument(id)}; - if (checksum != m_storage->checksum32(filedata)) { - return filedata; + int revision {m_storage->getRevision(id)}; + if (revision != request_revision) { + return make_xml({{"type", "update"}, {"data", m_storage->getDocument(id)}, {"revision", std::to_string(revision) }}); } else { - return {}; + return {}; // no reply } } else if (command == "newid") { - return m_storage->generate_id(); + return make_xml({{"type", "newid"}, {"id", m_storage->generate_id()}}); } else if (command == "qrcode") { std::string url{xml.get<std::string>("request.url")}; @@ -124,7 +140,7 @@ std::string Whiteboard::handle_request(const std::string& request) std::string pngdata {QRCode::getQRCode(url)}; - return pngdata; + return make_xml({{"type", "qrcode"}, {"png", pngdata}}); } else { throw std::runtime_error("Bad command: "s + command); } @@ -167,7 +183,8 @@ void Whiteboard::do_session(boost::asio::ip::tcp::socket socket) data = handle_request(data); buffer.consume(buffer.size()); boost::beast::ostream(buffer) << data; - ws.write(buffer.data()); + if (buffer.data().size() > 0) + ws.write(buffer.data()); } } catch (boost::beast::system_error const& se) { // This indicates that the session was closed |