/** @file @author Stefan Frings */ #include "static.h" #include "yacreader_http_server.h" // #include "dualfilelogger.h" #include "httplistener.h" #include "requestmapper.h" #include "staticfilecontroller.h" #include "yacreader_global.h" #include #include /** Name of this application */ #define APPNAME "YACReaderLibrary" /** Publisher of this application */ #define ORGANISATION "YACReader" /** Short description of this application */ #define DESCRIPTION "Comic reader and organizer" using stefanfrings::HttpListener; using stefanfrings::HttpRequest; using stefanfrings::HttpResponse; using stefanfrings::HttpSessionStore; using stefanfrings::StaticFileController; using stefanfrings::TemplateCache; void YACReaderHttpServer::start(quint16 port) { // Initialize the core application QCoreApplication *app = QCoreApplication::instance(); QString configFileName = YACReader::getSettingsPath() + "/" + QCoreApplication::applicationName() + ".ini"; // Configure template loader and cache auto templateSettings = new QSettings(configFileName, QSettings::IniFormat, app); templateSettings->beginGroup("templates"); if (templateSettings->value("cacheSize").isNull()) templateSettings->setValue("cacheSize", "160000"); QString baseTemplatePath = QString("./server/templates"); QString templatePath; #if defined Q_OS_UNIX && !defined Q_OS_MAC templatePath = QFileInfo(QString(DATADIR) + "/yacreader", baseTemplatePath).absoluteFilePath(); #else templatePath = QFileInfo(QCoreApplication::applicationDirPath(), baseTemplatePath).absoluteFilePath(); #endif if (!templateSettings->contains("path")) templateSettings->setValue("path", templatePath); Static::templateLoader = new TemplateCache(templateSettings, app); // Configure session store auto sessionSettings = new QSettings(configFileName, QSettings::IniFormat, app); sessionSettings->beginGroup("sessions"); if (sessionSettings->value("expirationTime").isNull()) sessionSettings->setValue("expirationTime", 864000000); Static::sessionStore = new HttpSessionStore(sessionSettings, app); Static::yacreaderSessionStore = new YACReaderHttpSessionStore(Static::sessionStore, app); // Configure static file controller auto fileSettings = new QSettings(configFileName, QSettings::IniFormat, app); fileSettings->beginGroup("docroot"); QString basedocroot = "./server/docroot"; QString docroot; #if defined Q_OS_UNIX && !defined Q_OS_MAC QFileInfo configFile(QString(DATADIR) + "/yacreader"); docroot = QFileInfo(QString(DATADIR) + "/yacreader", basedocroot).absoluteFilePath(); #else QFileInfo configFile(QCoreApplication::applicationDirPath()); docroot = QFileInfo(QCoreApplication::applicationDirPath(), basedocroot).absoluteFilePath(); #endif if (!fileSettings->contains("path")) fileSettings->setValue("path", docroot); Static::staticFileController = new StaticFileController(fileSettings, app); // Configure and start the TCP listener qDebug("ServiceHelper: Starting service"); auto listenerSettings = new QSettings(configFileName, QSettings::IniFormat, app); listenerSettings->beginGroup("listener"); if (listenerSettings->value("maxRequestSize").isNull()) listenerSettings->setValue("maxRequestSize", "32000000"); if (listenerSettings->value("maxMultiPartSize").isNull()) listenerSettings->setValue("maxMultiPartSize", "32000000"); if (listenerSettings->value("cleanupInterval").isNull()) listenerSettings->setValue("cleanupInterval", 10000); if (listenerSettings->value("minThreads").isNull()) listenerSettings->setValue("maxThreads", 1000); if (listenerSettings->value("minThreads").isNull()) listenerSettings->setValue("minThreads", 50); if (listenerSettings->value("port").isNull()) listenerSettings->setValue("port", 8080); // start with a temporary port if (port != 0) { // cache saved port if (!listenerSettings->contains("cachedPort")) { listenerSettings->setValue("cachedPort", listenerSettings->value("port").toInt()); } listenerSettings->setValue("port", port); } else { // restore saved port if (listenerSettings->contains("cachedPort")) { listenerSettings->setValue("port", listenerSettings->value("cachedPort")); listenerSettings->remove("cachedPort"); } } // test if port is working { QTcpServer testServer; if (!testServer.listen(QHostAddress::Any, listenerSettings->value("port").toInt())) { qDebug("Port is busy."); // get random port testServer.listen(QHostAddress::Any, 0); listenerSettings->setValue("port", testServer.serverPort()); } testServer.close(); } auto requestMapper = new RequestMapper(app); listener = new HttpListener(listenerSettings, requestMapper, app); connect(requestMapper, &RequestMapper::comicUpdated, this, &YACReaderHttpServer::comicUpdated); connect(requestMapper, &RequestMapper::clientSync, this, &YACReaderHttpServer::clientSync); if (listener->isListening()) { qDebug("ServiceHelper: Service has started"); } else { qDebug("ServiceHelper: Could not launch service"); } } void YACReaderHttpServer::stop() { qDebug("ServiceHelper: Service has been stopped"); // QCoreApplication destroys all objects that have been created in start(). if (listener != nullptr) { listener->close(); delete listener; listener = nullptr; } } YACReaderHttpServer::YACReaderHttpServer() : QObject(nullptr), listener(nullptr) { } QString YACReaderHttpServer::getPort() { return QString("%1").arg(listener->serverPort()); }