diff --git a/src/librssguard/CMakeLists.txt b/src/librssguard/CMakeLists.txt
index 848442237..b5fafe424 100644
--- a/src/librssguard/CMakeLists.txt
+++ b/src/librssguard/CMakeLists.txt
@@ -261,6 +261,8 @@ set(SOURCES
network-web/downloadmanager.h
network-web/googlesuggest.cpp
network-web/googlesuggest.h
+ network-web/apiserver.cpp
+ network-web/apiserver.h
network-web/httpresponse.cpp
network-web/httpresponse.h
network-web/httpserver.cpp
diff --git a/src/librssguard/gui/settings/settingsbrowsermail.cpp b/src/librssguard/gui/settings/settingsbrowsermail.cpp
index 1088465a5..8b799219f 100644
--- a/src/librssguard/gui/settings/settingsbrowsermail.cpp
+++ b/src/librssguard/gui/settings/settingsbrowsermail.cpp
@@ -41,6 +41,7 @@ SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
m_ui->m_listTools->header()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
connect(m_ui->m_cbEnableHttp2, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
+ connect(m_ui->m_cbEnableApiServer, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_cbIgnoreAllCookies, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_proxyDetails, &NetworkProxyDetails::changed, this, &SettingsBrowserMail::dirtifySettings);
@@ -172,6 +173,7 @@ void SettingsBrowserMail::loadSettings() {
m_ui->m_cbDisableCache->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::DisableCache)).toBool());
m_ui->m_cbEnableHttp2->setChecked(settings()->value(GROUP(Network), SETTING(Network::EnableHttp2)).toBool());
+ m_ui->m_cbEnableApiServer->setChecked(settings()->value(GROUP(Network), SETTING(Network::EnableApiServer)).toBool());
m_ui->m_cbIgnoreAllCookies
->setChecked(settings()->value(GROUP(Network), SETTING(Network::IgnoreAllCookies)).toBool());
m_ui->m_checkOpenLinksInExternal
@@ -218,8 +220,15 @@ void SettingsBrowserMail::saveSettings() {
settings()->setValue(GROUP(Browser), Browser::DisableCache, m_ui->m_cbDisableCache->isChecked());
settings()->setValue(GROUP(Network), Network::EnableHttp2, m_ui->m_cbEnableHttp2->isChecked());
+ settings()->setValue(GROUP(Network), Network::EnableApiServer, m_ui->m_cbEnableApiServer->isChecked());
settings()->setValue(GROUP(Network), Network::IgnoreAllCookies, m_ui->m_cbIgnoreAllCookies->isChecked());
+ qApp->web()->stopApiServer();
+
+ if (m_ui->m_cbEnableApiServer->isChecked()) {
+ qApp->web()->startApiServer();
+ }
+
settings()->setValue(GROUP(Browser),
Browser::OpenLinksInExternalBrowserRightAway,
m_ui->m_checkOpenLinksInExternal->isChecked());
diff --git a/src/librssguard/gui/settings/settingsbrowsermail.ui b/src/librssguard/gui/settings/settingsbrowsermail.ui
index f44a57ff3..a7862e0a4 100644
--- a/src/librssguard/gui/settings/settingsbrowsermail.ui
+++ b/src/librssguard/gui/settings/settingsbrowsermail.ui
@@ -35,6 +35,13 @@
+ -
+
+
+ Enable API server
+
+
+
diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp
index 84384867a..ef9dc8525 100644
--- a/src/librssguard/miscellaneous/settings.cpp
+++ b/src/librssguard/miscellaneous/settings.cpp
@@ -57,6 +57,9 @@ DKEY Network::ID = "network";
DKEY Network::SendDNT = "send_dnt";
VALUE(bool) Network::SendDNTDef = false;
+DKEY Network::EnableApiServer = "api_server";
+VALUE(bool) Network::EnableApiServerDef = false;
+
DKEY Network::EnableHttp2 = "http2_enabled";
DVALUE(bool) Network::EnableHttp2Def = false;
diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h
index 2f16321c5..23a774ebb 100644
--- a/src/librssguard/miscellaneous/settings.h
+++ b/src/librssguard/miscellaneous/settings.h
@@ -372,6 +372,9 @@ namespace Network {
KEY SendDNT;
VALUE(bool) SendDNTDef;
+ KEY EnableApiServer;
+ VALUE(bool) EnableApiServerDef;
+
KEY EnableHttp2;
VALUE(bool) EnableHttp2Def;
diff --git a/src/librssguard/network-web/apiserver.cpp b/src/librssguard/network-web/apiserver.cpp
new file mode 100644
index 000000000..27e408317
--- /dev/null
+++ b/src/librssguard/network-web/apiserver.cpp
@@ -0,0 +1,23 @@
+// For license of this file, see /LICENSE.md.
+
+#include "network-web/apiserver.h"
+
+#include "definitions/definitions.h"
+
+ApiServer::ApiServer(QObject* parent) : HttpServer(parent) {}
+
+void ApiServer::answerClient(QTcpSocket* socket, const QHttpRequest& request) {
+ QByteArray incoming_data = socket->readAll();
+
+ const QByteArray output_data = incoming_data;
+ 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();
+}
diff --git a/src/librssguard/network-web/apiserver.h b/src/librssguard/network-web/apiserver.h
new file mode 100644
index 000000000..e9bff3716
--- /dev/null
+++ b/src/librssguard/network-web/apiserver.h
@@ -0,0 +1,16 @@
+// For license of this file, see /LICENSE.md.
+
+#ifndef APISERVER_H
+#define APISERVER_H
+
+#include "network-web/httpserver.h"
+
+class ApiServer : public HttpServer {
+ public:
+ explicit ApiServer(QObject* parent = nullptr);
+
+ protected:
+ virtual void answerClient(QTcpSocket* socket, const QHttpRequest& request);
+};
+
+#endif // APISERVER_H
diff --git a/src/librssguard/network-web/oauthhttphandler.cpp b/src/librssguard/network-web/oauthhttphandler.cpp
index 0f7d15ebd..d5c42062f 100644
--- a/src/librssguard/network-web/oauthhttphandler.cpp
+++ b/src/librssguard/network-web/oauthhttphandler.cpp
@@ -62,11 +62,13 @@ void OAuthHttpHandler::answerClient(QTcpSocket* socket, const QHttpRequest& requ
const QString html = QSL("") + qApp->applicationName() + QSL("") +
m_successText + QSL("");
const QByteArray html_utf = html.toUtf8();
- const QByteArray html_size = QString::number(html_utf.size()).toLocal8Bit();
- const QByteArray reply_message = QByteArrayLiteral("HTTP/1.0 200 OK \r\n"
- "Content-Type: text/html; charset=\"utf-8\"\r\n"
- "Content-Length: ") +
- html_size + QByteArrayLiteral("\r\n\r\n") + html_utf;
+ const QByteArray reply_message = QSL("HTTP/1.0 200 OK \r\n"
+ "Content-Type: text/html; charset=\"utf-8\"\r\n"
+ "Content-Length: %1"
+ "\r\n\r\n"
+ "%2")
+ .arg(QString::number(html_utf.size()), html_utf)
+ .toLocal8Bit();
socket->write(reply_message);
}
diff --git a/src/librssguard/network-web/webfactory.cpp b/src/librssguard/network-web/webfactory.cpp
index 21ceb1ea9..b6e842147 100644
--- a/src/librssguard/network-web/webfactory.cpp
+++ b/src/librssguard/network-web/webfactory.cpp
@@ -7,6 +7,7 @@
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/settings.h"
#include "network-web/adblock/adblockmanager.h"
+#include "network-web/apiserver.h"
#include "network-web/cookiejar.h"
#include "network-web/readability.h"
@@ -28,9 +29,13 @@
#include
#endif
-WebFactory::WebFactory(QObject* parent) : QObject(parent), m_customUserAgent(QString()) {
+WebFactory::WebFactory(QObject* parent) : QObject(parent), m_apiServer(nullptr), m_customUserAgent(QString()) {
m_adBlock = new AdBlockManager(this);
+ if (qApp->settings()->value(GROUP(Network), SETTING(Network::EnableApiServer)).toBool()) {
+ startApiServer();
+ }
+
#if defined(NO_LITE)
if (qApp->settings()->value(GROUP(Browser), SETTING(Browser::DisableCache)).toBool()) {
qWarningNN << LOGSEC_NETWORK << "Using off-the-record WebEngine profile.";
@@ -58,6 +63,8 @@ WebFactory::WebFactory(QObject* parent) : QObject(parent), m_customUserAgent(QSt
}
WebFactory::~WebFactory() {
+ stopApiServer();
+
#if defined(NO_LITE)
if (m_engineSettings != nullptr && m_engineSettings->menu() != nullptr) {
m_engineSettings->menu()->deleteLater();
@@ -558,6 +565,22 @@ Readability* WebFactory::readability() const {
return m_readability;
}
+void WebFactory::startApiServer() {
+ m_apiServer = new ApiServer(this);
+ m_apiServer->setListenAddressPort(QSL("http://localhost:54123"), true);
+
+ qDebugNN << LOGSEC_NETWORK << "Started API server:" << QUOTE_W_SPACE_DOT(m_apiServer->listenAddressPort());
+}
+
+void WebFactory::stopApiServer() {
+ if (m_apiServer != nullptr) {
+ delete m_apiServer;
+ m_apiServer = nullptr;
+
+ qDebugNN << LOGSEC_NETWORK << "Stopped API server:" << QUOTE_W_SPACE_DOT(m_apiServer->listenAddressPort());
+ }
+}
+
void WebFactory::generateUnescapes() {
m_htmlNamedEntities[QSL("AElig")] = 0x00c6;
m_htmlNamedEntities[QSL("AMP")] = 38;
diff --git a/src/librssguard/network-web/webfactory.h b/src/librssguard/network-web/webfactory.h
index eaa344b0d..d68f1bd57 100644
--- a/src/librssguard/network-web/webfactory.h
+++ b/src/librssguard/network-web/webfactory.h
@@ -20,6 +20,7 @@ class NetworkUrlInterceptor;
class QMenu;
class AdBlockManager;
class CookieJar;
+class ApiServer;
class Readability;
class WebFactory : public QObject {
@@ -52,6 +53,9 @@ class WebFactory : public QObject {
CookieJar* cookieJar() const;
Readability* readability() const;
+ void startApiServer();
+ void stopApiServer();
+
void updateProxy();
bool sendMessageViaEmail(const Message& message);
@@ -90,6 +94,7 @@ class WebFactory : public QObject {
QAction* m_engineSettings;
#endif
+ ApiServer* m_apiServer;
CookieJar* m_cookieJar;
Readability* m_readability;
QMap m_htmlNamedEntities;