106 lines
3.9 KiB
C++
106 lines
3.9 KiB
C++
#include "ipc_serve.hpp"
|
|
|
|
#include <cstdio>
|
|
|
|
#include <asio.hpp>
|
|
#include <asio/read_until.hpp>
|
|
#include <asio/write.hpp>
|
|
|
|
#include <iostream>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#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<int>();
|
|
if (j.contains("max_height"))
|
|
opt.max_height = j["max_height"].get<int>();
|
|
if (j.contains("format") && j["format"].is_string())
|
|
opt.format = j["format"].get<std::string>();
|
|
std::string err;
|
|
bool ok = media::resize_file(j["input"].get<std::string>(), j["output"].get<std::string>(), 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<unsigned short>(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 <asio/local/stream_protocol.hpp>
|
|
#include <unistd.h>
|
|
|
|
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<int>();
|
|
if (j.contains("max_height"))
|
|
opt.max_height = j["max_height"].get<int>();
|
|
if (j.contains("format") && j["format"].is_string())
|
|
opt.format = j["format"].get<std::string>();
|
|
std::string err;
|
|
bool ok = media::resize_file(j["input"].get<std::string>(), j["output"].get<std::string>(), 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
|