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
|
||||
$pname = $('<select>').attr('id', 'new-protocol-name');
|
||||
$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') );
|
||||
|
||||
$nprot.append( $('<td>').append($pname) );
|
||||
|
|
|
@ -11,7 +11,7 @@ SUBDIRS=converters analysers
|
|||
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_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
|
||||
MistConnRTMP_SOURCES=conn_rtmp.cpp ../VERSION
|
||||
MistConnHTTP_SOURCES=conn_http.cpp tinythread.cpp tinythread.h ../VERSION ./embed.js.h
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
#include <sys/wait.h>
|
||||
#include <getopt.h>
|
||||
#include <set>
|
||||
#include <openssl/md5.h>
|
||||
#include <mist/socket.h>
|
||||
#include <mist/http_parser.h>
|
||||
#include <mist/config.h>
|
||||
#include <mist/procs.h>
|
||||
#include <mist/stream.h>
|
||||
#include <mist/timing.h>
|
||||
#include <mist/auth.h>
|
||||
#include "tinythread.h"
|
||||
#include "embed.js.h"
|
||||
|
||||
|
@ -188,22 +188,10 @@ namespace Connector_HTTP{
|
|||
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.
|
||||
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
|
||||
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-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
|
||||
|
@ -417,11 +405,6 @@ int main(int argc, char ** argv){
|
|||
if (!server_socket.connected()){return 1;}
|
||||
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){
|
||||
Socket::Connection S = server_socket.accept();
|
||||
if (S.connected()){//check if the new connection is valid
|
||||
|
|
|
@ -22,13 +22,14 @@
|
|||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sstream>
|
||||
#include <openssl/md5.h>
|
||||
#include <mist/config.h>
|
||||
#include <mist/socket.h>
|
||||
#include <mist/http_parser.h>
|
||||
#include <mist/procs.h>
|
||||
#include <mist/auth.h>
|
||||
#include <mist/timing.h>
|
||||
#include "controller_storage.h"
|
||||
#include "controller_connectors.h"
|
||||
#include "server.html.h"
|
||||
|
||||
#define UPLINK_INTERVAL 30
|
||||
|
@ -38,22 +39,8 @@
|
|||
namespace Controller{
|
||||
|
||||
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 ) {
|
||||
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 ) {
|
||||
time_t Time = time(0);
|
||||
tm * TimeInfo = localtime(&Time);
|
||||
std::stringstream Date;
|
||||
std::string retval;
|
||||
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" ) ) {
|
||||
std::string UserID = Request["authorize"]["username"];
|
||||
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";
|
||||
conn.Username = UserID;
|
||||
conn.Authorized = true;
|
||||
|
@ -112,7 +84,7 @@ void Authorize( JSON::Value & Request, JSON::Value & Response, ConnectedUser & c
|
|||
}
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -125,78 +97,6 @@ void Authorize( JSON::Value & Request, JSON::Value & Response, ConnectedUser & c
|
|||
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){
|
||||
for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
|
||||
if (out.isMember(jit->first)){
|
||||
|
@ -477,7 +377,7 @@ int main(int argc, char ** argv){
|
|||
std::string uname = account.substr(0, colon);
|
||||
std::string pword = account.substr(colon + 1, std::string::npos);
|
||||
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;
|
||||
|
@ -645,7 +545,7 @@ int main(int argc, char ** argv){
|
|||
Response["authorize"]["username"] = COMPILED_USERNAME;
|
||||
Controller::checkCapable(Response["capabilities"]);
|
||||
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.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
||||
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