handle query params in HTTPManager, display stats table from DS

This commit is contained in:
Stephen Birarda 2014-03-24 14:14:26 -07:00
parent 1fffda674a
commit f8279c1f5b
11 changed files with 71 additions and 24 deletions

View file

@ -358,11 +358,17 @@ void AudioMixer::readPendingDatagrams() {
void AudioMixer::sendStatsPacket() {
static QJsonObject statsObject;
statsObject["trailing_sleep_time"] = _trailingSleepRatio;
statsObject["performance_cutoff"] = _minAudibilityThreshold;
statsObject["trailing_sleep_percentage"] = _trailingSleepRatio * 100.0f;
statsObject["performance_throttling"] = _performanceThrottling;
statsObject["average_listeners_per_frame"] = _sumListeners / (float) _numStatFrames;
statsObject["average_mixes_per_listeners"] = _sumMixes / _sumListeners / _numStatFrames;
if (_sumListeners > 0) {
statsObject["average_mixes_per_listener"] = _sumMixes / (float) _sumListeners;
} else {
statsObject["average_mixes_per_listener"] = 0.0;
}
_sumListeners = 0;
_sumMixes = 0;

View file

@ -1,3 +1,3 @@
</div>
<script src='js/jquery-2.0.3.min.js'></script>
<script src="js/bootstrap.min.js"></script>
<script src='/js/jquery-2.0.3.min.js'></script>
<script src='/js/bootstrap.min.js'></script>

View file

@ -4,8 +4,8 @@
<title>domain-server</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="css/style.css" rel="stylesheet" media="screen">
<link href="/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="/css/style.css" rel="stylesheet" media="screen">
</head>
<body>
<div class="container">

View file

@ -7,7 +7,7 @@ $(document).ready(function(){
$.each(json.nodes, function (uuid, data) {
nodesTableBody += "<tr>";
nodesTableBody += "<td>" + data.type + "</td>";
nodesTableBody += "<td><a href='nodes/" + uuid + "'>" + uuid + "</a></td>";
nodesTableBody += "<td><a href='stats/?uuid=" + uuid + "'>" + uuid + "</a></td>";
nodesTableBody += "<td>" + (data.pool ? data.pool : "") + "</td>";
nodesTableBody += "<td>" + data.public.ip + "<span class='port'>:" + data.public.port + "</span></td>";
nodesTableBody += "<td>" + data.local.ip + "<span class='port'>:" + data.local.port + "</span></td>";

View file

@ -0,0 +1,6 @@
<!--#include virtual="header.html"-->
<div id="stats-lead" class="table-lead"><h3>Stats</h3><div class="lead-line"></div></div>
<table id="stats-table" class="table"><tbody></tbody></table>
<!--#include virtual="footer.html"-->
<script src='js/stats.js'></script>
<!--#include virtual="page-end.html"-->

View file

@ -0,0 +1,31 @@
function qs(key) {
key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}
$(document).ready(function(){
// setup a function to grab the nodeStats
function getNodeStats() {
var uuid = qs("uuid");
var statsTableBody = "";
$.getJSON("/nodes/" + uuid + ".json", function(json){
$.each(json, function (key, value) {
statsTableBody += "<tr>";
statsTableBody += "<td>" + key + "</td>";
statsTableBody += "<td>" + value + "</td>";
statsTableBody += "</tr>";
});
$('#stats-table tbody').html(statsTableBody);
});
}
// do the first GET on page load
getNodeStats();
// grab the new assignments JSON every second
var getNodeStatsInterval = setInterval(getNodeStats, 1000);
});

View file

@ -651,14 +651,14 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
return nodeJson;
}
bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString& path) {
bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url) {
const QString JSON_MIME_TYPE = "application/json";
const QString URI_ASSIGNMENT = "/assignment";
const QString URI_NODES = "/nodes";
if (connection->requestOperation() == QNetworkAccessManager::GetOperation) {
if (path == "/assignments.json") {
if (url.path() == "/assignments.json") {
// user is asking for json list of assignments
// setup the JSON
@ -702,7 +702,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
// we've processed this request
return true;
} else if (path == QString("%1.json").arg(URI_NODES)) {
} else if (url.path() == QString("%1.json").arg(URI_NODES)) {
// setup the JSON
QJsonObject rootJSON;
QJsonObject nodesJSON;
@ -727,10 +727,10 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
return true;
} else {
const QString NODE_REGEX_STRING =
QString("\\%1\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\/?$").arg(URI_NODES);
QString("\\%1\\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}).json\\/?$").arg(URI_NODES);
QRegExp nodeShowRegex(NODE_REGEX_STRING);
if (nodeShowRegex.indexIn(path) != -1) {
if (nodeShowRegex.indexIn(url.path()) != -1) {
QUuid matchingUUID = QUuid(nodeShowRegex.cap(1));
// see if we have a node that matches this ID
@ -740,7 +740,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
QJsonDocument statsDocument(reinterpret_cast<DomainServerNodeData*>(matchingNode->getLinkedData())
->getStatsJSONObject());
// send the resposne
// send the response
connection->respond(HTTPConnection::StatusCode200, statsDocument.toJson(), qPrintable(JSON_MIME_TYPE));
// tell the caller we processed the request
@ -749,7 +749,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
}
}
} else if (connection->requestOperation() == QNetworkAccessManager::PostOperation) {
if (path == URI_ASSIGNMENT) {
if (url.path() == URI_ASSIGNMENT) {
// this is a script upload - ask the HTTPConnection to parse the form data
QList<FormData> formData = connection->parseFormData();
@ -796,11 +796,11 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QString&
return true;
}
} else if (connection->requestOperation() == QNetworkAccessManager::DeleteOperation) {
if (path.startsWith(URI_NODES)) {
if (url.path().startsWith(URI_NODES)) {
// this is a request to DELETE a node by UUID
// pull the UUID from the url
QUuid deleteUUID = QUuid(path.mid(URI_NODES.size() + sizeof('/')));
QUuid deleteUUID = QUuid(url.path().mid(URI_NODES.size() + sizeof('/')));
if (!deleteUUID.isNull()) {
SharedNodePointer nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);

View file

@ -30,7 +30,7 @@ public:
bool requiresAuthentication() const { return !_nodeAuthenticationURL.isEmpty(); }
bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url);
void exit(int retCode = 0);

View file

@ -180,7 +180,7 @@ void HTTPConnection::readHeaders() {
QByteArray clength = _requestHeaders.value("Content-Length");
if (clength.isEmpty()) {
_parentManager->handleHTTPRequest(this, _requestUrl.path());
_parentManager->handleHTTPRequest(this, _requestUrl);
} else {
_requestContent.resize(clength.toInt());

View file

@ -15,15 +15,15 @@
#include "HTTPConnection.h"
#include "HTTPManager.h"
bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QString& path) {
if (_requestHandler && _requestHandler->handleHTTPRequest(connection, path)) {
bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QUrl& url) {
if (_requestHandler && _requestHandler->handleHTTPRequest(connection, url)) {
// 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;
QString subPath = url.path();
// remove any slash at the beginning of the path
if (subPath.startsWith('/')) {
@ -38,6 +38,10 @@ bool HTTPManager::handleHTTPRequest(HTTPConnection* connection, const QString& p
// this could be a directory with a trailing slash
// send a redirect to the path with a slash so we can
QString redirectLocation = '/' + subPath + '/';
if (!url.query().isEmpty()) {
redirectLocation += "?" + url.query();
}
QHash<QByteArray, QByteArray> redirectHeader;
redirectHeader.insert(QByteArray("Location"), redirectLocation.toUtf8());

View file

@ -20,7 +20,7 @@ class HTTPConnection;
class HTTPRequestHandler {
public:
/// Handles an HTTP request.
virtual bool handleHTTPRequest(HTTPConnection* connection, const QString& path) = 0;
virtual bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url) = 0;
};
/// Handles HTTP connections
@ -30,7 +30,7 @@ public:
/// Initializes the manager.
HTTPManager(quint16 port, const QString& documentRoot, HTTPRequestHandler* requestHandler = NULL, QObject* parent = 0);
bool handleHTTPRequest(HTTPConnection* connection, const QString& path);
bool handleHTTPRequest(HTTPConnection* connection, const QUrl& url);
protected slots:
/// Accepts all pending connections