From 1bb76af35fee4620e85fc849108eede838666102 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 12 Dec 2023 09:14:30 +0100 Subject: [PATCH] support cors --- src/librssguard/network-web/apiserver.cpp | 71 +++++++++++++--------- src/librssguard/network-web/apiserver.h | 1 + src/librssguard/network-web/httpserver.cpp | 5 +- src/librssguard/network-web/httpserver.h | 1 + 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/librssguard/network-web/apiserver.cpp b/src/librssguard/network-web/apiserver.cpp index 09cbdb90a..90037fc51 100644 --- a/src/librssguard/network-web/apiserver.cpp +++ b/src/librssguard/network-web/apiserver.cpp @@ -13,47 +13,62 @@ ApiServer::ApiServer(QObject* parent) : HttpServer(parent) {} void ApiServer::answerClient(QTcpSocket* socket, const HttpRequest& request) { QByteArray incoming_data = socket->readAll(); - QByteArray output_data; + QByteArray reply_message; - 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(); + if (request.m_method == HttpRequest::Method::Options) { + reply_message = processCorsPreflight(); } else { - ApiRequest req(incoming_doc); + QJsonParseError json_err; + QByteArray json_data; + QJsonDocument incoming_doc = QJsonDocument::fromJson(incoming_data, &json_err); - try { - ApiResponse resp(processRequest(req)); - - output_data = resp.toJson().toJson(); + if (json_err.error != QJsonParseError::ParseError::NoError) { + json_data = + ApiResponse(ApiResponse::Result::Error, ApiRequest::Method::Unknown, QJsonValue(json_err.errorString())) + .toJson() + .toJson(); } - catch (const ApplicationException& ex) { - ApiResponse err_resp(ApiResponse::Result::Error, req.m_method, ex.message()); + else { + ApiRequest req(incoming_doc); - output_data = err_resp.toJson().toJson(); + try { + ApiResponse resp(processRequest(req)); + + json_data = resp.toJson().toJson(); + } + catch (const ApplicationException& ex) { + ApiResponse err_resp(ApiResponse::Result::Error, req.m_method, ex.message()); + + json_data = err_resp.toJson().toJson(); + } } + + 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") + .arg(QString::number(json_data.size())) + .toLocal8Bit(); + + reply_message += json_data; + + IOFactory::writeFile("a.out", json_data); } - 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") - .arg(QString::number(output_data.size())) - .toLocal8Bit(); - - reply_message += output_data; - - IOFactory::writeFile("a.out", output_data); - socket->write(reply_message); socket->disconnectFromHost(); } +QByteArray ApiServer::processCorsPreflight() const { + QString answer = QSL("HTTP/1.0 204 No Content\r\n" + "Access-Control-Allow-Origin: *\r\n" + "Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE\r\n" + "Access-Control-Max-Age: 86400"); + + return answer.toLocal8Bit(); +} + ApiResponse ApiServer::processRequest(const ApiRequest& req) const { switch (req.m_method) { case ApiRequest::Method::AppVersion: diff --git a/src/librssguard/network-web/apiserver.h b/src/librssguard/network-web/apiserver.h index 01086a50c..66fcb75ba 100644 --- a/src/librssguard/network-web/apiserver.h +++ b/src/librssguard/network-web/apiserver.h @@ -48,6 +48,7 @@ class ApiServer : public HttpServer { virtual void answerClient(QTcpSocket* socket, const HttpRequest& request); private: + QByteArray processCorsPreflight() const; ApiResponse processRequest(const ApiRequest& req) const; ApiResponse processAppVersion() const; ApiResponse processArticlesFromFeed(const QJsonValue& req) const; diff --git a/src/librssguard/network-web/httpserver.cpp b/src/librssguard/network-web/httpserver.cpp index b539316b4..2787e3003 100644 --- a/src/librssguard/network-web/httpserver.cpp +++ b/src/librssguard/network-web/httpserver.cpp @@ -136,7 +136,7 @@ bool HttpServer::HttpRequest::readMethod(QTcpSocket* socket) { while ((socket->bytesAvailable() != 0) && !finished) { const auto c = socket->read(1).at(0); - if ((std::isupper(c) != 0) && m_fragment.size() < 6) { + if ((std::isupper(c) != 0) && m_fragment.size() < 7) { m_fragment += c; } else { @@ -160,6 +160,9 @@ bool HttpServer::HttpRequest::readMethod(QTcpSocket* socket) { else if (m_fragment == "DELETE") { m_method = Method::Delete; } + else if (m_fragment == "OPTIONS") { + m_method = Method::Options; + } else { qWarningNN << LOGSEC_NETWORK << "Invalid operation:" << QUOTE_W_SPACE_DOT(m_fragment.data()); } diff --git a/src/librssguard/network-web/httpserver.h b/src/librssguard/network-web/httpserver.h index 58b198a8e..a6fe5825c 100644 --- a/src/librssguard/network-web/httpserver.h +++ b/src/librssguard/network-web/httpserver.h @@ -57,6 +57,7 @@ class HttpServer : public QObject { Put, Post, Delete, + Options } m_method = Method::Unknown; QString m_address;