Converting to split-up controller for readability.
This commit is contained in:
parent
4c9e0c7083
commit
0db5f60b95
8 changed files with 134 additions and 128 deletions
|
@ -298,6 +298,9 @@
|
||||||
// protocol select
|
// protocol select
|
||||||
$pname = $('<select>').attr('id', 'new-protocol-name');
|
$pname = $('<select>').attr('id', 'new-protocol-name');
|
||||||
$pname.append( $('<option>').attr('value', 'HTTP').text('HTTP') );
|
$pname.append( $('<option>').attr('value', 'HTTP').text('HTTP') );
|
||||||
|
$pname.append( $('<option>').attr('value', 'HTTPDynamic').text('HTTPDynamic') );
|
||||||
|
$pname.append( $('<option>').attr('value', 'HTTPProgressive').text('HTTPProgressive') );
|
||||||
|
$pname.append( $('<option>').attr('value', 'HTTPSmooth').text('HTTPSmooth') );
|
||||||
$pname.append( $('<option>').attr('value', 'RTMP').text('RTMP') );
|
$pname.append( $('<option>').attr('value', 'RTMP').text('RTMP') );
|
||||||
|
|
||||||
$nprot.append( $('<td>').append($pname) );
|
$nprot.append( $('<td>').append($pname) );
|
||||||
|
|
|
@ -11,7 +11,7 @@ SUBDIRS=converters analysers
|
||||||
bin_PROGRAMS=MistBuffer MistController MistConnRAW MistConnRTMP MistConnHTTP MistConnHTTPProgressive MistConnHTTPDynamic MistConnHTTPSmooth MistPlayer
|
bin_PROGRAMS=MistBuffer MistController MistConnRAW MistConnRTMP MistConnHTTP MistConnHTTPProgressive MistConnHTTPDynamic MistConnHTTPSmooth MistPlayer
|
||||||
MistBuffer_SOURCES=buffer.cpp buffer_user.h buffer_user.cpp buffer_stream.h buffer_stream.cpp tinythread.cpp tinythread.h ../VERSION
|
MistBuffer_SOURCES=buffer.cpp buffer_user.h buffer_user.cpp buffer_stream.h buffer_stream.cpp tinythread.cpp tinythread.h ../VERSION
|
||||||
MistBuffer_LDADD=$(MIST_LIBS) -lpthread
|
MistBuffer_LDADD=$(MIST_LIBS) -lpthread
|
||||||
MistController_SOURCES=controller.cpp ../VERSION ./server.html.h
|
MistController_SOURCES=controller.cpp controller_connectors.h controller_connectors.cpp controller_storage.h controller_storage.cpp ../VERSION ./server.html.h
|
||||||
MistConnRAW_SOURCES=conn_raw.cpp ../VERSION
|
MistConnRAW_SOURCES=conn_raw.cpp ../VERSION
|
||||||
MistConnRTMP_SOURCES=conn_rtmp.cpp ../VERSION
|
MistConnRTMP_SOURCES=conn_rtmp.cpp ../VERSION
|
||||||
MistConnHTTP_SOURCES=conn_http.cpp tinythread.cpp tinythread.h ../VERSION ./embed.js.h
|
MistConnHTTP_SOURCES=conn_http.cpp tinythread.cpp tinythread.h ../VERSION ./embed.js.h
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <openssl/md5.h>
|
|
||||||
#include <mist/socket.h>
|
#include <mist/socket.h>
|
||||||
#include <mist/http_parser.h>
|
#include <mist/http_parser.h>
|
||||||
#include <mist/config.h>
|
#include <mist/config.h>
|
||||||
#include <mist/procs.h>
|
#include <mist/procs.h>
|
||||||
#include <mist/stream.h>
|
#include <mist/stream.h>
|
||||||
#include <mist/timing.h>
|
#include <mist/timing.h>
|
||||||
|
#include <mist/auth.h>
|
||||||
#include "tinythread.h"
|
#include "tinythread.h"
|
||||||
#include "embed.js.h"
|
#include "embed.js.h"
|
||||||
|
|
||||||
|
@ -188,22 +188,10 @@ namespace Connector_HTTP{
|
||||||
Handle_None(H, conn);//anything else doesn't get handled
|
Handle_None(H, conn);//anything else doesn't get handled
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper function for openssl MD5 implementation
|
|
||||||
std::string md5(std::string input){
|
|
||||||
char tmp[3];
|
|
||||||
std::string ret;
|
|
||||||
const unsigned char * res = MD5((const unsigned char*)input.c_str(), input.length(), 0);
|
|
||||||
for (int i = 0; i < 16; ++i){
|
|
||||||
snprintf(tmp, 3, "%02x", res[i]);
|
|
||||||
ret += tmp;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handles requests without associated handler, displaying a nice friendly error message.
|
/// Handles requests without associated handler, displaying a nice friendly error message.
|
||||||
void Handle_Through_Connector(HTTP::Parser & H, Socket::Connection * conn, std::string & connector){
|
void Handle_Through_Connector(HTTP::Parser & H, Socket::Connection * conn, std::string & connector){
|
||||||
//create a unique ID based on a hash of the user agent and host, followed by the stream name and connector
|
//create a unique ID based on a hash of the user agent and host, followed by the stream name and connector
|
||||||
std::string uid = md5(H.GetHeader("User-Agent")+conn->getHost())+"_"+H.GetVar("stream")+"_"+connector;
|
std::string uid = Secure::md5(H.GetHeader("User-Agent")+conn->getHost())+"_"+H.GetVar("stream")+"_"+connector;
|
||||||
H.SetHeader("X-UID", uid);//add the UID to the headers before copying
|
H.SetHeader("X-UID", uid);//add the UID to the headers before copying
|
||||||
H.SetHeader("X-Origin", conn->getHost());//add the UID to the headers before copying
|
H.SetHeader("X-Origin", conn->getHost());//add the UID to the headers before copying
|
||||||
std::string request = H.BuildRequest();//copy the request for later forwarding to the connector
|
std::string request = H.BuildRequest();//copy the request for later forwarding to the connector
|
||||||
|
@ -417,11 +405,6 @@ int main(int argc, char ** argv){
|
||||||
if (!server_socket.connected()){return 1;}
|
if (!server_socket.connected()){return 1;}
|
||||||
conf.activate();
|
conf.activate();
|
||||||
|
|
||||||
//start progressive and dynamic handlers from the same folder as this application
|
|
||||||
Util::Procs::Start("progressive", Util::getMyPath() + "MistConnHTTPProgressive -n");
|
|
||||||
Util::Procs::Start("dynamic", Util::getMyPath() + "MistConnHTTPDynamic -n");
|
|
||||||
Util::Procs::Start("smooth", Util::getMyPath() + "MistConnHTTPSmooth -n");
|
|
||||||
|
|
||||||
while (server_socket.connected() && conf.is_active){
|
while (server_socket.connected() && conf.is_active){
|
||||||
Socket::Connection S = server_socket.accept();
|
Socket::Connection S = server_socket.accept();
|
||||||
if (S.connected()){//check if the new connection is valid
|
if (S.connected()){//check if the new connection is valid
|
||||||
|
|
|
@ -22,13 +22,14 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <openssl/md5.h>
|
|
||||||
#include <mist/config.h>
|
#include <mist/config.h>
|
||||||
#include <mist/socket.h>
|
#include <mist/socket.h>
|
||||||
#include <mist/http_parser.h>
|
#include <mist/http_parser.h>
|
||||||
#include <mist/procs.h>
|
#include <mist/procs.h>
|
||||||
#include <mist/auth.h>
|
#include <mist/auth.h>
|
||||||
#include <mist/timing.h>
|
#include <mist/timing.h>
|
||||||
|
#include "controller_storage.h"
|
||||||
|
#include "controller_connectors.h"
|
||||||
#include "server.html.h"
|
#include "server.html.h"
|
||||||
|
|
||||||
#define UPLINK_INTERVAL 30
|
#define UPLINK_INTERVAL 30
|
||||||
|
@ -38,22 +39,8 @@
|
||||||
namespace Controller{
|
namespace Controller{
|
||||||
|
|
||||||
std::map<std::string, int> lastBuffer; ///< Last moment of contact with all buffers.
|
std::map<std::string, int> lastBuffer; ///< Last moment of contact with all buffers.
|
||||||
Auth keychecker; ///< Checks key authorization.
|
Secure::Auth keychecker; ///< Checks key authorization.
|
||||||
|
|
||||||
/// Wrapper function for openssl MD5 implementation
|
|
||||||
std::string md5(std::string input){
|
|
||||||
char tmp[3];
|
|
||||||
std::string ret;
|
|
||||||
const unsigned char * res = MD5((const unsigned char*)input.c_str(), input.length(), 0);
|
|
||||||
for (int i = 0; i < 16; ++i){
|
|
||||||
snprintf(tmp, 3, "%02x", res[i]);
|
|
||||||
ret += tmp;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
JSON::Value Storage; ///< Global storage of data.
|
|
||||||
|
|
||||||
void WriteFile( std::string Filename, std::string contents ) {
|
void WriteFile( std::string Filename, std::string contents ) {
|
||||||
std::ofstream File;
|
std::ofstream File;
|
||||||
|
@ -79,32 +66,17 @@ class ConnectedUser{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Log(std::string kind, std::string message){
|
|
||||||
//if last log message equals this one, do not log.
|
|
||||||
if (Storage["log"].size() > 0){
|
|
||||||
JSON::ArrIter it = Storage["log"].ArrEnd() - 1;
|
|
||||||
if ((*it)[2] == message){return;}
|
|
||||||
}
|
|
||||||
JSON::Value m;
|
|
||||||
m.append(Util::epoch());
|
|
||||||
m.append(kind);
|
|
||||||
m.append(message);
|
|
||||||
Storage["log"].append(m);
|
|
||||||
Storage["log"].shrink(100);//limit to 100 log messages
|
|
||||||
std::cout << "[" << kind << "] " << message << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Authorize( JSON::Value & Request, JSON::Value & Response, ConnectedUser & conn ) {
|
void Authorize( JSON::Value & Request, JSON::Value & Response, ConnectedUser & conn ) {
|
||||||
time_t Time = time(0);
|
time_t Time = time(0);
|
||||||
tm * TimeInfo = localtime(&Time);
|
tm * TimeInfo = localtime(&Time);
|
||||||
std::stringstream Date;
|
std::stringstream Date;
|
||||||
std::string retval;
|
std::string retval;
|
||||||
Date << TimeInfo->tm_mday << "-" << TimeInfo->tm_mon << "-" << TimeInfo->tm_year + 1900;
|
Date << TimeInfo->tm_mday << "-" << TimeInfo->tm_mon << "-" << TimeInfo->tm_year + 1900;
|
||||||
std::string Challenge = md5( Date.str().c_str() + conn.C.getHost() );
|
std::string Challenge = Secure::md5( Date.str().c_str() + conn.C.getHost() );
|
||||||
if( Request.isMember( "authorize" ) ) {
|
if( Request.isMember( "authorize" ) ) {
|
||||||
std::string UserID = Request["authorize"]["username"];
|
std::string UserID = Request["authorize"]["username"];
|
||||||
if (Storage["account"].isMember(UserID)){
|
if (Storage["account"].isMember(UserID)){
|
||||||
if (md5(Storage["account"][UserID]["password"].asString() + Challenge) == Request["authorize"]["password"].asString()){
|
if (Secure::md5(Storage["account"][UserID]["password"].asString() + Challenge) == Request["authorize"]["password"].asString()){
|
||||||
Response["authorize"]["status"] = "OK";
|
Response["authorize"]["status"] = "OK";
|
||||||
conn.Username = UserID;
|
conn.Username = UserID;
|
||||||
conn.Authorized = true;
|
conn.Authorized = true;
|
||||||
|
@ -112,7 +84,7 @@ void Authorize( JSON::Value & Request, JSON::Value & Response, ConnectedUser & c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (UserID != ""){
|
if (UserID != ""){
|
||||||
if (Request["authorize"]["password"].asString() != "" && md5(Storage["account"][UserID]["password"].asString()) != Request["authorize"]["password"].asString()){
|
if (Request["authorize"]["password"].asString() != "" && Secure::md5(Storage["account"][UserID]["password"].asString()) != Request["authorize"]["password"].asString()){
|
||||||
Log("AUTH", "Failed login attempt "+UserID+" @ "+conn.C.getHost());
|
Log("AUTH", "Failed login attempt "+UserID+" @ "+conn.C.getHost());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,78 +97,6 @@ void Authorize( JSON::Value & Request, JSON::Value & Response, ConnectedUser & c
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckProtocols(JSON::Value & p){
|
|
||||||
static std::map<std::string, std::string> current_connectors;
|
|
||||||
std::map<std::string, std::string> new_connectors;
|
|
||||||
std::map<std::string, std::string>::iterator iter;
|
|
||||||
|
|
||||||
std::string tmp;
|
|
||||||
JSON::Value counter = (long long int)0;
|
|
||||||
|
|
||||||
//collect object type
|
|
||||||
for (JSON::ObjIter jit = p.ObjBegin(); jit != p.ObjEnd(); jit++){
|
|
||||||
if (!jit->second.isMember("connector") || jit->second["connector"].asString() == ""){continue;}
|
|
||||||
if (!jit->second.isMember("port") || jit->second["port"].asInt() == 0){continue;}
|
|
||||||
tmp = "MistConn";
|
|
||||||
tmp += jit->second["connector"].asString();
|
|
||||||
tmp += " -n -p ";
|
|
||||||
tmp += jit->second["port"].asString();
|
|
||||||
if (jit->second.isMember("interface") && jit->second["interface"].asString() != "" && jit->second["interface"].asString() != "0.0.0.0"){
|
|
||||||
tmp += " -i ";
|
|
||||||
tmp += jit->second["interface"].asString();
|
|
||||||
}
|
|
||||||
if (jit->second.isMember("username") && jit->second["username"].asString() != "" && jit->second["username"].asString() != "root"){
|
|
||||||
tmp += " -u ";
|
|
||||||
tmp += jit->second["username"].asString();
|
|
||||||
}
|
|
||||||
counter = counter.asInt() + 1;
|
|
||||||
new_connectors[std::string("Conn")+counter.asString()] = tmp;
|
|
||||||
}
|
|
||||||
//collect array type
|
|
||||||
for (JSON::ArrIter ait = p.ArrBegin(); ait != p.ArrEnd(); ait++){
|
|
||||||
if (!(*ait).isMember("connector") || (*ait)["connector"].asString() == ""){continue;}
|
|
||||||
if (!(*ait).isMember("port") || (*ait)["port"].asInt() == 0){continue;}
|
|
||||||
tmp = "MistConn";
|
|
||||||
tmp += (*ait)["connector"].asString();
|
|
||||||
tmp += " -n -p ";
|
|
||||||
tmp += (*ait)["port"].asString();
|
|
||||||
if ((*ait).isMember("interface") && (*ait)["interface"].asString() != "" && (*ait)["interface"].asString() != "0.0.0.0"){
|
|
||||||
tmp += " -i ";
|
|
||||||
tmp += (*ait)["interface"].asString();
|
|
||||||
}
|
|
||||||
if ((*ait).isMember("username") && (*ait)["username"].asString() != "" && (*ait)["username"].asString() != "root"){
|
|
||||||
tmp += " -u ";
|
|
||||||
tmp += (*ait)["username"].asString();
|
|
||||||
}
|
|
||||||
counter = counter.asInt() + 1;
|
|
||||||
new_connectors[std::string("Conn")+counter.asString()] = tmp;
|
|
||||||
if (Util::Procs::isActive(std::string("Conn")+counter.asString())){
|
|
||||||
(*ait)["online"] = 1;
|
|
||||||
}else{
|
|
||||||
(*ait)["online"] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//shut down deleted/changed connectors
|
|
||||||
for (iter = current_connectors.begin(); iter != current_connectors.end(); iter++){
|
|
||||||
if (new_connectors.count(iter->first) != 1 || new_connectors[iter->first] != iter->second){
|
|
||||||
Log("CONF", "Stopping connector: " + iter->second);
|
|
||||||
Util::Procs::Stop(iter->first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//start up new/changed connectors
|
|
||||||
for (iter = new_connectors.begin(); iter != new_connectors.end(); iter++){
|
|
||||||
if (current_connectors.count(iter->first) != 1 || current_connectors[iter->first] != iter->second || !Util::Procs::isActive(iter->first)){
|
|
||||||
Log("CONF", "Starting connector: " + iter->second);
|
|
||||||
Util::Procs::Start(iter->first, Util::getMyPath() + iter->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//store new state
|
|
||||||
current_connectors = new_connectors;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckConfig(JSON::Value & in, JSON::Value & out){
|
void CheckConfig(JSON::Value & in, JSON::Value & out){
|
||||||
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
|
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
|
||||||
if (out.isMember(jit->first)){
|
if (out.isMember(jit->first)){
|
||||||
|
@ -477,7 +377,7 @@ int main(int argc, char ** argv){
|
||||||
std::string uname = account.substr(0, colon);
|
std::string uname = account.substr(0, colon);
|
||||||
std::string pword = account.substr(colon + 1, std::string::npos);
|
std::string pword = account.substr(colon + 1, std::string::npos);
|
||||||
Controller::Log("CONF", "Created account "+uname+" through commandline option");
|
Controller::Log("CONF", "Created account "+uname+" through commandline option");
|
||||||
Controller::Storage["account"][uname]["password"] = Controller::md5(pword);
|
Controller::Storage["account"][uname]["password"] = Secure::md5(pword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time_t lastuplink = 0;
|
time_t lastuplink = 0;
|
||||||
|
@ -645,7 +545,7 @@ int main(int argc, char ** argv){
|
||||||
Response["authorize"]["username"] = COMPILED_USERNAME;
|
Response["authorize"]["username"] = COMPILED_USERNAME;
|
||||||
Controller::checkCapable(Response["capabilities"]);
|
Controller::checkCapable(Response["capabilities"]);
|
||||||
Controller::Log("UPLK", "Responding to login challenge: " + Request["authorize"]["challenge"].asString());
|
Controller::Log("UPLK", "Responding to login challenge: " + Request["authorize"]["challenge"].asString());
|
||||||
Response["authorize"]["password"] = Controller::md5(COMPILED_PASSWORD + Request["authorize"]["challenge"].asString());
|
Response["authorize"]["password"] = Secure::md5(COMPILED_PASSWORD + Request["authorize"]["challenge"].asString());
|
||||||
it->H.Clean();
|
it->H.Clean();
|
||||||
it->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
it->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
||||||
it->H.BuildRequest();
|
it->H.BuildRequest();
|
||||||
|
|
79
src/controller_connectors.cpp
Normal file
79
src/controller_connectors.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include <mist/json.h>
|
||||||
|
#include <mist/config.h>
|
||||||
|
#include <mist/procs.h>
|
||||||
|
#include "controller_storage.h"
|
||||||
|
|
||||||
|
namespace Controller{
|
||||||
|
|
||||||
|
void CheckProtocols(JSON::Value & p){
|
||||||
|
static std::map<std::string, std::string> current_connectors;
|
||||||
|
std::map<std::string, std::string> new_connectors;
|
||||||
|
std::map<std::string, std::string>::iterator iter;
|
||||||
|
bool haveHTTPgeneric = false;
|
||||||
|
bool haveHTTPspecific = false;
|
||||||
|
|
||||||
|
std::string tmp;
|
||||||
|
JSON::Value counter = (long long int)0;
|
||||||
|
|
||||||
|
for (JSON::ArrIter ait = p.ArrBegin(); ait != p.ArrEnd(); ait++){
|
||||||
|
if (!(*ait).isMember("connector") || (*ait)["connector"].asString() == ""){continue;}
|
||||||
|
|
||||||
|
tmp = std::string("MistConn") + (*ait)["connector"].asString() + std::string(" -n");
|
||||||
|
if ((*ait)["connector"].asString() == "HTTP"){haveHTTPgeneric = true;}
|
||||||
|
if ((*ait)["connector"].asString() != "HTTP" && (*ait)["connector"].asString().substr(0, 4) == "HTTP"){haveHTTPspecific = true;}
|
||||||
|
|
||||||
|
if ((*ait).isMember("port") && (*ait)["port"].asInt() != 0){
|
||||||
|
tmp += std::string(" -p ") + (*ait)["port"].asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*ait).isMember("interface") && (*ait)["interface"].asString() != "" && (*ait)["interface"].asString() != "0.0.0.0"){
|
||||||
|
tmp += std::string(" -i ") + (*ait)["interface"].asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*ait).isMember("username") && (*ait)["username"].asString() != "" && (*ait)["username"].asString() != "root"){
|
||||||
|
tmp += std::string(" -u ") + (*ait)["username"].asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*ait).isMember("args") && (*ait)["args"].asString() != ""){
|
||||||
|
tmp += std::string(" ") + (*ait)["args"].asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
counter = counter.asInt() + 1;
|
||||||
|
new_connectors[std::string("Conn")+counter.asString()] = tmp;
|
||||||
|
if (Util::Procs::isActive(std::string("Conn")+counter.asString())){
|
||||||
|
(*ait)["online"] = 1;
|
||||||
|
}else{
|
||||||
|
(*ait)["online"] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//shut down deleted/changed connectors
|
||||||
|
for (iter = current_connectors.begin(); iter != current_connectors.end(); iter++){
|
||||||
|
if (new_connectors.count(iter->first) != 1 || new_connectors[iter->first] != iter->second){
|
||||||
|
Log("CONF", "Stopping connector: " + iter->second);
|
||||||
|
Util::Procs::Stop(iter->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//start up new/changed connectors
|
||||||
|
for (iter = new_connectors.begin(); iter != new_connectors.end(); iter++){
|
||||||
|
if (current_connectors.count(iter->first) != 1 || current_connectors[iter->first] != iter->second || !Util::Procs::isActive(iter->first)){
|
||||||
|
Log("CONF", "Starting connector: " + iter->second);
|
||||||
|
Util::Procs::Start(iter->first, Util::getMyPath() + iter->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (haveHTTPgeneric && !haveHTTPspecific){
|
||||||
|
Log("WARN", "HTTP Connector is enabled but no HTTP-based protocols are active!");
|
||||||
|
}
|
||||||
|
if (!haveHTTPgeneric && haveHTTPspecific){
|
||||||
|
Log("WARN", "HTTP-based protocols will not work without the generic HTTP connector!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//store new state
|
||||||
|
current_connectors = new_connectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
5
src/controller_connectors.h
Normal file
5
src/controller_connectors.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
|
namespace Controller{
|
||||||
|
void CheckProtocols(JSON::Value & p);
|
||||||
|
}
|
25
src/controller_storage.cpp
Normal file
25
src/controller_storage.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <mist/timing.h>
|
||||||
|
#include "controller_storage.h"
|
||||||
|
|
||||||
|
namespace Controller{
|
||||||
|
|
||||||
|
JSON::Value Storage; ///< Global storage of data.
|
||||||
|
|
||||||
|
/// Store and print a log message.
|
||||||
|
void Log(std::string kind, std::string message){
|
||||||
|
//if last log message equals this one, do not log.
|
||||||
|
if (Storage["log"].size() > 0){
|
||||||
|
JSON::ArrIter it = Storage["log"].ArrEnd() - 1;
|
||||||
|
if ((*it)[2] == message){return;}
|
||||||
|
}
|
||||||
|
JSON::Value m;
|
||||||
|
m.append(Util::epoch());
|
||||||
|
m.append(kind);
|
||||||
|
m.append(message);
|
||||||
|
Storage["log"].append(m);
|
||||||
|
Storage["log"].shrink(100);//limit to 100 log messages
|
||||||
|
std::cout << "[" << kind << "] " << message << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
src/controller_storage.h
Normal file
11
src/controller_storage.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include <string>
|
||||||
|
#include <mist/json.h>
|
||||||
|
|
||||||
|
namespace Controller{
|
||||||
|
|
||||||
|
extern JSON::Value Storage; ///< Global storage of data.
|
||||||
|
|
||||||
|
/// Store and print a log message.
|
||||||
|
void Log(std::string kind, std::string message);
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue