mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
handle programmatic DS requests except for script creation
This commit is contained in:
parent
bce40a9963
commit
40cdba203d
6 changed files with 159 additions and 164 deletions
|
@ -13,6 +13,7 @@
|
|||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#include <HttpConnection.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <UUID.h>
|
||||
|
@ -33,7 +34,7 @@ const quint16 DOMAIN_SERVER_HTTP_PORT = 8080;
|
|||
|
||||
DomainServer::DomainServer(int argc, char* argv[]) :
|
||||
QCoreApplication(argc, argv),
|
||||
_httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath())),
|
||||
_httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
|
||||
_assignmentQueueMutex(),
|
||||
_assignmentQueue(),
|
||||
_staticAssignmentFile(QString("%1/config.ds").arg(QCoreApplication::applicationDirPath())),
|
||||
|
@ -293,142 +294,122 @@ QJsonObject jsonObjectForNode(Node* node) {
|
|||
return nodeJson;
|
||||
}
|
||||
|
||||
//int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
||||
// const struct mg_request_info* ri = mg_get_request_info(connection);
|
||||
//
|
||||
// const char RESPONSE_200[] = "HTTP/1.0 200 OK\r\n\r\n";
|
||||
// const char RESPONSE_400[] = "HTTP/1.0 400 Bad Request\r\n\r\n";
|
||||
//
|
||||
// const char URI_ASSIGNMENT[] = "/assignment";
|
||||
// const char URI_NODE[] = "/node";
|
||||
//
|
||||
// if (strcmp(ri->request_method, "GET") == 0) {
|
||||
// if (strcmp(ri->uri, "/assignments.json") == 0) {
|
||||
// // user is asking for json list of assignments
|
||||
//
|
||||
// // start with a 200 response
|
||||
// mg_printf(connection, "%s", RESPONSE_200);
|
||||
//
|
||||
// // setup the JSON
|
||||
// QJsonObject assignmentJSON;
|
||||
// QJsonObject assignedNodesJSON;
|
||||
//
|
||||
// // enumerate the NodeList to find the assigned nodes
|
||||
// foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||
// if (node->getLinkedData()) {
|
||||
// // add the node using the UUID as the key
|
||||
// QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||
// assignedNodesJSON[uuidString] = jsonObjectForNode(node.data());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// assignmentJSON["fulfilled"] = assignedNodesJSON;
|
||||
//
|
||||
// QJsonObject queuedAssignmentsJSON;
|
||||
//
|
||||
// // add the queued but unfilled assignments to the json
|
||||
// std::deque<Assignment*>::iterator assignment = domainServerInstance->_assignmentQueue.begin();
|
||||
//
|
||||
// while (assignment != domainServerInstance->_assignmentQueue.end()) {
|
||||
// QJsonObject queuedAssignmentJSON;
|
||||
//
|
||||
// QString uuidString = uuidStringWithoutCurlyBraces((*assignment)->getUUID());
|
||||
// queuedAssignmentJSON[JSON_KEY_TYPE] = QString((*assignment)->getTypeName());
|
||||
//
|
||||
// // if the assignment has a pool, add it
|
||||
// if ((*assignment)->hasPool()) {
|
||||
// queuedAssignmentJSON[JSON_KEY_POOL] = QString((*assignment)->getPool());
|
||||
// }
|
||||
//
|
||||
// // add this queued assignment to the JSON
|
||||
// queuedAssignmentsJSON[uuidString] = queuedAssignmentJSON;
|
||||
//
|
||||
// // push forward the iterator to check the next assignment
|
||||
// assignment++;
|
||||
// }
|
||||
//
|
||||
// assignmentJSON["queued"] = queuedAssignmentsJSON;
|
||||
//
|
||||
// // print out the created JSON
|
||||
// QJsonDocument assignmentDocument(assignmentJSON);
|
||||
// mg_printf(connection, "%s", assignmentDocument.toJson().constData());
|
||||
//
|
||||
// // we've processed this request
|
||||
// return 1;
|
||||
// } else if (strcmp(ri->uri, "/nodes.json") == 0) {
|
||||
// // start with a 200 response
|
||||
// mg_printf(connection, "%s", RESPONSE_200);
|
||||
//
|
||||
// // setup the JSON
|
||||
// QJsonObject rootJSON;
|
||||
// QJsonObject nodesJSON;
|
||||
//
|
||||
// // enumerate the NodeList to find the assigned nodes
|
||||
// NodeList* nodeList = NodeList::getInstance();
|
||||
//
|
||||
// foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
// // add the node using the UUID as the key
|
||||
// QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||
// nodesJSON[uuidString] = jsonObjectForNode(node.data());
|
||||
// }
|
||||
//
|
||||
// rootJSON["nodes"] = nodesJSON;
|
||||
//
|
||||
// // print out the created JSON
|
||||
// QJsonDocument nodesDocument(rootJSON);
|
||||
// mg_printf(connection, "%s", nodesDocument.toJson().constData());
|
||||
//
|
||||
// // we've processed this request
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// // not processed, pass to document root
|
||||
// return 0;
|
||||
// } else if (strcmp(ri->request_method, "POST") == 0) {
|
||||
// if (strcmp(ri->uri, URI_ASSIGNMENT) == 0) {
|
||||
// // return a 200
|
||||
// mg_printf(connection, "%s", RESPONSE_200);
|
||||
// // upload the file
|
||||
// mg_upload(connection, "/tmp");
|
||||
//
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// return 0;
|
||||
// } else if (strcmp(ri->request_method, "DELETE") == 0) {
|
||||
// // this is a DELETE request
|
||||
//
|
||||
// // check if it is for an assignment
|
||||
// if (memcmp(ri->uri, URI_NODE, strlen(URI_NODE)) == 0) {
|
||||
// // pull the UUID from the url
|
||||
// QUuid deleteUUID = QUuid(QString(ri->uri + strlen(URI_NODE) + sizeof('/')));
|
||||
//
|
||||
// if (!deleteUUID.isNull()) {
|
||||
// SharedNodePointer nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
|
||||
//
|
||||
// if (nodeToKill) {
|
||||
// // start with a 200 response
|
||||
// mg_printf(connection, "%s", RESPONSE_200);
|
||||
//
|
||||
// // we have a valid UUID and node - kill the node that has this assignment
|
||||
// QMetaObject::invokeMethod(NodeList::getInstance(), "killNodeWithUUID", Q_ARG(const QUuid&, deleteUUID));
|
||||
//
|
||||
// // successfully processed request
|
||||
// return 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // request not processed - bad request
|
||||
// mg_printf(connection, "%s", RESPONSE_400);
|
||||
//
|
||||
// // this was processed by civetweb
|
||||
// return 1;
|
||||
// } else {
|
||||
// // have mongoose process this request from the document_root
|
||||
// return 0;
|
||||
// }
|
||||
//}
|
||||
bool DomainServer::handleHTTPRequest(HttpConnection* connection, const QString& path) {
|
||||
const QString JSON_MIME_TYPE = "application/json";
|
||||
|
||||
const QString URI_ASSIGNMENT = "/assignment";
|
||||
const QString URI_NODE = "/node";
|
||||
|
||||
if (connection->requestOperation() == QNetworkAccessManager::GetOperation) {
|
||||
if (path == "/assignments.json") {
|
||||
// user is asking for json list of assignments
|
||||
|
||||
// setup the JSON
|
||||
QJsonObject assignmentJSON;
|
||||
QJsonObject assignedNodesJSON;
|
||||
|
||||
// enumerate the NodeList to find the assigned nodes
|
||||
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
|
||||
if (node->getLinkedData()) {
|
||||
// add the node using the UUID as the key
|
||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||
assignedNodesJSON[uuidString] = jsonObjectForNode(node.data());
|
||||
}
|
||||
}
|
||||
|
||||
assignmentJSON["fulfilled"] = assignedNodesJSON;
|
||||
|
||||
QJsonObject queuedAssignmentsJSON;
|
||||
|
||||
// add the queued but unfilled assignments to the json
|
||||
std::deque<Assignment*>::iterator assignment = domainServerInstance->_assignmentQueue.begin();
|
||||
|
||||
while (assignment != domainServerInstance->_assignmentQueue.end()) {
|
||||
QJsonObject queuedAssignmentJSON;
|
||||
|
||||
QString uuidString = uuidStringWithoutCurlyBraces((*assignment)->getUUID());
|
||||
queuedAssignmentJSON[JSON_KEY_TYPE] = QString((*assignment)->getTypeName());
|
||||
|
||||
// if the assignment has a pool, add it
|
||||
if ((*assignment)->hasPool()) {
|
||||
queuedAssignmentJSON[JSON_KEY_POOL] = QString((*assignment)->getPool());
|
||||
}
|
||||
|
||||
// add this queued assignment to the JSON
|
||||
queuedAssignmentsJSON[uuidString] = queuedAssignmentJSON;
|
||||
|
||||
// push forward the iterator to check the next assignment
|
||||
assignment++;
|
||||
}
|
||||
|
||||
assignmentJSON["queued"] = queuedAssignmentsJSON;
|
||||
|
||||
// print out the created JSON
|
||||
QJsonDocument assignmentDocument(assignmentJSON);
|
||||
connection->respond(HttpConnection::StatusCode200, assignmentDocument.toJson(), qPrintable(JSON_MIME_TYPE));
|
||||
|
||||
// we've processed this request
|
||||
return true;
|
||||
} else if (path == "/nodes.json") {
|
||||
// setup the JSON
|
||||
QJsonObject rootJSON;
|
||||
QJsonObject nodesJSON;
|
||||
|
||||
// enumerate the NodeList to find the assigned nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||
// add the node using the UUID as the key
|
||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||
nodesJSON[uuidString] = jsonObjectForNode(node.data());
|
||||
}
|
||||
|
||||
rootJSON["nodes"] = nodesJSON;
|
||||
|
||||
// print out the created JSON
|
||||
QJsonDocument nodesDocument(rootJSON);
|
||||
|
||||
// send the response
|
||||
connection->respond(HttpConnection::StatusCode200, nodesDocument.toJson(), qPrintable(JSON_MIME_TYPE));
|
||||
}
|
||||
} else if (connection->requestOperation() == QNetworkAccessManager::PostOperation) {
|
||||
if (path == URI_ASSIGNMENT) {
|
||||
// this is a script upload - ask the HttpConnection to parse the form data
|
||||
QList<FormData> formData = connection->parseFormData();
|
||||
qDebug() << formData;
|
||||
}
|
||||
} else if (connection->requestOperation() == QNetworkAccessManager::DeleteOperation) {
|
||||
if (path.startsWith(URI_NODE)) {
|
||||
// this is a request to DELETE a node by UUID
|
||||
|
||||
// pull the UUID from the url
|
||||
QUuid deleteUUID = QUuid(path.mid(URI_NODE.size() + sizeof('/')));
|
||||
|
||||
if (!deleteUUID.isNull()) {
|
||||
SharedNodePointer nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
|
||||
|
||||
if (nodeToKill) {
|
||||
// start with a 200 response
|
||||
connection->respond(HttpConnection::StatusCode200);
|
||||
|
||||
// we have a valid UUID and node - kill the node that has this assignment
|
||||
QMetaObject::invokeMethod(NodeList::getInstance(), "killNodeWithUUID", Q_ARG(const QUuid&, deleteUUID));
|
||||
|
||||
// successfully processed request
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// bad request, couldn't pull a node ID
|
||||
connection->respond(HttpConnection::StatusCode400);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't process the request, let the HTTPManager try and handle
|
||||
return false;
|
||||
}
|
||||
|
||||
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment";
|
||||
|
||||
|
|
|
@ -21,11 +21,13 @@
|
|||
|
||||
const int MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS = 1000;
|
||||
|
||||
class DomainServer : public QCoreApplication {
|
||||
class DomainServer : public QCoreApplication, public HttpRequestHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DomainServer(int argc, char* argv[]);
|
||||
|
||||
bool handleHTTPRequest(HttpConnection* connection, const QString& path);
|
||||
|
||||
void exit(int retCode = 0);
|
||||
|
||||
static void setDomainServerInstance(DomainServer* domainServer);
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
// Created by Stephen Birarda on 1/16/14.
|
||||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Heavily based on Andrzej Kapolka's original HttpConnection class
|
||||
// found from another one of his projects.
|
||||
// (https://github.com/ey6es/witgap/tree/master/src/cpp/server/http)
|
||||
//
|
||||
|
||||
|
||||
#include <QBuffer>
|
||||
|
@ -18,6 +14,10 @@
|
|||
#include "HttpConnection.h"
|
||||
#include "HttpManager.h"
|
||||
|
||||
const char* HttpConnection::StatusCode200 = "200 OK";
|
||||
const char* HttpConnection::StatusCode400 = "400 Bad Request";
|
||||
const char* HttpConnection::StatusCode404 = "404 Not Found";
|
||||
|
||||
HttpConnection::HttpConnection (QTcpSocket* socket, HttpManager* parentManager) :
|
||||
QObject(parentManager),
|
||||
_parentManager(parentManager),
|
||||
|
@ -178,7 +178,7 @@ void HttpConnection::readHeaders() {
|
|||
|
||||
QByteArray clength = _requestHeaders.value("Content-Length");
|
||||
if (clength.isEmpty()) {
|
||||
_parentManager->handleRequest(this, _requestUrl.path());
|
||||
_parentManager->handleHTTPRequest(this, _requestUrl.path());
|
||||
|
||||
} else {
|
||||
_requestContent.resize(clength.toInt());
|
||||
|
@ -217,5 +217,5 @@ void HttpConnection::readContent() {
|
|||
_socket->read(_requestContent.data(), size);
|
||||
_socket->disconnect(this, SLOT(readContent()));
|
||||
|
||||
_parentManager->handleRequest(this, _requestUrl.path());
|
||||
_parentManager->handleHTTPRequest(this, _requestUrl.path());
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
// Heavily based on Andrzej Kapolka's original HttpConnection class
|
||||
// found from another one of his projects.
|
||||
// (https://github.com/ey6es/witgap/tree/master/src/cpp/server/http)
|
||||
// https://github.com/ey6es/witgap/tree/master/src/cpp/server/http
|
||||
//
|
||||
|
||||
#ifndef __hifi__HttpConnection__
|
||||
|
@ -38,6 +38,9 @@ class HttpConnection : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static const char* StatusCode200;
|
||||
static const char* StatusCode400;
|
||||
static const char* StatusCode404;
|
||||
|
||||
/// WebSocket close status codes.
|
||||
enum ReasonCode { NoReason = 0, NormalClosure = 1000, GoingAway = 1001 };
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
// Created by Stephen Birarda on 1/16/14.
|
||||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
// Heavily based on Andrzej Kapolka's original HttpManager class
|
||||
// found from another one of his projects.
|
||||
// (https://github.com/ey6es/witgap/tree/master/src/cpp/server/http)
|
||||
//
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QFile>
|
||||
|
@ -19,7 +15,15 @@
|
|||
#include "HttpConnection.h"
|
||||
#include "HttpManager.h"
|
||||
|
||||
bool HttpManager::handleRequest(HttpConnection* connection, const QString& path) {
|
||||
bool HttpManager::handleHTTPRequest(HttpConnection* connection, const QString& path) {
|
||||
if (_requestHandler && _requestHandler->handleHTTPRequest(connection, path)) {
|
||||
// this request was handled by our _requestHandler object
|
||||
// so we don't need to attempt to do so in the document root
|
||||
return true;
|
||||
}
|
||||
|
||||
// check to see if there is a file to serve from the document root for this path
|
||||
|
||||
QString subPath = path;
|
||||
|
||||
// remove any slash at the beginning of the path
|
||||
|
@ -45,6 +49,8 @@ bool HttpManager::handleRequest(HttpConnection* connection, const QString& path)
|
|||
|
||||
|
||||
if (!filePath.isEmpty()) {
|
||||
// file exists, serve it
|
||||
|
||||
static QMimeDatabase mimeDatabase;
|
||||
|
||||
QFile localFile(filePath);
|
||||
|
@ -93,18 +99,20 @@ bool HttpManager::handleRequest(HttpConnection* connection, const QString& path)
|
|||
}
|
||||
}
|
||||
|
||||
connection->respond("200 OK", localFileString.toLocal8Bit(), qPrintable(mimeDatabase.mimeTypeForFile(filePath).name()));
|
||||
connection->respond(HttpConnection::StatusCode200, localFileString.toLocal8Bit(), qPrintable(mimeDatabase.mimeTypeForFile(filePath).name()));
|
||||
} else {
|
||||
// respond with a 404
|
||||
connection->respond("404 Not Found", "Resource not found.");
|
||||
connection->respond(HttpConnection::StatusCode404, "Resource not found.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HttpManager::HttpManager(quint16 port, const QString& documentRoot, QObject* parent) :
|
||||
HttpManager::HttpManager(quint16 port, const QString& documentRoot, HttpRequestHandler* requestHandler, QObject* parent) :
|
||||
QTcpServer(parent),
|
||||
_documentRoot(documentRoot) {
|
||||
_documentRoot(documentRoot),
|
||||
_requestHandler(requestHandler)
|
||||
{
|
||||
// start listening on the passed port
|
||||
if (!listen(QHostAddress("0.0.0.0"), port)) {
|
||||
qDebug() << "Failed to open HTTP server socket:" << errorString();
|
||||
|
|
|
@ -7,36 +7,37 @@
|
|||
//
|
||||
// Heavily based on Andrzej Kapolka's original HttpManager class
|
||||
// found from another one of his projects.
|
||||
// (https://github.com/ey6es/witgap/tree/master/src/cpp/server/http)
|
||||
// https://github.com/ey6es/witgap/tree/master/src/cpp/server/http
|
||||
//
|
||||
|
||||
#ifndef __hifi__HttpManager__
|
||||
#define __hifi__HttpManager__
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <QtNetwork/QTcpServer>
|
||||
|
||||
class HttpConnection;
|
||||
class HttpRequestHandler;
|
||||
|
||||
class HttpRequestHandler {
|
||||
public:
|
||||
/// Handles an HTTP request.
|
||||
virtual bool handleHTTPRequest(HttpConnection* connection, const QString& path) = 0;
|
||||
};
|
||||
|
||||
/// Handles HTTP connections
|
||||
class HttpManager : public QTcpServer {
|
||||
class HttpManager : public QTcpServer, public HttpRequestHandler {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/// Initializes the manager.
|
||||
HttpManager(quint16 port, const QString& documentRoot, QObject* parent = 0);
|
||||
HttpManager(quint16 port, const QString& documentRoot, HttpRequestHandler* requestHandler = NULL, QObject* parent = 0);
|
||||
|
||||
/// Handles an HTTP request.
|
||||
virtual bool handleRequest (HttpConnection* connection, const QString& path);
|
||||
bool handleHTTPRequest(HttpConnection* connection, const QString& path);
|
||||
|
||||
protected slots:
|
||||
/// Accepts all pending connections
|
||||
void acceptConnections();
|
||||
protected:
|
||||
QString _documentRoot;
|
||||
HttpRequestHandler* _requestHandler;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__HttpManager__) */
|
||||
|
|
Loading…
Reference in a new issue