// For license of this file, see /LICENSE.md. #include "network-web/apiserver.h" #include "database/databasefactory.h" #include "database/databasequeries.h" #include "definitions/definitions.h" #include "miscellaneous/application.h" #include ApiServer::ApiServer(QObject* parent) : HttpServer(parent) {} void ApiServer::answerClient(QTcpSocket* socket, const HttpRequest& request) { QByteArray incoming_data = socket->readAll(); QByteArray output_data; QJsonParseError json_err; QJsonDocument incoming_doc = QJsonDocument::fromJson(incoming_data, &json_err); if (json_err.error != QJsonParseError::ParseError::NoError) { output_data = ApiResponse(ApiResponse::Result::Error, ApiRequest::Method::Unknown, QJsonValue(json_err.errorString())) .toJson() .toJson(); } else { ApiRequest req(incoming_doc); try { ApiResponse resp(processRequest(req)); output_data = resp.toJson().toJson(); } catch (const ApplicationException& ex) { ApiResponse err_resp(ApiResponse::Result::Error, req.m_method, ex.message()); output_data = err_resp.toJson().toJson(); } } const QByteArray reply_message = QSL("HTTP/1.0 200 OK \r\n" "Content-Type: application/json; charset=\"utf-8\"\r\n" "Content-Length: %1" "\r\n\r\n" "%2") .arg(QString::number(output_data.size()), output_data) .toLocal8Bit(); socket->write(reply_message); socket->disconnectFromHost(); } ApiResponse ApiServer::processRequest(const ApiRequest& req) const { switch (req.m_method) { case ApiRequest::Method::AppVersion: return processAppVersion(); case ApiRequest::Method::ArticlesFromFeed: return processArticlesFromFeed(req.m_parameters); case ApiRequest::Method::Unknown: default: return processUnknown(); } } ApiResponse ApiServer::processAppVersion() const { return ApiResponse(ApiResponse::Result::Success, ApiRequest::Method::AppVersion, QSL(APP_VERSION)); } ApiResponse ApiServer::processArticlesFromFeed(const QJsonValue& req) const { QJsonObject data = req.toObject(); QString feed_id = data.value(QSL("feed")).toString(); int account_id = data.value(QSL("account")).toInt(); bool newest_first = data.value(QSL("newest_first")).toBool(); bool unread_only = data.value(QSL("unread_only")).toBool(); int row_offset = data.value(QSL("row_offset")).toInt(); int row_limit = data.value(QSL("row_limit")).toInt(); QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className()); QList msgs = DatabaseQueries::getFeedsSlice(database, feed_id, account_id, newest_first, unread_only, row_offset, row_limit); QJsonArray msgs_json_array; for (const Message& msg : msgs) { msgs_json_array.append(msg.toJson()); } ApiResponse resp(ApiResponse::Result::Success, ApiRequest::Method::ArticlesFromFeed, msgs_json_array); return resp; } ApiResponse ApiServer::processUnknown() const { return ApiResponse(ApiResponse::Result::Error, ApiRequest::Method::Unknown, QSL("unknown method")); } QJsonDocument ApiResponse::toJson() const { QJsonObject obj; obj.insert("method", int(m_method)); obj.insert("result", int(m_result)); obj.insert("data", m_response); return QJsonDocument(obj); }