Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions App/Server/APICache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,27 @@ struct stuCacheValue {
QVariant Value;
qint32 TTL;

stuCacheValue(){}
stuCacheValue(const QVariant& _value, qint32 _ttl) : InsertionTime(QTime::currentTime()),Value(_value), TTL(_ttl){}
stuCacheValue(const stuCacheValue& _other) : InsertionTime(_other.InsertionTime),Value(_other.Value), TTL(_other.TTL){}
stuCacheValue() { ; }
stuCacheValue(const QVariant& _value, qint32 _ttl) : InsertionTime(QTime::currentTime()),Value(_value), TTL(_ttl) { ; }
stuCacheValue(const stuCacheValue& _other) : InsertionTime(_other.InsertionTime),Value(_other.Value), TTL(_other.TTL) { ; }
};
typedef QHash<QString, stuCacheValue> Cache_t;

class InternalCache
{
public:
static void setValue(const QString& _key, const QVariant& _value, qint32 _ttl){
static void setValue(const QString& _key, const QVariant& _value, qint32 _ttl) {
QMutexLocker Locker(&InternalCache::Lock);
if(InternalCache::Cache.size() < static_cast<qint32>(ServerConfigs::MaxCachedItems.value()))
if (InternalCache::Cache.size() < static_cast<qint32>(ServerConfigs::MaxCachedItems.value()))
InternalCache::Cache.insert(_key, stuCacheValue(_value, _ttl));
}
static QVariant storedValue(const QString& _key){
static QVariant storedValue(const QString& _key) {
QMutexLocker Locker(&InternalCache::Lock);
auto StoredValue = InternalCache::Cache.find(_key);
if(StoredValue == InternalCache::Cache.end())
if (StoredValue == InternalCache::Cache.end())
return QVariant();
Locker.unlock();
if(StoredValue->InsertionTime.secsTo(QTime::currentTime()) > StoredValue->TTL)
if (StoredValue->InsertionTime.secsTo(QTime::currentTime()) > StoredValue->TTL)
return QVariant();
return StoredValue->Value;
}
Expand All @@ -76,13 +76,13 @@ class InternalCache
class CentralCache
{
public:
static bool isValid(){return CentralCache::Connector.isNull() == false;}
static void setup(intfCacheConnector* _connector){ CentralCache::Connector.reset(_connector); }
static void setValue(const QString& _key, const QVariant& _value, qint32 _ttl){
if(CentralCache::Connector.isNull() == false)
static bool isValid() {return CentralCache::Connector.isNull() == false;}
static void setup(intfCacheConnector* _connector) { CentralCache::Connector.reset(_connector); }
static void setValue(const QString& _key, const QVariant& _value, qint32 _ttl) {
if (CentralCache::Connector.isNull() == false)
CentralCache::Connector->setKeyVal(_key, _value, _ttl);
}
static QVariant storedValue(const QString& _key){
static QVariant storedValue(const QString& _key) {
return CentralCache::Connector.isNull() ? QVariant() : CentralCache::Connector->getValue(_key);
}

Expand Down
178 changes: 82 additions & 96 deletions App/Server/OpenAPIGenerator.cpp

Large diffs are not rendered by default.

127 changes: 60 additions & 67 deletions App/Server/RESTAPIRegistry.cpp

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions App/Server/RESTAPIRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ TARGOMAN_ADD_EXCEPTION_HANDLER(exRESTRegistry, Targoman::Common::exTargomanBase)

/*****************************************************/
class OpenAPIGenerator;
class RESTAPIRegistry
{
class RESTAPIRegistry {
public:
static inline QString makeRESTAPIKey(const QString& _httpMethod, const QString& _path) {
return _httpMethod.toUpper() + " " + (_path.endsWith('/') ? _path.mid(0, _path.size() - 1) : _path);
Expand All @@ -55,7 +54,7 @@ class RESTAPIRegistry
}

#ifdef TARGOMAN_API_ENABLE_WEBSOCKET
static inline clsAPIObject* getWSAPIObject(const QString& _path){
static inline clsAPIObject* getWSAPIObject(const QString& _path) {
return RESTAPIRegistry::WSRegistry.value(RESTAPIRegistry::makeRESTAPIKey("WS", _path));
}
#endif
Expand Down
60 changes: 21 additions & 39 deletions App/Server/RESTServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ static WebSocketServer gWSServer;
#endif
static clsUpdateAndPruneThread *gStatUpdateThread;

void RESTServer::start(fnIsInBlackList_t _fnIPInBlackList)
{
void RESTServer::start(fnIsInBlackList_t _fnIPInBlackList) {
if (this->IsStarted)
throw exTargomanInitialization("RESTServer can be run single instance only");

Expand Down Expand Up @@ -82,26 +81,22 @@ void RESTServer::start(fnIsInBlackList_t _fnIPInBlackList)

this->IsStarted = true;

if (ServerConfigs::StatisticsInterval.value())
{
if (ServerConfigs::StatisticsInterval.value()) {
gStatUpdateThread = new clsUpdateAndPruneThread();
connect(gStatUpdateThread, &clsUpdateAndPruneThread::finished, gStatUpdateThread, &QObject::deleteLater);
gStatUpdateThread->start();
}

QObject::connect(&gHTTPServer, &QHttpServer::newConnection, [this](QHttpConnection* _con)
{
QObject::connect(&gHTTPServer, &QHttpServer::newConnection, [this](QHttpConnection* _con) {
if (!this->validateConnection(_con->tcpSocket()->peerAddress(), _con->tcpSocket()->peerPort()))
_con->killConnection();
});

QHostAddress ListenAddress = ServerConfigs::JustLocal.value() ? QHostAddress::LocalHost : QHostAddress::Any;

gHTTPServer.listen(ListenAddress, ServerConfigs::ListenPort.value(), [&, BasePath](QHttpRequest* _req, QHttpResponse* _res)
{
gHTTPServer.listen(ListenAddress, ServerConfigs::ListenPort.value(), [&, BasePath](QHttpRequest* _req, QHttpResponse* _res) {
clsRequestHandler* RequestHandler = new clsRequestHandler(_req, _res);
try
{
try {
QString Path = _req->url().adjusted(QUrl::NormalizePathSegments |
QUrl::RemoveAuthority
).path(QUrl::PrettyDecoded);
Expand Down Expand Up @@ -133,37 +128,31 @@ void RESTServer::start(fnIsInBlackList_t _fnIPInBlackList)
_req->url().query());

//----------------------------------
try
{
try {
auto headers = _req->headers();
QStringList headersLog;
for (auto Iter = headers.begin(); Iter != headers.end(); ++Iter)
headersLog.append(QString(" %1: %2").arg(Iter.key().toStdString().c_str()).arg(Iter.value().toStdString().c_str()));
TargomanLogInfo(7, "headers: " << "\n" << headersLog.join("\n"));
} catch (...) {}
} catch (...) { ; }

//----------------------------------
RequestHandler->process(Path.mid(ServerConfigs::BasePathWithVersion.size() - 1));
}
catch(exTargomanBase& ex)
{
} catch (exTargomanBase& ex) {
RequestHandler->sendError(static_cast<qhttp::TStatusCode>(ex.httpCode()), ex.what(), {}, ex.httpCode() >= 500);
}
});

if (gHTTPServer.isListening())
{
if (gHTTPServer.isListening()) {
TargomanLogInfo(1, "REST Server is listening on "<<ListenAddress.toString()<<":"<<ServerConfigs::ListenPort.value()<<ServerConfigs::BasePathWithVersion);
}
else
{
} else {
TargomanLogError("Unable to start server to listen on "<<ListenAddress.toString()<<":"<<ServerConfigs::ListenPort.value());
QCoreApplication::exit(-1);
}

#ifdef TARGOMAN_API_ENABLE_WEBSOCKET
if(gWSServer.isActive()){
QObject::connect(&gWSServer, &WebSocketServer::sigNewConnection, [this](QWebSocket* _con){
if (gWSServer.isActive()) {
QObject::connect(&gWSServer, &WebSocketServer::sigNewConnection, [this](QWebSocket* _con) {
if (!validateConnection (_con->peerAddress(), _con->peerPort()))
_con->close(QWebSocketProtocol::CloseCodePolicyViolated,"IP banned");
});
Expand All @@ -173,8 +162,7 @@ void RESTServer::start(fnIsInBlackList_t _fnIPInBlackList)
#endif
}

void RESTServer::stop()
{
void RESTServer::stop() {
gHTTPServer.stopListening();
#ifdef TARGOMAN_API_ENABLE_WEBSOCKET
gWSServer.stopListening();
Expand All @@ -185,32 +173,27 @@ void RESTServer::stop()
gStatUpdateThread->quit();
}

TAPI::stuStatistics RESTServer::stats()
{
TAPI::stuStatistics RESTServer::stats() {
return gServerStats;
}

QStringList RESTServer::registeredAPIs(bool _showParams, bool _showTypes, bool _prettifyTypes)
{
QStringList RESTServer::registeredAPIs(bool _showParams, bool _showTypes, bool _prettifyTypes) {
return RESTAPIRegistry::registeredAPIs("", _showParams, _showTypes, _prettifyTypes);
}

void RESTServer::registerUserDefinedType(const char* _typeName, intfAPIArgManipulator* _argManipulator)
{
void RESTServer::registerUserDefinedType(const char* _typeName, intfAPIArgManipulator* _argManipulator) {
// TargomanInfo(9, "registering User Defined Type: (" << _typeName << ")");

Q_ASSERT_X(QMetaType::type(_typeName), QString("registerUserDefinedType typeName(%1)").arg(_typeName).toStdString().c_str(), "Seems that registering syntax is erroneous");

gUserDefinedTypesInfo.insert(QMetaType::type(_typeName) - TAPI_BASE_USER_DEFINED_TYPEID, _argManipulator);
}

bool RESTServer::validateConnection(const QHostAddress& _peerAddress, quint16 _peerPort)
{
bool RESTServer::validateConnection(const QHostAddress& _peerAddress, quint16 _peerPort) {
enuIPBlackListStatus::Type IPBlackListStatus = enuIPBlackListStatus::Unknown;

if (this->fnIPInBlackList &&
(IPBlackListStatus = this->fnIPInBlackList(_peerAddress)) != enuIPBlackListStatus::Ok)
{
(IPBlackListStatus = this->fnIPInBlackList(_peerAddress)) != enuIPBlackListStatus::Ok) {
TargomanLogWarn(1,"Connection from " + _peerAddress.toString() + " was closed by security provider due to: "+enuIPBlackListStatus::toStr(IPBlackListStatus));
gServerStats.Blocked.inc();
return false;
Expand All @@ -223,14 +206,13 @@ bool RESTServer::validateConnection(const QHostAddress& _peerAddress, quint16 _p
}

RESTServer::RESTServer() :
IsStarted(false) {
}
IsStarted(false)
{ ; }

} //namespace Server

/***********************************************************************************************/
void registerUserDefinedType(const char* _typeName, intfAPIArgManipulator* _argManipulator)
{
void registerUserDefinedType(const char* _typeName, intfAPIArgManipulator* _argManipulator) {
Server::RESTServer::instance().registerUserDefinedType(_typeName, _argManipulator);
}

Expand Down
8 changes: 3 additions & 5 deletions App/Server/ServerConfigs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ tmplConfigurable<QString> ServerConfigs::MasterDB::Schema(

/****************************************************************************/
/*static auto langValidator = [](const intfConfigurable& _item, QString& _errorMessage) -> bool{
if(ISO639isValid(_item.toVariant().toString().toLatin1().constData()))
if (ISO639isValid(_item.toVariant().toString().toLatin1().constData()))
return true;
_errorMessage = QString("Invalid language code <%1> on <%2>").arg(
_item.toVariant().toString()).arg(
Expand Down Expand Up @@ -332,8 +332,7 @@ gConfigs::Server::Server(const QString& _basePath) :
"","","",
enuConfigSource::File
),
Statistics(gConfigs::Server::stuStatistics(_basePath))
{}
Statistics(gConfigs::Server::stuStatistics(_basePath)) { ; }

gConfigs::Server::stuStatistics::stuStatistics(const QString& _basePath) :
OkResponses(_basePath + "Stats/OkResponses",
Expand All @@ -349,8 +348,7 @@ gConfigs::Server::stuStatistics::stuStatistics(const QString& _basePath) :
ReturnTrueCrossValidator(),
"","","",
enuConfigSource::ReadOnly
)
{}
) { ; }

tmplConfigurableMultiMap<gConfigs::Server> gConfigs::TranslationServers(
clsConfigPath("TranslationServers"),
Expand Down
2 changes: 1 addition & 1 deletion App/Server/ServerConfigs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ TARGOMAN_ADD_EXCEPTION_HANDLER(exTargomanAPI, Targoman::Common::exTargomanBase);

struct ServerConfigs
{
static inline QString makeConfig(const QString& _name){return "/Server/" + _name;}
static inline QString makeConfig(const QString& _name) {return "/Server/" + _name;}

static Targoman::Common::Configuration::tmplConfigurable<QString> BasePath;
static Targoman::Common::Configuration::tmplConfigurable<QString> Version;
Expand Down
40 changes: 17 additions & 23 deletions App/Server/WebSocketServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ tmplConfigurable<bool> WebSocketServer::Secure(



void WebSocketServer::start()
{
void WebSocketServer::start() {
this->WS.reset(new QWebSocketServer(this->Name.value(),
this->Secure.value()?
QWebSocketServer::SecureMode :
Expand All @@ -91,14 +90,12 @@ void WebSocketServer::start()
}
}

void WebSocketServer::stopListening()
{
void WebSocketServer::stopListening() {
this->WS->close ();
qDeleteAll(this->Clients.begin(), this->Clients.end());
}

void WebSocketServer::onNewConnection()
{
void WebSocketServer::onNewConnection() {

QWebSocket *pSocket = this->WS->nextPendingConnection();

Expand All @@ -111,14 +108,13 @@ void WebSocketServer::onNewConnection()
emit sigNewConnection(pSocket);
}

void WebSocketServer::processTextMessage(QString _message)
{
void WebSocketServer::processTextMessage(QString _message) {

QWebSocket *pSocket = qobject_cast<QWebSocket *>(sender());
TargomanDebug(5, "Text Message Received:" << _message);

if (pSocket) {
auto sendError = [pSocket](qhttp::TStatusCode _code, QString _message){
auto sendError = [pSocket](qhttp::TStatusCode _code, QString _message) {
QJsonObject ErrorInfo = QJsonObject({
{"code", _code},
{"message", _message}
Expand All @@ -130,22 +126,22 @@ void WebSocketServer::processTextMessage(QString _message)
QJsonDocument::Compact).data());
};

try{
try {
QJsonParseError Error;
QJsonDocument JSON = QJsonDocument::fromJson(_message.toUtf8(), &Error);
if(JSON.isNull())
if (JSON.isNull())
throw exHTTPBadRequest(QString("Invalid JSON request: %1").arg(Error.errorString()));

QString ExtraAPIPath;
QJsonObject JSONReqObject = JSON.object();
QString API = JSONReqObject.begin().key();
if(API.isEmpty())
if (API.isEmpty())
return sendError(qhttp::ESTATUS_BAD_REQUEST, "No API path specified");

clsAPIObject* APIObject = RESTAPIRegistry::getWSAPIObject (API);
if (!APIObject) {
QString Path = API;
if(Path.endsWith('/'))
if (Path.endsWith('/'))
Path.truncate(Path.size() - 1);
ExtraAPIPath = Path.mid(Path.lastIndexOf('/'));
Path = Path.mid(0, Path.lastIndexOf('/'));
Expand All @@ -157,10 +153,10 @@ void WebSocketServer::processTextMessage(QString _message)

QVariantMap APIArgs = JSONReqObject.begin().value().toObject().toVariantMap();
QStringList Queries;
for(auto Map = APIArgs.begin(); Map != APIArgs.end(); ++Map)
for (auto Map = APIArgs.begin(); Map != APIArgs.end(); ++Map)
Queries.append(Map.key() + '=' + Map.value().toString());

/*if(ExtraAPIPath)
/*if (ExtraAPIPath)
Queries.append(REQUES)*/


Expand All @@ -170,29 +166,27 @@ void WebSocketServer::processTextMessage(QString _message)
QJsonDocument::Indented :
QJsonDocument::Compact);
pSocket->sendTextMessage(Data.data());
}catch(Targoman::Common::exTargomanBase& ex){
} catch (Targoman::Common::exTargomanBase& ex) {
sendError(static_cast<qhttp::TStatusCode>(ex.code()), ex.what());
}catch(exQFVRequiredParam &ex){
} catch (exQFVRequiredParam &ex) {
sendError(qhttp::ESTATUS_BAD_REQUEST, ex.what());
}catch(exQFVInvalidValue &ex){
} catch (exQFVInvalidValue &ex) {
sendError(qhttp::ESTATUS_BAD_REQUEST, ex.what());
}catch(std::exception &ex){
} catch (std::exception &ex) {
sendError(qhttp::ESTATUS_INTERNAL_SERVER_ERROR, ex.what());
}
}
}

void WebSocketServer::processBinaryMessage(QByteArray _message)
{
void WebSocketServer::processBinaryMessage(QByteArray _message) {
QWebSocket *pSocket = qobject_cast<QWebSocket *>(sender());
TargomanDebug(5, "Binary Message Received:" << _message);
if (pSocket) {
pSocket->sendBinaryMessage(_message);
}
}

void WebSocketServer::socketDisconnected()
{
void WebSocketServer::socketDisconnected() {
QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
if (pClient) {
TargomanLogDebug(5, "Client Disconnected: "<<pClient)
Expand Down
Loading