#include "ipc_serve.hpp" #include #include #include #include #include #include #include "core/resize.hpp" namespace media::ipc { static int handle_session(asio::ip::tcp::socket sock) { try { asio::streambuf buf; asio::read_until(sock, buf, '\n'); std::istream is(&buf); std::string line; std::getline(is, line); nlohmann::json j = nlohmann::json::parse(line, nullptr, false); if (!j.is_object()) { std::string err = R"({"ok":false,"error":"invalid json"})"; asio::write(sock, asio::buffer(err + "\n")); return 0; } if (!j.contains("input") || !j.contains("output")) { std::string err = R"({"ok":false,"error":"need input and output"})"; asio::write(sock, asio::buffer(err + "\n")); return 0; } media::ResizeOptions opt; if (j.contains("max_width")) opt.max_width = j["max_width"].get(); if (j.contains("max_height")) opt.max_height = j["max_height"].get(); if (j.contains("format") && j["format"].is_string()) opt.format = j["format"].get(); std::string err; bool ok = media::resize_file(j["input"].get(), j["output"].get(), opt, err); nlohmann::json out = ok ? nlohmann::json{{"ok", true}} : nlohmann::json{{"ok", false}, {"error", err}}; std::string payload = out.dump() + "\n"; asio::write(sock, asio::buffer(payload)); } catch (const std::exception& e) { try { std::string err = std::string(R"({"ok":false,"error":")") + e.what() + "\"}\n"; asio::write(sock, asio::buffer(err)); } catch (...) { } } return 0; } int run_tcp_server(const std::string& host, int port) { asio::io_context io; asio::ip::tcp::acceptor acc(io, asio::ip::tcp::endpoint(asio::ip::make_address(host), static_cast(port))); std::cerr << "media-img IPC (TCP) " << host << ":" << port << "\n"; for (;;) { asio::ip::tcp::socket sock(io); acc.accept(sock); handle_session(std::move(sock)); } } #if !defined(_WIN32) #include #include int run_unix_server(const std::string& path) { ::unlink(path.c_str()); asio::io_context io; asio::local::stream_protocol::acceptor acc(io, asio::local::stream_protocol::endpoint(path)); std::cerr << "media-img IPC (unix) " << path << "\n"; for (;;) { asio::local::stream_protocol::socket sock(io); acc.accept(sock); // reuse same JSON line protocol over stream socket asio::streambuf buf; asio::read_until(sock, buf, '\n'); std::istream is(&buf); std::string line; std::getline(is, line); nlohmann::json j = nlohmann::json::parse(line, nullptr, false); if (!j.is_object()) { asio::write(sock, asio::buffer(std::string(R"({"ok":false})") + "\n")); continue; } media::ResizeOptions opt; if (j.contains("max_width")) opt.max_width = j["max_width"].get(); if (j.contains("max_height")) opt.max_height = j["max_height"].get(); if (j.contains("format") && j["format"].is_string()) opt.format = j["format"].get(); std::string err; bool ok = media::resize_file(j["input"].get(), j["output"].get(), opt, err); nlohmann::json out = ok ? nlohmann::json{{"ok", true}} : nlohmann::json{{"ok", false}, {"error", err}}; asio::write(sock, asio::buffer(out.dump() + "\n")); } } #endif } // namespace media::ipc