make the REST server optional and disabled by default

Also fixes an issue where the REST server would sometimes
try to send the reply to the wrong WebServer instance
This commit is contained in:
Michael Zanetti 2018-04-16 17:08:03 +02:00
parent c14e7f54cd
commit b2756c9241
5 changed files with 36 additions and 21 deletions

View File

@ -114,6 +114,7 @@ NymeaConfiguration::NymeaConfiguration(QObject *parent) :
insecureConfig.sslEnabled = false;
insecureConfig.authenticationEnabled = false;
insecureConfig.publicFolder = defaultWebserverPublicFolderPath();
insecureConfig.restServerEnabled = false;
m_webServerConfigs[insecureConfig.id] = insecureConfig;
storeWebServerConfig(insecureConfig);
@ -124,6 +125,7 @@ NymeaConfiguration::NymeaConfiguration(QObject *parent) :
secureConfig.sslEnabled = true;
secureConfig.authenticationEnabled = false;
secureConfig.publicFolder = defaultWebserverPublicFolderPath();
secureConfig.restServerEnabled = false;
m_webServerConfigs[secureConfig.id] = secureConfig;
storeWebServerConfig(secureConfig);
}
@ -269,6 +271,7 @@ void NymeaConfiguration::setWebServerConfiguration(const WebServerConfiguration
settings.beginGroup("WebServer");
settings.beginGroup(config.id);
settings.setValue("publicFolder", config.publicFolder);
settings.setValue("restServerEnabled", config.restServerEnabled);
settings.endGroup();
settings.endGroup();
@ -479,6 +482,7 @@ void NymeaConfiguration::storeWebServerConfig(const WebServerConfiguration &conf
settings.beginGroup("WebServer");
settings.beginGroup(config.id);
settings.setValue("publicFolder", config.publicFolder);
settings.setValue("restServerEnabled", config.restServerEnabled);
settings.endGroup();
settings.endGroup();
}
@ -495,6 +499,7 @@ WebServerConfiguration NymeaConfiguration::readWebServerConfig(const QString &id
config.sslEnabled = settings.value("sslEnabled", true).toBool();
config.authenticationEnabled = settings.value("authenticationEnabled", true).toBool();
config.publicFolder = settings.value("publicFolder").toString();
config.restServerEnabled = settings.value("restServerEnabled", false).toBool();
settings.endGroup();
settings.endGroup();
return config;

View File

@ -53,6 +53,7 @@ class WebServerConfiguration: public ServerConfiguration
{
public:
QString publicFolder;
bool restServerEnabled = false;
};
class NymeaConfiguration : public QObject

View File

@ -46,8 +46,7 @@ namespace nymeaserver {
/*! Constructs a \l{RestServer} with the given \a sslConfiguration and \a parent. */
RestServer::RestServer(const QSslConfiguration &sslConfiguration, QObject *parent) :
QObject(parent),
m_webserver(0)
QObject(parent)
{
Q_UNUSED(sslConfiguration)
@ -61,12 +60,10 @@ RestServer::RestServer(const QSslConfiguration &sslConfiguration, QObject *paren
*/
void RestServer::registerWebserver(WebServer *webServer)
{
m_webserver = webServer;
connect(m_webserver, &WebServer::clientConnected, this, &RestServer::clientConnected);
connect(m_webserver, &WebServer::clientDisconnected, this, &RestServer::clientDisconnected);
connect(m_webserver, &WebServer::httpRequestReady, this, &RestServer::processHttpRequest);
QMetaObject::invokeMethod(m_webserver, "startServer", Qt::QueuedConnection);
connect(webServer, &WebServer::clientConnected, this, &RestServer::clientConnected);
connect(webServer, &WebServer::clientDisconnected, this, &RestServer::clientDisconnected);
connect(webServer, &WebServer::httpRequestReady, this, &RestServer::processHttpRequest);
QMetaObject::invokeMethod(webServer, "startServer", Qt::QueuedConnection);
}
void RestServer::setup()
@ -89,12 +86,13 @@ void RestServer::setup()
void RestServer::clientConnected(const QUuid &clientId)
{
m_clientList.append(clientId);
WebServer *webserver = dynamic_cast<WebServer*>(sender());
m_clientList.insert(clientId, webserver);
}
void RestServer::clientDisconnected(const QUuid &clientId)
{
m_clientList.removeAll(clientId);
m_clientList.take(clientId);
}
void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &request)
@ -102,11 +100,14 @@ void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &re
QStringList urlTokens = request.url().path().split("/");
urlTokens.removeAll(QString());
WebServer *webserver = dynamic_cast<WebServer*>(sender());
Q_ASSERT(webserver);
// check token count
if (urlTokens.count() < 3) {
HttpReply *reply = RestResource::createErrorReply(HttpReply::BadRequest);
reply->setClientId(clientId);
m_webserver->sendHttpReply(reply);
webserver->sendHttpReply(reply);
reply->deleteLater();
return;
}
@ -116,7 +117,7 @@ void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &re
if (!m_resources.contains(resourceName)) {
HttpReply *reply = RestResource::createErrorReply(HttpReply::BadRequest);
reply->setClientId(clientId);
m_webserver->sendHttpReply(reply);
webserver->sendHttpReply(reply);
reply->deleteLater();
return;
}
@ -125,7 +126,7 @@ void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &re
if (request.method() == HttpRequest::Options && urlTokens.count() == 3) {
HttpReply *reply = RestResource::createCorsSuccessReply();
reply->setClientId(clientId);
m_webserver->sendHttpReply(reply);
webserver->sendHttpReply(reply);
reply->deleteLater();
return;
}
@ -141,7 +142,7 @@ void RestServer::processHttpRequest(const QUuid &clientId, const HttpRequest &re
reply->startWait();
return;
}
m_webserver->sendHttpReply(reply);
webserver->sendHttpReply(reply);
reply->deleteLater();
}
@ -171,7 +172,8 @@ void RestServer::asyncReplyFinished()
qCWarning(dcWebServer) << "Client for async reply not longer connected.";
} else {
reply->setClientId(clientId);
m_webserver->sendHttpReply(reply);
WebServer *webserver = m_clientList.value(clientId);
webserver->sendHttpReply(reply);
}
reply->deleteLater();
}

View File

@ -48,8 +48,7 @@ public:
void registerWebserver(WebServer *webServer);
private:
WebServer *m_webserver;
QList<QUuid> m_clientList;
QHash<QUuid, WebServer*> m_clientList;
QHash<QString, RestResource *> m_resources;
QHash<QUuid, HttpReply *> m_asyncReplies;

View File

@ -106,9 +106,8 @@ WebServer::WebServer(const WebServerConfiguration &configuration, const QSslConf
{
if (QCoreApplication::instance()->organizationName() == "nymea-test") {
m_configuration.publicFolder = QCoreApplication::applicationDirPath();
qCWarning(dcWebServer) << "Using public folder" << QDir(m_configuration.publicFolder).canonicalPath();
}
qCDebug(dcWebServer) << "Using public folder" << QDir(m_configuration.publicFolder).canonicalPath();
qCDebug(dcWebServer) << "Starting WebServer. Interface:" << m_configuration.address << "Port:" << m_configuration.port << "SSL:" << m_configuration.sslEnabled << "AUTH:" << m_configuration.authenticationEnabled << "Public folder:" << QDir(m_configuration.publicFolder).canonicalPath();
m_avahiService = new QtAvahiService(this);
connect(m_avahiService, &QtAvahiService::serviceStateChanged, this, &WebServer::onAvahiServiceStateChanged);
@ -351,8 +350,17 @@ void WebServer::readClient()
// Verify API query
if (request.url().path().startsWith("/api/v1")) {
emit httpRequestReady(clientId, request);
return;
if (m_configuration.restServerEnabled) {
emit httpRequestReady(clientId, request);
return;
} else {
qCWarning(dcWebServer()) << "The REST server is disabled. You can enable it by adding \'restServerEnabled=true\' in the WebServer section of the nymead.conf file.";
HttpReply *reply = RestResource::createErrorReply(HttpReply::NotFound);
reply->setClientId(clientId);
sendHttpReply(reply);
reply->deleteLater();
return;
}
}
// Check icon call