Some checks failed
Build and push docker image / build (push) Failing after 1m40s
216 lines
7.5 KiB
C++
216 lines
7.5 KiB
C++
#include <QCoreApplication>
|
|
#include <QCommandLineParser>
|
|
|
|
#include "webserver.h"
|
|
#ifdef FEATURE_REDIS
|
|
#include <hiredis/async.h>
|
|
#include "redisqtadapter.h"
|
|
#endif
|
|
|
|
#include <QTcpServer>
|
|
#include <QDebug>
|
|
#include <QUuid>
|
|
|
|
static QHostAddress parseHostAddress(const QString &str);
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
qSetMessagePattern("%{time dd.MM.yyyy HH:mm:ss.zzz} "
|
|
"["
|
|
"%{if-debug}D%{endif}"
|
|
"%{if-info}I%{endif}"
|
|
"%{if-warning}W%{endif}"
|
|
"%{if-critical}C%{endif}"
|
|
"%{if-fatal}F%{endif}"
|
|
"] "
|
|
"%{function}(): "
|
|
"%{message}");
|
|
|
|
QCoreApplication app{argc, argv};
|
|
QCoreApplication::setApplicationName("less_shitty_proxyjs");
|
|
QCoreApplication::setApplicationVersion("1.0");
|
|
|
|
QHostAddress listenAddress = QHostAddress::Any;
|
|
if (auto str = qgetenv("PROXYJS_LISTEN_ADDR"); !str.isEmpty())
|
|
listenAddress = parseHostAddress(str);
|
|
|
|
uint16_t port = 8080;
|
|
if (auto str = qgetenv("PROXYJS_PORT"); !str.isEmpty())
|
|
port = str.toInt();
|
|
|
|
QString identity = "proxyjs_" + QUuid::createUuid().toString(QUuid::WithoutBraces);
|
|
if (auto str = qgetenv("PROXYJS_IDENTITY"); !str.isEmpty())
|
|
identity = str;
|
|
|
|
#ifdef FEATURE_REDIS
|
|
QString redisHost = "localhost";
|
|
if (auto str = qgetenv("PROXYJS_REDIS_HOST"); !str.isEmpty())
|
|
redisHost = str;
|
|
QString redisPassword;
|
|
if (auto str = qgetenv("PROXYJS_REDIS_PASSWORD"); !str.isEmpty())
|
|
redisPassword = str;
|
|
QString endpointAddr;
|
|
if (auto str = qgetenv("PROXYJS_ENDPOINT_ADDR"); !str.isEmpty())
|
|
endpointAddr = str;
|
|
#endif
|
|
|
|
{
|
|
QCommandLineParser parser;
|
|
parser.setApplicationDescription("Test helper");
|
|
parser.addHelpOption();
|
|
parser.addVersionOption();
|
|
|
|
QCommandLineOption listenAddrOption{QStringList{ "l", "listenAddress" },
|
|
QCoreApplication::translate("main", "The address to listen on (Can be \"Any\" \"Localhost\" or any valid ip address)."),
|
|
QCoreApplication::translate("main", "listenAddress")};
|
|
parser.addOption(listenAddrOption);
|
|
|
|
QCommandLineOption portOption{QStringList{ "p", "port" },
|
|
QCoreApplication::translate("main", "The port to listen on (will only listen on localhost)."),
|
|
QCoreApplication::translate("main", "port")};
|
|
parser.addOption(portOption);
|
|
|
|
QCommandLineOption identityOption{QStringList{ "i", "identity" },
|
|
QCoreApplication::translate("main", "The name of this service instance"),
|
|
QCoreApplication::translate("main", "identity")};
|
|
parser.addOption(identityOption);
|
|
|
|
#ifdef FEATURE_REDIS
|
|
QCommandLineOption redisHostOption{QStringList{ "H", "redisHost" },
|
|
QCoreApplication::translate("main", "The redis host"),
|
|
QCoreApplication::translate("main", "redisHost")};
|
|
parser.addOption(redisHostOption);
|
|
|
|
QCommandLineOption redisPasswordOption{QStringList{ "r", "redisPassword" },
|
|
QCoreApplication::translate("main", "The redis password"),
|
|
QCoreApplication::translate("main", "redisPassword")};
|
|
parser.addOption(redisPasswordOption);
|
|
|
|
QCommandLineOption endpointAddrOption{QStringList{ "e", "endpointAddr" },
|
|
QCoreApplication::translate("main", "Endpoint address for traefik"),
|
|
QCoreApplication::translate("main", "endpointAddr")};
|
|
parser.addOption(endpointAddrOption);
|
|
#endif
|
|
|
|
parser.process(app);
|
|
|
|
if (parser.isSet(listenAddrOption))
|
|
{
|
|
listenAddress = parseHostAddress(parser.value(listenAddrOption));
|
|
}
|
|
if (parser.isSet(portOption))
|
|
{
|
|
const auto &str = parser.value(portOption);
|
|
bool ok;
|
|
port = str.toInt(&ok);
|
|
if (!ok)
|
|
{
|
|
qCritical("could not parse port: %s", qPrintable(str));
|
|
return -1;
|
|
}
|
|
}
|
|
if (parser.isSet(identityOption))
|
|
identity = parser.value(identityOption);
|
|
#ifdef FEATURE_REDIS
|
|
if (parser.isSet(redisHostOption))
|
|
redisHost = parser.value(redisHostOption);
|
|
if (parser.isSet(redisPasswordOption))
|
|
redisPassword = parser.value(redisPasswordOption);
|
|
if (parser.isSet(endpointAddrOption))
|
|
endpointAddr = parser.value(endpointAddrOption);
|
|
#endif
|
|
}
|
|
|
|
#ifdef FEATURE_REDIS
|
|
if (endpointAddr.isEmpty())
|
|
endpointAddr = QString{"http://localhost:%0"}.arg(port);
|
|
#endif
|
|
|
|
qSetMessagePattern(QString{"%{time dd.MM.yyyy HH:mm:ss.zzz} %0 "
|
|
"["
|
|
"%{if-debug}D%{endif}"
|
|
"%{if-info}I%{endif}"
|
|
"%{if-warning}W%{endif}"
|
|
"%{if-critical}C%{endif}"
|
|
"%{if-fatal}F%{endif}"
|
|
"] "
|
|
"%{function}(): "
|
|
"%{message}"}.arg(identity));
|
|
|
|
#ifdef FEATURE_REDIS
|
|
redisAsyncContext * const redis = redisAsyncConnect(redisHost.toUtf8().constData(), 6379);
|
|
|
|
if (redis->err)
|
|
qFatal("error with redis connection: %s", redis->errstr);
|
|
|
|
RedisQtAdapter redisAdapter;
|
|
redisAdapter.setContext(redis);
|
|
|
|
if (!redisPassword.isEmpty())
|
|
{
|
|
qDebug() << "redis AUTH" << redisPassword;
|
|
|
|
redisAsyncCommand(redis, NULL, NULL, "AUTH %s",
|
|
redisPassword.toUtf8().constData());
|
|
}
|
|
|
|
qDebug() << "redis connected";
|
|
#endif
|
|
|
|
WebServer server{identity
|
|
#ifdef FEATURE_REDIS
|
|
, redis
|
|
#endif
|
|
};
|
|
|
|
QTcpServer tcpServer;
|
|
if (!tcpServer.listen(listenAddress, port))
|
|
{
|
|
qCritical("failed to start listening on addr %s port %hu: %s", qPrintable(listenAddress.toString()), port, qPrintable(tcpServer.errorString()));
|
|
return -1;
|
|
}
|
|
|
|
if (!server.bind(&tcpServer))
|
|
{
|
|
qCritical("failed to webserver on socket!");
|
|
return -2;
|
|
}
|
|
|
|
#ifdef FEATURE_REDIS
|
|
redisAsyncCommand(redis, NULL, NULL, "SET %s %s",
|
|
QString{"traefik/http/services/%0/loadbalancer/servers/0/url"}
|
|
.arg(identity).toUtf8().constData(),
|
|
endpointAddr.toUtf8().constData()
|
|
);
|
|
#endif
|
|
|
|
qDebug() << "server started on" << listenAddress << "port" << port;
|
|
|
|
auto result = app.exec();
|
|
|
|
#ifdef FEATURE_REDIS
|
|
redisAsyncCommand(redis, NULL, NULL, "DEL %s",
|
|
QString{"traefik/http/services/%0/loadbalancer/servers/0/url"}
|
|
.arg(identity).toUtf8().constData());
|
|
#endif
|
|
|
|
qDebug() << "bey bey!";
|
|
return result;
|
|
}
|
|
|
|
static QHostAddress parseHostAddress(const QString &str)
|
|
{
|
|
if (str == "Any")
|
|
return QHostAddress::Any;
|
|
else if (str == "AnyIPv4")
|
|
return QHostAddress::AnyIPv4;
|
|
else if (str == "AnyIPv6")
|
|
return QHostAddress::AnyIPv6;
|
|
else if (str == "LocalHost")
|
|
return QHostAddress::LocalHost;
|
|
else if (str == "LocalHostIPv6")
|
|
return QHostAddress::LocalHostIPv6;
|
|
else
|
|
return QHostAddress{str};
|
|
}
|