From dbf41c8a422b90aed2bfe1ec1194f3b452330943 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 28 Jul 2014 14:56:26 -0700 Subject: [PATCH] allow domain-server to serve settings publicly, fix retry in DomainHandler --- domain-server/src/DomainServer.cpp | 8 +++- .../src/DomainServerSettingsManager.cpp | 42 +++++++++++-------- .../src/DomainServerSettingsManager.h | 5 ++- libraries/networking/src/DomainHandler.cpp | 19 +++++---- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index e462e05aa6..2ea66c2ee3 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -940,6 +940,12 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url const QString UUID_REGEX_STRING = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"; + // allow sub-handlers to handle requests that do not require authentication + if (_settingsManager.handlePublicHTTPRequest(connection, url)) { + return true; + } + + // all requests below require a cookie to prove authentication so check that first if (!isAuthenticatedRequest(connection, url)) { // this is not an authenticated request // return true from the handler since it was handled with a 401 or re-direct to auth @@ -1186,7 +1192,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url } // didn't process the request, let our DomainServerSettingsManager or HTTPManager handle - return _settingsManager.handleHTTPRequest(connection, url); + return _settingsManager.handleAuthenticatedHTTPRequest(connection, url); } const QString HIFI_SESSION_COOKIE_KEY = "DS_WEB_SESSION_UUID"; diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 0520426ea8..4ec88996a6 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -47,24 +47,8 @@ DomainServerSettingsManager::DomainServerSettingsManager() : const QString DESCRIPTION_SETTINGS_KEY = "settings"; const QString SETTING_DEFAULT_KEY = "default"; -bool DomainServerSettingsManager::handleHTTPRequest(HTTPConnection* connection, const QUrl &url) { - if (connection->requestOperation() == QNetworkAccessManager::PostOperation && url.path() == "/settings.json") { - // this is a POST operation to change one or more settings - QJsonDocument postedDocument = QJsonDocument::fromJson(connection->requestContent()); - QJsonObject postedObject = postedDocument.object(); - - // we recurse one level deep below each group for the appropriate setting - recurseJSONObjectAndOverwriteSettings(postedObject, _settingsMap, _descriptionObject); - - // store whatever the current _settingsMap is to file - persistToFile(); - - // return success to the caller - QString jsonSuccess = "{\"status\": \"success\"}"; - connection->respond(HTTPConnection::StatusCode200, jsonSuccess.toUtf8(), "application/json"); - - return true; - } else if (connection->requestOperation() == QNetworkAccessManager::GetOperation && url.path() == "/settings.json") { +bool DomainServerSettingsManager::handlePublicHTTPRequest(HTTPConnection* connection, const QUrl &url) { + if (connection->requestOperation() == QNetworkAccessManager::GetOperation && url.path() == "/settings.json") { // this is a GET operation for our settings // check if there is a query parameter for settings affecting a particular type of assignment @@ -135,6 +119,28 @@ bool DomainServerSettingsManager::handleHTTPRequest(HTTPConnection* connection, return false; } +bool DomainServerSettingsManager::handleAuthenticatedHTTPRequest(HTTPConnection *connection, const QUrl &url) { + if (connection->requestOperation() == QNetworkAccessManager::PostOperation && url.path() == "/settings.json") { + // this is a POST operation to change one or more settings + QJsonDocument postedDocument = QJsonDocument::fromJson(connection->requestContent()); + QJsonObject postedObject = postedDocument.object(); + + // we recurse one level deep below each group for the appropriate setting + recurseJSONObjectAndOverwriteSettings(postedObject, _settingsMap, _descriptionObject); + + // store whatever the current _settingsMap is to file + persistToFile(); + + // return success to the caller + QString jsonSuccess = "{\"status\": \"success\"}"; + connection->respond(HTTPConnection::StatusCode200, jsonSuccess.toUtf8(), "application/json"); + + return true; + } + + return false; +} + void DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject, QVariantMap& settingsVariant, QJsonObject descriptionObject) { diff --git a/domain-server/src/DomainServerSettingsManager.h b/domain-server/src/DomainServerSettingsManager.h index 8b80cad280..26bfe57ab4 100644 --- a/domain-server/src/DomainServerSettingsManager.h +++ b/domain-server/src/DomainServerSettingsManager.h @@ -16,11 +16,12 @@ #include -class DomainServerSettingsManager : public QObject, HTTPRequestHandler { +class DomainServerSettingsManager : public QObject { Q_OBJECT public: DomainServerSettingsManager(); - bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url); + bool handlePublicHTTPRequest(HTTPConnection* connection, const QUrl& url); + bool handleAuthenticatedHTTPRequest(HTTPConnection* connection, const QUrl& url); QByteArray getJSONSettingsMap() const; private: diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 286909279b..ce6a264b34 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -11,6 +11,7 @@ #include +#include "Assignment.h" #include "NodeList.h" #include "PacketHeaders.h" #include "UserActivityLogger.h" @@ -133,10 +134,9 @@ void DomainHandler::requestDomainSettings() const { settingsJSONURL.setScheme("http"); settingsJSONURL.setHost(_hostname); settingsJSONURL.setPort(DOMAIN_SERVER_HTTP_PORT); - settingsJSONURL.setPath("/settings.json"); - settingsJSONURL.setQuery(QString("type=%1").arg(NodeList::getInstance()->getOwnerType())); - - qDebug() << settingsJSONURL; + settingsJSONURL.setPath("/settingz.json/"); + Assignment::Type assignmentType = Assignment::typeForNodeType(NodeList::getInstance()->getOwnerType()); + settingsJSONURL.setQuery(QString("type=%1").arg(assignmentType)); QNetworkReply* reply = NetworkAccessManager::getInstance().get(QNetworkRequest(settingsJSONURL)); connect(reply, &QNetworkReply::finished, this, &DomainHandler::settingsRequestFinished); @@ -147,11 +147,12 @@ const int MAX_SETTINGS_REQUEST_FAILED_ATTEMPTS = 5; void DomainHandler::settingsRequestFinished() { QNetworkReply* settingsReply = reinterpret_cast(sender()); - if (settingsReply->error() == QNetworkReply::NoError) { + int replyCode = settingsReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (settingsReply->error() == QNetworkReply::NoError && replyCode != 301 && replyCode != 302) { // parse the JSON to a QJsonObject and save it _settingsObject = QJsonDocument::fromJson(settingsReply->readAll()).object(); - qDebug() << settingsReply->attribute(QNetworkRequest::HttpStatusCodeAttribute); qDebug() << "Received domain settings."; // reset failed settings requests to 0, we got them @@ -165,9 +166,9 @@ void DomainHandler::settingsRequestFinished() { qDebug() << "Failed to retreive domain-server settings" << MAX_SETTINGS_REQUEST_FAILED_ATTEMPTS << "times. Re-setting connection to domain."; clearSettings(); clearConnectionInfo(); - } - - requestDomainSettings(); + } else { + requestDomainSettings(); + } } }