mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-05-14 16:30:10 -05:00
Add HTTP condition
This commit is contained in:
parent
c711147d24
commit
f12ef9c9f8
|
|
@ -676,6 +676,34 @@ AdvSceneSwitcher.condition.websocket.type.event="Scene Switcher Event"
|
|||
AdvSceneSwitcher.condition.websocket.useRegex="Use regular expressions"
|
||||
AdvSceneSwitcher.condition.websocket.entry.request="{{type}}was received:"
|
||||
AdvSceneSwitcher.condition.websocket.entry.event="{{type}}was received from{{connection}}:"
|
||||
AdvSceneSwitcher.condition.http="HTTP"
|
||||
AdvSceneSwitcher.condition.http.layout="Receive{{method}}request on{{server}}"
|
||||
AdvSceneSwitcher.condition.http.layout.path="Path:{{path}}{{regex}}"
|
||||
AdvSceneSwitcher.condition.http.layout.body="Body:{{body}}{{regex}}"
|
||||
AdvSceneSwitcher.condition.http.method.any="any"
|
||||
AdvSceneSwitcher.condition.http.method.get="GET"
|
||||
AdvSceneSwitcher.condition.http.method.post="POST"
|
||||
AdvSceneSwitcher.condition.http.method.put="PUT"
|
||||
AdvSceneSwitcher.condition.http.method.patch="PATCH"
|
||||
AdvSceneSwitcher.condition.http.method.delete="DELETE"
|
||||
AdvSceneSwitcher.httpServer.select="Select HTTP server"
|
||||
AdvSceneSwitcher.httpServer.add="Add HTTP server"
|
||||
AdvSceneSwitcher.httpServer.configure="Configure HTTP server"
|
||||
AdvSceneSwitcher.httpServer.invalid="Invalid HTTP server"
|
||||
AdvSceneSwitcher.httpServer.name="Name:"
|
||||
AdvSceneSwitcher.httpServer.port="Port:"
|
||||
AdvSceneSwitcher.httpServer.startOnLoad="Start on load"
|
||||
AdvSceneSwitcher.httpServer.status.listening="Listening"
|
||||
AdvSceneSwitcher.httpServer.status.stopped="Stopped"
|
||||
AdvSceneSwitcher.httpServerTab.title="HTTP Servers"
|
||||
AdvSceneSwitcher.httpServerTab.help="No HTTP servers configured.\nAdd one to receive incoming HTTP requests in conditions."
|
||||
AdvSceneSwitcher.httpServerTab.addButton.tooltip="Add HTTP server"
|
||||
AdvSceneSwitcher.httpServerTab.removeButton.tooltip="Remove HTTP server"
|
||||
AdvSceneSwitcher.httpServerTab.name.header="Name"
|
||||
AdvSceneSwitcher.httpServerTab.port.header="Port"
|
||||
AdvSceneSwitcher.httpServerTab.status.header="Status"
|
||||
AdvSceneSwitcher.httpServerTab.removeSingle.text="Are you sure you want to remove \"%1\"?"
|
||||
AdvSceneSwitcher.httpServerTab.removeMultiple.text="Are you sure you want to remove %1 HTTP servers?"
|
||||
AdvSceneSwitcher.condition.temporaryVariable="Macro property"
|
||||
AdvSceneSwitcher.condition.variable="Variable"
|
||||
AdvSceneSwitcher.condition.variable.type.compare="equals"
|
||||
|
|
@ -2380,9 +2408,14 @@ AdvSceneSwitcher.tempVar.gameCapture.executable="Executable"
|
|||
AdvSceneSwitcher.tempVar.gameCapture.executable.description="Executable name of the application captured by the source."
|
||||
|
||||
AdvSceneSwitcher.tempVar.http.status="Status code"
|
||||
AdvSceneSwitcher.tempVar.http.body="Message body"
|
||||
AdvSceneSwitcher.tempVar.http.error="Error"
|
||||
AdvSceneSwitcher.tempVar.http.error.description="Empty when no error occurred.\nOther possible values:\n\n * Could not establish connection\n * Failed to bind IP address\n * Failed to read connection\n * Failed to write connection\n * Maximum redirect count exceeded\n * Connection handling canceled\n * SSL connection failed\n * SSL certificate loading failed\n * SSL server verification failed\n * Unsupported HTTP multipart boundary characters\n * Compression failed\n * Connection timed out\n * Proxy connection failed\n * Unknown"
|
||||
AdvSceneSwitcher.tempVar.http.method="Method"
|
||||
AdvSceneSwitcher.tempVar.http.method.description="Received HTTP request method"
|
||||
AdvSceneSwitcher.tempVar.http.path="Request path"
|
||||
AdvSceneSwitcher.tempVar.http.path.description="Received HTTP request path"
|
||||
AdvSceneSwitcher.tempVar.http.body="Message body"
|
||||
AdvSceneSwitcher.tempVar.http.body.description="Received HTTP request body"
|
||||
|
||||
AdvSceneSwitcher.tempVar.mqtt.message="Message"
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,17 @@ if(MSVC)
|
|||
endif()
|
||||
|
||||
target_sources(
|
||||
${PROJECT_NAME} PRIVATE macro-action-http.cpp macro-action-http.hpp
|
||||
key-value-list.cpp key-value-list.hpp)
|
||||
${PROJECT_NAME}
|
||||
PRIVATE macro-action-http.cpp
|
||||
macro-action-http.hpp
|
||||
macro-condition-http.cpp
|
||||
macro-condition-http.hpp
|
||||
http-server.cpp
|
||||
http-server.hpp
|
||||
http-server-tab.cpp
|
||||
http-server-tab.hpp
|
||||
key-value-list.cpp
|
||||
key-value-list.hpp)
|
||||
|
||||
setup_advss_plugin(${PROJECT_NAME})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
||||
|
|
|
|||
223
plugins/http/http-server-tab.cpp
Normal file
223
plugins/http/http-server-tab.cpp
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
#include "http-server-tab.hpp"
|
||||
#include "http-server.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "sync-helpers.hpp"
|
||||
#include "tab-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QTimer>
|
||||
|
||||
namespace advss {
|
||||
|
||||
static bool registerTab();
|
||||
static void setupTab(QTabWidget *);
|
||||
static bool registerTabDone = registerTab();
|
||||
|
||||
static HttpServersTable *tabWidget = nullptr;
|
||||
|
||||
static bool registerTab()
|
||||
{
|
||||
AddSetupTabCallback("httpServerTab", HttpServersTable::Create,
|
||||
setupTab);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void setTabVisible(QTabWidget *tab, bool visible)
|
||||
{
|
||||
SetTabVisibleByName(
|
||||
tab, visible,
|
||||
obs_module_text("AdvSceneSwitcher.httpServerTab.title"));
|
||||
}
|
||||
|
||||
HttpServersTable *HttpServersTable::Create()
|
||||
{
|
||||
tabWidget = new HttpServersTable();
|
||||
return tabWidget;
|
||||
}
|
||||
|
||||
void HttpServersTable::Add()
|
||||
{
|
||||
auto newServer = std::make_shared<HttpServer>();
|
||||
bool accepted = HttpServerSettingsDialog::AskForSettings(
|
||||
GetSettingsWindow(), *newServer);
|
||||
if (!accepted) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
auto lock = LockContext();
|
||||
GetHttpServers().emplace_back(newServer);
|
||||
}
|
||||
|
||||
HttpServerSignalManager::Instance()->Add(
|
||||
QString::fromStdString(newServer->Name()));
|
||||
}
|
||||
|
||||
void HttpServersTable::Remove()
|
||||
{
|
||||
auto selectedRows =
|
||||
tabWidget->Table()->selectionModel()->selectedRows();
|
||||
if (selectedRows.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList serverNames;
|
||||
for (const auto &row : selectedRows) {
|
||||
auto cell = tabWidget->Table()->item(row.row(), 0);
|
||||
if (!cell) {
|
||||
continue;
|
||||
}
|
||||
serverNames << cell->text();
|
||||
}
|
||||
|
||||
const int count = serverNames.size();
|
||||
if (count == 1) {
|
||||
const QString msg = obs_module_text(
|
||||
"AdvSceneSwitcher.httpServerTab.removeSingle.text");
|
||||
if (!DisplayMessage(msg.arg(serverNames.at(0)), true)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const QString msg = obs_module_text(
|
||||
"AdvSceneSwitcher.httpServerTab.removeMultiple.text");
|
||||
if (!DisplayMessage(msg.arg(count), true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto lock = LockContext();
|
||||
RemoveItemsByName(GetHttpServers(), serverNames);
|
||||
}
|
||||
|
||||
for (const auto &name : serverNames) {
|
||||
HttpServerSignalManager::Instance()->Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getCellLabels(HttpServer *server, bool addName = true)
|
||||
{
|
||||
assert(server);
|
||||
QStringList result;
|
||||
if (addName) {
|
||||
result << QString::fromStdString(server->Name());
|
||||
}
|
||||
result << QString::number(server->GetPort())
|
||||
<< obs_module_text(
|
||||
server->IsListening()
|
||||
? "AdvSceneSwitcher.httpServer.status.listening"
|
||||
: "AdvSceneSwitcher.httpServer.status.stopped");
|
||||
return result;
|
||||
}
|
||||
|
||||
static void updateServerStatus(QTableWidget *table)
|
||||
{
|
||||
for (int row = 0; row < table->rowCount(); ++row) {
|
||||
auto item = table->item(row, 0);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
auto weakServer = GetWeakHttpServerByQString(item->text());
|
||||
auto server = weakServer.lock();
|
||||
if (!server) {
|
||||
continue;
|
||||
}
|
||||
UpdateItemTableRow(table, row,
|
||||
getCellLabels(server.get(), false));
|
||||
}
|
||||
}
|
||||
|
||||
static void openSettingsDialog()
|
||||
{
|
||||
auto selectedRows =
|
||||
tabWidget->Table()->selectionModel()->selectedRows();
|
||||
if (selectedRows.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto cell = tabWidget->Table()->item(selectedRows.last().row(), 0);
|
||||
if (!cell) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto weakServer = GetWeakHttpServerByQString(cell->text());
|
||||
auto server = weakServer.lock();
|
||||
if (!server) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto oldName = server->Name();
|
||||
bool accepted = HttpServerSettingsDialog::AskForSettings(
|
||||
GetSettingsWindow(), *server);
|
||||
if (accepted && oldName != server->Name()) {
|
||||
HttpServerSignalManager::Instance()->Rename(
|
||||
QString::fromStdString(oldName),
|
||||
QString::fromStdString(server->Name()));
|
||||
}
|
||||
updateServerStatus(tabWidget->Table());
|
||||
}
|
||||
|
||||
static const QStringList headers =
|
||||
QStringList()
|
||||
<< obs_module_text("AdvSceneSwitcher.httpServerTab.name.header")
|
||||
<< obs_module_text("AdvSceneSwitcher.httpServerTab.port.header")
|
||||
<< obs_module_text("AdvSceneSwitcher.httpServerTab.status.header");
|
||||
|
||||
HttpServersTable::HttpServersTable(QTabWidget *parent)
|
||||
: ResourceTable(
|
||||
parent,
|
||||
obs_module_text("AdvSceneSwitcher.httpServerTab.help"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.httpServerTab.addButton.tooltip"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.httpServerTab.removeButton.tooltip"),
|
||||
headers, openSettingsDialog)
|
||||
{
|
||||
for (const auto &s : GetHttpServers()) {
|
||||
auto server = std::static_pointer_cast<HttpServer>(s);
|
||||
AddItemTableRow(Table(), getCellLabels(server.get()));
|
||||
}
|
||||
SetHelpVisible(GetHttpServers().empty());
|
||||
}
|
||||
|
||||
static void setupTab(QTabWidget *tab)
|
||||
{
|
||||
if (GetHttpServers().empty()) {
|
||||
setTabVisible(tab, false);
|
||||
}
|
||||
|
||||
QWidget::connect(HttpServerSignalManager::Instance(),
|
||||
&HttpServerSignalManager::Rename, tab,
|
||||
[](const QString &oldName, const QString &newName) {
|
||||
RenameItemTableRow(tabWidget->Table(), oldName,
|
||||
newName);
|
||||
});
|
||||
QWidget::connect(
|
||||
HttpServerSignalManager::Instance(),
|
||||
&HttpServerSignalManager::Add, tab, [tab](const QString &name) {
|
||||
AddItemTableRow(tabWidget->Table(),
|
||||
getCellLabels(GetHttpServerByName(
|
||||
name.toStdString())));
|
||||
tabWidget->SetHelpVisible(false);
|
||||
tabWidget->HighlightAddButton(false);
|
||||
setTabVisible(tab, true);
|
||||
});
|
||||
QWidget::connect(HttpServerSignalManager::Instance(),
|
||||
&HttpServerSignalManager::Remove, tab,
|
||||
[](const QString &name) {
|
||||
RemoveItemTableRow(tabWidget->Table(), name);
|
||||
if (tabWidget->Table()->rowCount() == 0) {
|
||||
tabWidget->SetHelpVisible(true);
|
||||
tabWidget->HighlightAddButton(true);
|
||||
}
|
||||
});
|
||||
|
||||
auto timer = new QTimer(tabWidget);
|
||||
timer->setInterval(1000);
|
||||
QWidget::connect(timer, &QTimer::timeout,
|
||||
[]() { updateServerStatus(tabWidget->Table()); });
|
||||
timer->start();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
20
plugins/http/http-server-tab.hpp
Normal file
20
plugins/http/http-server-tab.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include "resource-table.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
class HttpServersTable final : public ResourceTable {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static HttpServersTable *Create();
|
||||
|
||||
private slots:
|
||||
void Add();
|
||||
void Remove();
|
||||
|
||||
private:
|
||||
HttpServersTable(QTabWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
364
plugins/http/http-server.cpp
Normal file
364
plugins/http/http-server.cpp
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
#include "http-server.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "log-helper.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
|
||||
#include <obs-data.h>
|
||||
#include <httplib.h>
|
||||
|
||||
#undef DispatchMessage
|
||||
|
||||
Q_DECLARE_METATYPE(advss::HttpServer *);
|
||||
|
||||
namespace advss {
|
||||
|
||||
static std::deque<std::shared_ptr<Item>> httpServers;
|
||||
static void saveHttpServers(obs_data_t *obj);
|
||||
static void loadHttpServers(obs_data_t *obj);
|
||||
static bool setup();
|
||||
static bool setupDone = setup();
|
||||
|
||||
bool setup()
|
||||
{
|
||||
AddSaveStep(saveHttpServers);
|
||||
AddLoadStep(loadHttpServers);
|
||||
AddPluginCleanupStep([]() {
|
||||
for (auto &s : httpServers) {
|
||||
auto server = std::dynamic_pointer_cast<HttpServer>(s);
|
||||
if (server) {
|
||||
server->Stop();
|
||||
}
|
||||
}
|
||||
httpServers.clear();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
static void saveHttpServers(obs_data_t *obj)
|
||||
{
|
||||
auto array = obs_data_array_create();
|
||||
for (const auto &s : httpServers) {
|
||||
auto item = obs_data_create();
|
||||
s->Save(item);
|
||||
obs_data_array_push_back(array, item);
|
||||
obs_data_release(item);
|
||||
}
|
||||
obs_data_set_array(obj, "httpServers", array);
|
||||
obs_data_array_release(array);
|
||||
}
|
||||
|
||||
static void loadHttpServers(obs_data_t *obj)
|
||||
{
|
||||
httpServers.clear();
|
||||
auto array = obs_data_get_array(obj, "httpServers");
|
||||
const size_t count = obs_data_array_count(array);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
auto item = obs_data_array_item(array, i);
|
||||
auto server = HttpServer::Create();
|
||||
httpServers.emplace_back(server);
|
||||
httpServers.back()->Load(item);
|
||||
obs_data_release(item);
|
||||
}
|
||||
obs_data_array_release(array);
|
||||
}
|
||||
|
||||
struct HttpServer::Impl {
|
||||
std::unique_ptr<httplib::Server> server;
|
||||
std::thread thread;
|
||||
std::mutex mutex;
|
||||
std::atomic_bool listening{false};
|
||||
MessageDispatcher<HttpRequest> dispatcher;
|
||||
};
|
||||
|
||||
HttpServer::HttpServer() : _impl(std::make_unique<Impl>()) {}
|
||||
|
||||
HttpServer::HttpServer(const HttpServer &other)
|
||||
: Item(other),
|
||||
_impl(std::make_unique<Impl>())
|
||||
{
|
||||
_port = other._port;
|
||||
_startOnLoad = other._startOnLoad;
|
||||
}
|
||||
|
||||
HttpServer &HttpServer::operator=(const HttpServer &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
Stop();
|
||||
_name = other._name;
|
||||
_port = other._port;
|
||||
_startOnLoad = other._startOnLoad;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
HttpServer::~HttpServer()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
bool HttpServer::IsListening() const
|
||||
{
|
||||
return _impl->listening.load();
|
||||
}
|
||||
|
||||
void HttpServer::Start()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_impl->mutex);
|
||||
|
||||
if (_impl->server) {
|
||||
_impl->server->stop();
|
||||
}
|
||||
if (_impl->thread.joinable()) {
|
||||
_impl->thread.join();
|
||||
}
|
||||
|
||||
_impl->server = std::make_unique<httplib::Server>();
|
||||
_impl->listening.store(false);
|
||||
|
||||
auto handleRequest = [this](const httplib::Request &req,
|
||||
httplib::Response &res) {
|
||||
HttpRequest request;
|
||||
request.method = req.method;
|
||||
request.path = req.path;
|
||||
request.body = req.body;
|
||||
for (const auto &[name, value] : req.headers) {
|
||||
request.headers.emplace(name, value);
|
||||
}
|
||||
_impl->dispatcher.DispatchMessage(request);
|
||||
res.status = 200;
|
||||
};
|
||||
|
||||
_impl->server->Get(".*", handleRequest);
|
||||
_impl->server->Post(".*", handleRequest);
|
||||
_impl->server->Put(".*", handleRequest);
|
||||
_impl->server->Patch(".*", handleRequest);
|
||||
_impl->server->Delete(".*", handleRequest);
|
||||
|
||||
const int port = _port;
|
||||
const std::string name = _name;
|
||||
auto serverPtr = _impl->server.get();
|
||||
auto listeningFlag = &_impl->listening;
|
||||
|
||||
_impl->thread = std::thread([serverPtr, listeningFlag, port, name]() {
|
||||
if (!serverPtr->bind_to_port("0.0.0.0", port)) {
|
||||
blog(LOG_WARNING,
|
||||
"HTTP server \"%s\" failed to bind to port %d",
|
||||
name.c_str(), port);
|
||||
return;
|
||||
}
|
||||
listeningFlag->store(true);
|
||||
blog(LOG_INFO, "HTTP server \"%s\" listening on port %d",
|
||||
name.c_str(), port);
|
||||
serverPtr->listen_after_bind();
|
||||
listeningFlag->store(false);
|
||||
blog(LOG_INFO, "HTTP server \"%s\" stopped", name.c_str());
|
||||
});
|
||||
}
|
||||
|
||||
void HttpServer::Stop()
|
||||
{
|
||||
if (!_impl) {
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(_impl->mutex);
|
||||
if (_impl->server) {
|
||||
_impl->server->stop();
|
||||
}
|
||||
if (_impl->thread.joinable()) {
|
||||
_impl->thread.join();
|
||||
}
|
||||
_impl->server.reset();
|
||||
_impl->listening.store(false);
|
||||
}
|
||||
|
||||
HttpRequestBuffer HttpServer::RegisterForRequests()
|
||||
{
|
||||
return _impl->dispatcher.RegisterClient();
|
||||
}
|
||||
|
||||
void HttpServer::Load(obs_data_t *obj)
|
||||
{
|
||||
Item::Load(obj);
|
||||
_port = (int)obs_data_get_int(obj, "port");
|
||||
_startOnLoad = obs_data_get_bool(obj, "startOnLoad");
|
||||
if (_startOnLoad) {
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
void HttpServer::Save(obs_data_t *obj) const
|
||||
{
|
||||
Item::Save(obj);
|
||||
obs_data_set_int(obj, "port", _port);
|
||||
obs_data_set_bool(obj, "startOnLoad", _startOnLoad);
|
||||
}
|
||||
|
||||
HttpServer *GetHttpServerByName(const std::string &name)
|
||||
{
|
||||
for (auto &s : httpServers) {
|
||||
if (s->Name() == name) {
|
||||
return dynamic_cast<HttpServer *>(s.get());
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::weak_ptr<HttpServer> GetWeakHttpServerByName(const std::string &name)
|
||||
{
|
||||
for (const auto &s : httpServers) {
|
||||
if (s->Name() == name) {
|
||||
return std::dynamic_pointer_cast<HttpServer>(s);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::weak_ptr<HttpServer> GetWeakHttpServerByQString(const QString &name)
|
||||
{
|
||||
return GetWeakHttpServerByName(name.toStdString());
|
||||
}
|
||||
|
||||
std::string GetWeakHttpServerName(const std::weak_ptr<HttpServer> &server)
|
||||
{
|
||||
auto s = server.lock();
|
||||
if (!s) {
|
||||
return obs_module_text("AdvSceneSwitcher.httpServer.invalid");
|
||||
}
|
||||
return s->Name();
|
||||
}
|
||||
|
||||
std::deque<std::shared_ptr<Item>> &GetHttpServers()
|
||||
{
|
||||
return httpServers;
|
||||
}
|
||||
|
||||
// --- HttpServerSettingsDialog ---
|
||||
|
||||
static bool ServerNameAvailable(const QString &name)
|
||||
{
|
||||
return !GetHttpServerByName(name.toStdString());
|
||||
}
|
||||
|
||||
static bool AskForSettingsWrapper(QWidget *parent, Item &settings)
|
||||
{
|
||||
HttpServer &server = dynamic_cast<HttpServer &>(settings);
|
||||
return HttpServerSettingsDialog::AskForSettings(parent, server);
|
||||
}
|
||||
|
||||
HttpServerSettingsDialog::HttpServerSettingsDialog(QWidget *parent,
|
||||
const HttpServer &settings)
|
||||
: ItemSettingsDialog(settings, httpServers,
|
||||
"AdvSceneSwitcher.httpServer.select",
|
||||
"AdvSceneSwitcher.httpServer.add",
|
||||
"AdvSceneSwitcher.item.nameNotAvailable", true,
|
||||
parent),
|
||||
_port(new QSpinBox()),
|
||||
_startOnLoad(new QCheckBox()),
|
||||
_layout(new QGridLayout())
|
||||
{
|
||||
_port->setMinimum(1);
|
||||
_port->setMaximum(65535);
|
||||
_port->setValue(settings._port);
|
||||
_startOnLoad->setChecked(settings._startOnLoad);
|
||||
|
||||
int row = 0;
|
||||
_layout->addWidget(
|
||||
new QLabel(obs_module_text("AdvSceneSwitcher.httpServer.name")),
|
||||
row, 0);
|
||||
auto nameLayout = new QHBoxLayout;
|
||||
nameLayout->addWidget(_name);
|
||||
nameLayout->addWidget(_nameHint);
|
||||
_layout->addLayout(nameLayout, row, 1);
|
||||
++row;
|
||||
_layout->addWidget(
|
||||
new QLabel(obs_module_text("AdvSceneSwitcher.httpServer.port")),
|
||||
row, 0);
|
||||
_layout->addWidget(_port, row, 1);
|
||||
++row;
|
||||
_layout->addWidget(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.httpServer.startOnLoad")),
|
||||
row, 0);
|
||||
_layout->addWidget(_startOnLoad, row, 1);
|
||||
++row;
|
||||
_layout->addWidget(_buttonbox, row, 0, 1, -1);
|
||||
setLayout(_layout);
|
||||
|
||||
MinimizeSizeOfColumn(_layout, 0);
|
||||
}
|
||||
|
||||
bool HttpServerSettingsDialog::AskForSettings(QWidget *parent,
|
||||
HttpServer &settings)
|
||||
{
|
||||
HttpServerSettingsDialog dialog(parent, settings);
|
||||
dialog.setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
||||
if (dialog.exec() != DialogCode::Accepted) {
|
||||
return false;
|
||||
}
|
||||
settings._name = dialog._name->text().toStdString();
|
||||
settings._port = dialog._port->value();
|
||||
settings._startOnLoad = dialog._startOnLoad->isChecked();
|
||||
settings.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
HttpServerSelection::HttpServerSelection(QWidget *parent)
|
||||
: ItemSelection(httpServers, HttpServer::Create, AskForSettingsWrapper,
|
||||
"AdvSceneSwitcher.httpServer.select",
|
||||
"AdvSceneSwitcher.httpServer.add",
|
||||
"AdvSceneSwitcher.item.nameNotAvailable",
|
||||
"AdvSceneSwitcher.httpServer.configure", parent)
|
||||
{
|
||||
QWidget::connect(HttpServerSignalManager::Instance(),
|
||||
SIGNAL(Rename(const QString &, const QString &)), this,
|
||||
SLOT(RenameItem(const QString &, const QString &)));
|
||||
QWidget::connect(HttpServerSignalManager::Instance(),
|
||||
SIGNAL(Add(const QString &)), this,
|
||||
SLOT(AddItem(const QString &)));
|
||||
QWidget::connect(HttpServerSignalManager::Instance(),
|
||||
SIGNAL(Remove(const QString &)), this,
|
||||
SLOT(RemoveItem(const QString &)));
|
||||
|
||||
QWidget::connect(this,
|
||||
SIGNAL(ItemRenamed(const QString &, const QString &)),
|
||||
HttpServerSignalManager::Instance(),
|
||||
SIGNAL(Rename(const QString &, const QString &)));
|
||||
QWidget::connect(this, SIGNAL(ItemAdded(const QString &)),
|
||||
HttpServerSignalManager::Instance(),
|
||||
SIGNAL(Add(const QString &)));
|
||||
QWidget::connect(this, SIGNAL(ItemRemoved(const QString &)),
|
||||
HttpServerSignalManager::Instance(),
|
||||
SIGNAL(Remove(const QString &)));
|
||||
}
|
||||
|
||||
void HttpServerSelection::SetServer(const std::string &name)
|
||||
{
|
||||
if (GetHttpServerByName(name)) {
|
||||
SetItem(name);
|
||||
} else {
|
||||
SetItem("");
|
||||
}
|
||||
}
|
||||
|
||||
void HttpServerSelection::SetServer(const std::weak_ptr<HttpServer> &server)
|
||||
{
|
||||
auto s = server.lock();
|
||||
if (s) {
|
||||
SetItem(s->Name());
|
||||
} else {
|
||||
SetItem("");
|
||||
}
|
||||
}
|
||||
|
||||
HttpServerSignalManager::HttpServerSignalManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
HttpServerSignalManager *HttpServerSignalManager::Instance()
|
||||
{
|
||||
static HttpServerSignalManager manager;
|
||||
return &manager;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
101
plugins/http/http-server.hpp
Normal file
101
plugins/http/http-server.hpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#pragma once
|
||||
#include "item-selection-helpers.hpp"
|
||||
#include "message-buffer.hpp"
|
||||
#include "message-dispatcher.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
#include <QSpinBox>
|
||||
|
||||
namespace advss {
|
||||
|
||||
struct HttpRequest {
|
||||
std::string method;
|
||||
std::string path;
|
||||
std::string body;
|
||||
std::map<std::string, std::string> headers;
|
||||
};
|
||||
|
||||
using HttpRequestBuffer = std::shared_ptr<MessageBuffer<HttpRequest>>;
|
||||
|
||||
class HttpServerSelection;
|
||||
class HttpServerSettingsDialog;
|
||||
|
||||
class HttpServer : public Item {
|
||||
public:
|
||||
HttpServer();
|
||||
HttpServer(const HttpServer &);
|
||||
HttpServer &operator=(const HttpServer &);
|
||||
~HttpServer();
|
||||
|
||||
static std::shared_ptr<Item> Create()
|
||||
{
|
||||
return std::make_shared<HttpServer>();
|
||||
}
|
||||
|
||||
void Load(obs_data_t *obj);
|
||||
void Save(obs_data_t *obj) const;
|
||||
|
||||
HttpRequestBuffer RegisterForRequests();
|
||||
int GetPort() const { return _port; }
|
||||
bool IsListening() const;
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
int _port = 16384;
|
||||
bool _startOnLoad = true;
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> _impl;
|
||||
|
||||
friend HttpServerSelection;
|
||||
friend HttpServerSettingsDialog;
|
||||
};
|
||||
|
||||
class HttpServerSettingsDialog : public ItemSettingsDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HttpServerSettingsDialog(QWidget *parent, const HttpServer &);
|
||||
static bool AskForSettings(QWidget *parent, HttpServer &settings);
|
||||
|
||||
private:
|
||||
QSpinBox *_port;
|
||||
QCheckBox *_startOnLoad;
|
||||
QGridLayout *_layout;
|
||||
};
|
||||
|
||||
class HttpServerSelection : public ItemSelection {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HttpServerSelection(QWidget *parent = nullptr);
|
||||
void SetServer(const std::string &);
|
||||
void SetServer(const std::weak_ptr<HttpServer> &);
|
||||
};
|
||||
|
||||
class HttpServerSignalManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
HttpServerSignalManager(QObject *parent = nullptr);
|
||||
static HttpServerSignalManager *Instance();
|
||||
|
||||
signals:
|
||||
void Rename(const QString &, const QString &);
|
||||
void Add(const QString &);
|
||||
void Remove(const QString &);
|
||||
};
|
||||
|
||||
HttpServer *GetHttpServerByName(const std::string &);
|
||||
std::weak_ptr<HttpServer> GetWeakHttpServerByName(const std::string &);
|
||||
std::weak_ptr<HttpServer> GetWeakHttpServerByQString(const QString &);
|
||||
std::string GetWeakHttpServerName(const std::weak_ptr<HttpServer> &);
|
||||
std::deque<std::shared_ptr<Item>> &GetHttpServers();
|
||||
|
||||
} // namespace advss
|
||||
313
plugins/http/macro-condition-http.cpp
Normal file
313
plugins/http/macro-condition-http.cpp
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
#include "macro-condition-http.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "macro-helpers.hpp"
|
||||
|
||||
#undef DELETE
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroConditionHttp::id = "http";
|
||||
|
||||
bool MacroConditionHttp::_registered = MacroConditionFactory::Register(
|
||||
MacroConditionHttp::id,
|
||||
{MacroConditionHttp::Create, MacroConditionHttpEdit::Create,
|
||||
"AdvSceneSwitcher.condition.http"});
|
||||
|
||||
static const std::map<MacroConditionHttp::Method, std::string> methodLabels = {
|
||||
{MacroConditionHttp::Method::ANY,
|
||||
"AdvSceneSwitcher.condition.http.method.any"},
|
||||
{MacroConditionHttp::Method::GET,
|
||||
"AdvSceneSwitcher.condition.http.method.get"},
|
||||
{MacroConditionHttp::Method::POST,
|
||||
"AdvSceneSwitcher.condition.http.method.post"},
|
||||
{MacroConditionHttp::Method::PUT,
|
||||
"AdvSceneSwitcher.condition.http.method.put"},
|
||||
{MacroConditionHttp::Method::PATCH,
|
||||
"AdvSceneSwitcher.condition.http.method.patch"},
|
||||
{MacroConditionHttp::Method::DELETE,
|
||||
"AdvSceneSwitcher.condition.http.method.delete"},
|
||||
};
|
||||
|
||||
static std::string_view methodToString(MacroConditionHttp::Method method)
|
||||
{
|
||||
switch (method) {
|
||||
case MacroConditionHttp::Method::GET:
|
||||
return "GET";
|
||||
case MacroConditionHttp::Method::POST:
|
||||
return "POST";
|
||||
case MacroConditionHttp::Method::PUT:
|
||||
return "PUT";
|
||||
case MacroConditionHttp::Method::PATCH:
|
||||
return "PATCH";
|
||||
case MacroConditionHttp::Method::DELETE:
|
||||
return "DELETE";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void MacroConditionHttp::SetServer(const std::string &name)
|
||||
{
|
||||
_server = GetWeakHttpServerByName(name);
|
||||
auto server = _server.lock();
|
||||
if (!server) {
|
||||
_requestBuffer.reset();
|
||||
return;
|
||||
}
|
||||
_requestBuffer = server->RegisterForRequests();
|
||||
}
|
||||
|
||||
bool MacroConditionHttp::CheckCondition()
|
||||
{
|
||||
if (!_requestBuffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool macroWasPausedSinceLastCheck =
|
||||
MacroWasPausedSince(GetMacro(), _lastCheck);
|
||||
_lastCheck = std::chrono::high_resolution_clock::now();
|
||||
if (macroWasPausedSinceLastCheck) {
|
||||
_requestBuffer->Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!_requestBuffer->Empty()) {
|
||||
auto request = _requestBuffer->ConsumeMessage();
|
||||
if (!request) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SetTempVarValue("method", request->method);
|
||||
SetTempVarValue("path", request->path);
|
||||
SetTempVarValue("body", request->body);
|
||||
|
||||
if (_method != Method::ANY &&
|
||||
request->method != methodToString(_method)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string pathPattern = std::string(_path);
|
||||
if (_pathRegex.Enabled()) {
|
||||
if (!_pathRegex.Matches(request->path, _path)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (request->path != pathPattern) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string bodyPattern = std::string(_body);
|
||||
if (_bodyRegex.Enabled()) {
|
||||
if (!_bodyRegex.Matches(request->body, _body)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (request->body != bodyPattern) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (_clearBufferOnMatch) {
|
||||
_requestBuffer->Clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionHttp::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_int(obj, "method", static_cast<int>(_method));
|
||||
_path.Save(obj, "path");
|
||||
_pathRegex.Save(obj, "pathRegex");
|
||||
_body.Save(obj, "body");
|
||||
_bodyRegex.Save(obj, "bodyRegex");
|
||||
obs_data_set_bool(obj, "clearBufferOnMatch", _clearBufferOnMatch);
|
||||
auto server = _server.lock();
|
||||
obs_data_set_string(obj, "server",
|
||||
server ? server->Name().c_str() : "");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionHttp::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_method = static_cast<Method>(obs_data_get_int(obj, "method"));
|
||||
_path.Load(obj, "path");
|
||||
_pathRegex.Load(obj, "pathRegex");
|
||||
_body.Load(obj, "body");
|
||||
_bodyRegex.Load(obj, "bodyRegex");
|
||||
_clearBufferOnMatch = obs_data_get_bool(obj, "clearBufferOnMatch");
|
||||
if (!obs_data_has_user_value(obj, "clearBufferOnMatch")) {
|
||||
_clearBufferOnMatch = true;
|
||||
}
|
||||
SetServer(obs_data_get_string(obj, "server"));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionHttp::GetShortDesc() const
|
||||
{
|
||||
auto server = _server.lock();
|
||||
return server ? server->Name() : "";
|
||||
}
|
||||
|
||||
void MacroConditionHttp::SetupTempVars()
|
||||
{
|
||||
MacroCondition::SetupTempVars();
|
||||
AddTempvar("method",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.http.method"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.http.method.description"));
|
||||
AddTempvar("path",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.http.path"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.http.path.description"));
|
||||
AddTempvar("body",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.http.body"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.http.body.description"));
|
||||
}
|
||||
|
||||
static void populateMethodSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[value, name] : methodLabels) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(value));
|
||||
}
|
||||
}
|
||||
|
||||
MacroConditionHttpEdit::MacroConditionHttpEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionHttp> entryData)
|
||||
: QWidget(parent),
|
||||
_method(new QComboBox(this)),
|
||||
_server(new HttpServerSelection(this)),
|
||||
_path(new VariableLineEdit(this)),
|
||||
_pathRegex(new RegexConfigWidget(this)),
|
||||
_body(new VariableTextEdit(this)),
|
||||
_bodyRegex(new RegexConfigWidget(this)),
|
||||
_clearBufferOnMatch(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.clearBufferOnMatch")))
|
||||
{
|
||||
populateMethodSelection(_method);
|
||||
|
||||
QWidget::connect(_method, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(MethodChanged(int)));
|
||||
QWidget::connect(_server, SIGNAL(SelectionChanged(const QString &)),
|
||||
this, SLOT(ServerChanged(const QString &)));
|
||||
QWidget::connect(_path, SIGNAL(editingFinished()), this,
|
||||
SLOT(PathChanged()));
|
||||
QWidget::connect(_pathRegex,
|
||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
||||
SLOT(PathRegexChanged(const RegexConfig &)));
|
||||
QWidget::connect(_body, SIGNAL(textChanged()), this,
|
||||
SLOT(BodyChanged()));
|
||||
QWidget::connect(_bodyRegex,
|
||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
||||
SLOT(BodyRegexChanged(const RegexConfig &)));
|
||||
QWidget::connect(_clearBufferOnMatch, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(ClearBufferOnMatchChanged(int)));
|
||||
|
||||
auto topLayout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.http.layout"),
|
||||
topLayout,
|
||||
{{"{{method}}", _method}, {"{{server}}", _server}});
|
||||
|
||||
auto pathLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.http.layout.path"),
|
||||
pathLayout, {{"{{path}}", _path}, {"{{regex}}", _pathRegex}},
|
||||
false);
|
||||
|
||||
auto bodyLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.http.layout.body"),
|
||||
bodyLayout, {{"{{body}}", _body}, {"{{regex}}", _bodyRegex}},
|
||||
false);
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(topLayout);
|
||||
mainLayout->addLayout(pathLayout);
|
||||
mainLayout->addLayout(bodyLayout);
|
||||
mainLayout->addWidget(_clearBufferOnMatch);
|
||||
setLayout(mainLayout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_method->setCurrentIndex(
|
||||
_method->findData(static_cast<int>(_entryData->_method)));
|
||||
_server->SetServer(_entryData->GetServer());
|
||||
_path->setText(_entryData->_path);
|
||||
_pathRegex->SetRegexConfig(_entryData->_pathRegex);
|
||||
_body->setPlainText(_entryData->_body);
|
||||
_bodyRegex->SetRegexConfig(_entryData->_bodyRegex);
|
||||
_clearBufferOnMatch->setChecked(_entryData->_clearBufferOnMatch);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::MethodChanged(int idx)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_method = static_cast<MacroConditionHttp::Method>(
|
||||
_method->itemData(idx).toInt());
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::ServerChanged(const QString &name)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->SetServer(name.toStdString());
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::PathChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_path = _path->text().toStdString();
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::PathRegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pathRegex = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::BodyChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_body = _body->toPlainText().toUtf8().constData();
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::BodyRegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_bodyRegex = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionHttpEdit::ClearBufferOnMatchChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_clearBufferOnMatch = value;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
95
plugins/http/macro-condition-http.hpp
Normal file
95
plugins/http/macro-condition-http.hpp
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "http-server.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
#include "regex-config.hpp"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroConditionHttp : public MacroCondition {
|
||||
public:
|
||||
MacroConditionHttp(Macro *m) : MacroCondition(m, true) {}
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetShortDesc() const;
|
||||
std::string GetId() const { return id; }
|
||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroConditionHttp>(m);
|
||||
}
|
||||
|
||||
enum class Method {
|
||||
ANY = 0,
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
PATCH,
|
||||
DELETE,
|
||||
};
|
||||
|
||||
void SetServer(const std::string &name);
|
||||
std::weak_ptr<HttpServer> GetServer() const { return _server; }
|
||||
|
||||
StringVariable _path = ".*";
|
||||
StringVariable _body = ".*";
|
||||
RegexConfig _pathRegex = RegexConfig::PartialMatchRegexConfig(true);
|
||||
RegexConfig _bodyRegex = RegexConfig::PartialMatchRegexConfig(true);
|
||||
Method _method = Method::ANY;
|
||||
bool _clearBufferOnMatch = true;
|
||||
|
||||
private:
|
||||
void SetupTempVars();
|
||||
|
||||
std::weak_ptr<HttpServer> _server;
|
||||
HttpRequestBuffer _requestBuffer;
|
||||
std::chrono::high_resolution_clock::time_point _lastCheck{};
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroConditionHttpEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MacroConditionHttpEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroConditionHttp> cond = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroCondition> cond)
|
||||
{
|
||||
return new MacroConditionHttpEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroConditionHttp>(cond));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void MethodChanged(int);
|
||||
void ServerChanged(const QString &);
|
||||
void PathChanged();
|
||||
void PathRegexChanged(const RegexConfig &);
|
||||
void BodyChanged();
|
||||
void BodyRegexChanged(const RegexConfig &);
|
||||
void ClearBufferOnMatchChanged(int);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
QComboBox *_method;
|
||||
HttpServerSelection *_server;
|
||||
VariableLineEdit *_path;
|
||||
RegexConfigWidget *_pathRegex;
|
||||
VariableTextEdit *_body;
|
||||
RegexConfigWidget *_bodyRegex;
|
||||
QCheckBox *_clearBufferOnMatch;
|
||||
|
||||
std::shared_ptr<MacroConditionHttp> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
Loading…
Reference in New Issue
Block a user