Several stability improvements and optimizations for HTTP handling and parsing (also, should fix HTTP Progressive under Windows - again).
This commit is contained in:
parent
682ecd2a0e
commit
a08f8e3033
4 changed files with 203 additions and 250 deletions
|
@ -32,6 +32,7 @@ namespace Connector_HTTP{
|
|||
|
||||
/// Returns AMF-format metadata for Adobe HTTP Dynamic Streaming.
|
||||
std::string GetMetaData( ) {
|
||||
/// \todo Make this actually do what it should - even though it seems to be ignored completely by all media players.
|
||||
AMF::Object amfreply("container", AMF::AMF0_DDV_CONTAINER);
|
||||
amfreply.addContent(AMF::Object("onMetaData",AMF::AMF0_STRING));
|
||||
amfreply.addContent(AMF::Object("",AMF::AMF0_ECMA_ARRAY));
|
||||
|
@ -95,31 +96,32 @@ namespace Connector_HTTP{
|
|||
void Progressive(FLV::Tag & tag, HTTP::Parser HTTP_S, Socket::Connection & conn, DTSC::Stream & Strm){
|
||||
static bool progressive_has_sent_header = false;
|
||||
if (!progressive_has_sent_header){
|
||||
HTTP_S.Clean();//troep opruimen die misschien aanwezig is...
|
||||
HTTP_S.SetHeader("Content-Type", "video/x-flv");//FLV files hebben altijd dit content-type.
|
||||
HTTP_S.Clean();//make sure no parts of old requests are left in any buffers
|
||||
HTTP_S.SetHeader("Content-Type", "video/x-flv");//Send the correct content-type for FLV files
|
||||
//HTTP_S.SetHeader("Transfer-Encoding", "chunked");
|
||||
HTTP_S.protocol = "HTTP/1.0";
|
||||
HTTP_S.SendResponse(conn, "200", "OK");//geen SetBody = unknown length! Dat willen we hier.
|
||||
//HTTP_S.SendBodyPart(CONN_fd, FLVHeader, 13);//schrijf de FLV header
|
||||
conn.write(FLV::Header, 13);
|
||||
conn.Send(HTTP_S.BuildResponse("200", "OK"));//no SetBody = unknown length - this is intentional, we will stream the entire file
|
||||
conn.Send(std::string(FLV::Header, 13));//write FLV header
|
||||
static FLV::Tag tmp;
|
||||
//write metadata
|
||||
tmp.DTSCMetaInit(Strm);
|
||||
conn.write(tmp.data, tmp.len);
|
||||
conn.Send(std::string(tmp.data, tmp.len));
|
||||
//write video init data, if needed
|
||||
if (Strm.metadata.getContentP("video") && Strm.metadata.getContentP("video")->getContentP("init")){
|
||||
tmp.DTSCVideoInit(Strm);
|
||||
conn.write(tmp.data, tmp.len);
|
||||
conn.Send(std::string(tmp.data, tmp.len));
|
||||
}
|
||||
//write audio init data, if needed
|
||||
if (Strm.metadata.getContentP("audio") && Strm.metadata.getContentP("audio")->getContentP("init")){
|
||||
tmp.DTSCAudioInit(Strm);
|
||||
conn.write(tmp.data, tmp.len);
|
||||
conn.Send(std::string(tmp.data, tmp.len));
|
||||
}
|
||||
progressive_has_sent_header = true;
|
||||
#if DEBUG >= 1
|
||||
fprintf(stderr, "Sent progressive FLV header\n");
|
||||
#endif
|
||||
}
|
||||
//HTTP_S.SendBodyPart(CONN_fd, tag->data, tag->len);//schrijf deze FLV tag onbewerkt weg
|
||||
conn.write(tag.data, tag.len);
|
||||
conn.Send(std::string(tag.data, tag.len));//write the tag contents
|
||||
}
|
||||
|
||||
/// Handles Flash Dynamic HTTP streaming requests
|
||||
|
@ -129,6 +131,9 @@ namespace Connector_HTTP{
|
|||
if (Strm.getPacket(0).getContentP("keyframe")){
|
||||
if (FlashBuf != ""){
|
||||
Flash_FragBuffer.push(FlashBuf);
|
||||
while (Flash_FragBuffer.size() > 2){
|
||||
Flash_FragBuffer.pop();
|
||||
}
|
||||
#if DEBUG >= 4
|
||||
fprintf(stderr, "Received a fragment. Now %i in buffer.\n", (int)Flash_FragBuffer.size());
|
||||
#endif
|
||||
|
@ -165,96 +170,102 @@ namespace Connector_HTTP{
|
|||
int temp;
|
||||
int Flash_RequestPending = 0;
|
||||
unsigned int lastStats = 0;
|
||||
//int CurrentFragment = -1; later herbruiken?
|
||||
conn.setBlocking(false);//do not block on conn.spool() when no data is available
|
||||
|
||||
while (conn.connected()){
|
||||
//only parse input if available or not yet init'ed
|
||||
if (HTTP_R.Read(conn, ready4data)){
|
||||
handler = HANDLER_PROGRESSIVE;
|
||||
#if DEBUG >= 4
|
||||
std::cout << "Received request: " << HTTP_R.url << std::endl;
|
||||
#endif
|
||||
if ((HTTP_R.url.find("Seg") != std::string::npos) && (HTTP_R.url.find("Frag") != std::string::npos)){handler = HANDLER_FLASH;}
|
||||
if (HTTP_R.url.find("f4m") != std::string::npos){handler = HANDLER_FLASH;}
|
||||
if (HTTP_R.url == "/crossdomain.xml"){
|
||||
handler = HANDLER_NONE;
|
||||
HTTP_S.Clean();
|
||||
HTTP_S.SetHeader("Content-Type", "text/xml");
|
||||
HTTP_S.SetBody("<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" /><site-control permitted-cross-domain-policies=\"all\"/></cross-domain-policy>");
|
||||
HTTP_S.SendResponse(conn, "200", "OK");
|
||||
#if DEBUG >= 3
|
||||
printf("Sending crossdomain.xml file\n");
|
||||
if (conn.spool()){
|
||||
if (HTTP_R.Read(conn.Received())){
|
||||
handler = HANDLER_PROGRESSIVE;
|
||||
#if DEBUG >= 4
|
||||
std::cout << "Received request: " << HTTP_R.url << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (HTTP_R.url.length() > 10 && HTTP_R.url.substr(0, 7) == "/embed_" && HTTP_R.url.substr(HTTP_R.url.length() - 3, 3) == ".js"){
|
||||
streamname = HTTP_R.url.substr(7, HTTP_R.url.length() - 10);
|
||||
JSON::Value ServConf = JSON::fromFile("/tmp/mist/streamlist");
|
||||
std::string response;
|
||||
handler = HANDLER_NONE;
|
||||
HTTP_S.Clean();
|
||||
HTTP_S.SetHeader("Content-Type", "application/javascript");
|
||||
response = "// Generating embed code for stream " + streamname + "\n\n";
|
||||
if (ServConf["streams"].isMember(streamname)){
|
||||
std::string streamurl = "http://" + HTTP_S.GetHeader("Host") + "/" + streamname + ".flv";
|
||||
response += "// Stream URL: " + streamurl + "\n\n";
|
||||
response += "document.write('<object width=\"600\" height=\"409\"><param name=\"movie\" value=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\"></param><param name=\"flashvars\" value=\"src="+HTTP::Parser::urlencode(streamurl)+"&controlBarMode=floating\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"600\" height=\"409\" flashvars=\"src="+HTTP::Parser::urlencode(streamurl)+"&controlBarMode=floating\"></embed></object>');\n";
|
||||
}else{
|
||||
response += "// Stream not available at this server.\nalert(\"This stream is currently not available at this server.\\\\nPlease try again later!\");";
|
||||
}
|
||||
response += "";
|
||||
HTTP_S.SetBody(response);
|
||||
HTTP_S.SendResponse(conn, "200", "OK");
|
||||
#if DEBUG >= 3
|
||||
printf("Sending embed code for %s\n", streamname.c_str());
|
||||
#endif
|
||||
}
|
||||
if (handler == HANDLER_FLASH){
|
||||
if (HTTP_R.url.find("f4m") == std::string::npos){
|
||||
Movie = HTTP_R.url.substr(1);
|
||||
Movie = Movie.substr(0,Movie.find("/"));
|
||||
Quality = HTTP_R.url.substr( HTTP_R.url.find("/",1)+1 );
|
||||
Quality = Quality.substr(0, Quality.find("Seg"));
|
||||
temp = HTTP_R.url.find("Seg") + 3;
|
||||
Segment = atoi( HTTP_R.url.substr(temp,HTTP_R.url.find("-",temp)-temp).c_str());
|
||||
temp = HTTP_R.url.find("Frag") + 4;
|
||||
ReqFragment = atoi( HTTP_R.url.substr(temp).c_str() );
|
||||
#if DEBUG >= 4
|
||||
printf( "Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
|
||||
#endif
|
||||
Flash_RequestPending++;
|
||||
}else{
|
||||
Movie = HTTP_R.url.substr(1);
|
||||
Movie = Movie.substr(0,Movie.find("/"));
|
||||
if ((HTTP_R.url.find("Seg") != std::string::npos) && (HTTP_R.url.find("Frag") != std::string::npos)){handler = HANDLER_FLASH;}
|
||||
if (HTTP_R.url.find("f4m") != std::string::npos){handler = HANDLER_FLASH;}
|
||||
if (HTTP_R.url == "/crossdomain.xml"){
|
||||
handler = HANDLER_NONE;
|
||||
HTTP_S.Clean();
|
||||
HTTP_S.SetHeader("Content-Type","text/xml");
|
||||
HTTP_S.SetHeader("Cache-Control","no-cache");
|
||||
std::string manifest = BuildManifest(Movie);
|
||||
#if DEBUG >= 4
|
||||
printf("Manifest: %s\n", manifest.c_str());
|
||||
#endif
|
||||
HTTP_S.SetBody(manifest);
|
||||
HTTP_S.SendResponse(conn, "200", "OK");
|
||||
HTTP_S.SetHeader("Content-Type", "text/xml");
|
||||
HTTP_S.SetBody("<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" /><site-control permitted-cross-domain-policies=\"all\"/></cross-domain-policy>");
|
||||
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||
#if DEBUG >= 3
|
||||
printf("Sent manifest\n");
|
||||
printf("Sending crossdomain.xml file\n");
|
||||
#endif
|
||||
}
|
||||
#if DEBUG >= 4
|
||||
printf( "Movie: %s\n", Movie.c_str());
|
||||
if (HTTP_R.url.length() > 10 && HTTP_R.url.substr(0, 7) == "/embed_" && HTTP_R.url.substr(HTTP_R.url.length() - 3, 3) == ".js"){
|
||||
streamname = HTTP_R.url.substr(7, HTTP_R.url.length() - 10);
|
||||
JSON::Value ServConf = JSON::fromFile("/tmp/mist/streamlist");
|
||||
std::string response;
|
||||
handler = HANDLER_NONE;
|
||||
HTTP_S.Clean();
|
||||
HTTP_S.SetHeader("Content-Type", "application/javascript");
|
||||
response = "// Generating embed code for stream " + streamname + "\n\n";
|
||||
if (ServConf["streams"].isMember(streamname)){
|
||||
std::string streamurl = "http://" + HTTP_S.GetHeader("Host") + "/" + streamname + ".flv";
|
||||
response += "// Stream URL: " + streamurl + "\n\n";
|
||||
response += "document.write('<object width=\"600\" height=\"409\"><param name=\"movie\" value=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\"></param><param name=\"flashvars\" value=\"src="+HTTP::Parser::urlencode(streamurl)+"&controlBarMode=floating\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"600\" height=\"409\" flashvars=\"src="+HTTP::Parser::urlencode(streamurl)+"&controlBarMode=floating\"></embed></object>');\n";
|
||||
}else{
|
||||
response += "// Stream not available at this server.\nalert(\"This stream is currently not available at this server.\\\\nPlease try again later!\");";
|
||||
}
|
||||
response += "";
|
||||
HTTP_S.SetBody(response);
|
||||
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||
#if DEBUG >= 3
|
||||
printf("Sending embed code for %s\n", streamname.c_str());
|
||||
#endif
|
||||
}
|
||||
if (handler == HANDLER_FLASH){
|
||||
if (HTTP_R.url.find("f4m") == std::string::npos){
|
||||
Movie = HTTP_R.url.substr(1);
|
||||
Movie = Movie.substr(0,Movie.find("/"));
|
||||
Quality = HTTP_R.url.substr( HTTP_R.url.find("/",1)+1 );
|
||||
Quality = Quality.substr(0, Quality.find("Seg"));
|
||||
temp = HTTP_R.url.find("Seg") + 3;
|
||||
Segment = atoi( HTTP_R.url.substr(temp,HTTP_R.url.find("-",temp)-temp).c_str());
|
||||
temp = HTTP_R.url.find("Frag") + 4;
|
||||
ReqFragment = atoi( HTTP_R.url.substr(temp).c_str() );
|
||||
#if DEBUG >= 4
|
||||
printf( "Quality: %s, Seg %d Frag %d\n", Quality.c_str(), Segment, ReqFragment);
|
||||
#endif
|
||||
Flash_RequestPending++;
|
||||
}else{
|
||||
Movie = HTTP_R.url.substr(1);
|
||||
Movie = Movie.substr(0,Movie.find("/"));
|
||||
HTTP_S.Clean();
|
||||
HTTP_S.SetHeader("Content-Type","text/xml");
|
||||
HTTP_S.SetHeader("Cache-Control","no-cache");
|
||||
std::string manifest = BuildManifest(Movie);
|
||||
#if DEBUG >= 4
|
||||
printf("Manifest: %s\n", manifest.c_str());
|
||||
#endif
|
||||
HTTP_S.SetBody(manifest);
|
||||
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||
#if DEBUG >= 3
|
||||
printf("Sent manifest\n");
|
||||
#endif
|
||||
}
|
||||
#if DEBUG >= 4
|
||||
printf( "Movie: %s\n", Movie.c_str());
|
||||
#endif
|
||||
streamname = Movie;
|
||||
ready4data = true;
|
||||
}//FLASH handler
|
||||
if (handler == HANDLER_PROGRESSIVE){
|
||||
//we assume the URL is the stream name with a 3 letter extension
|
||||
std::string extension = HTTP_R.url.substr(HTTP_R.url.size()-4);
|
||||
streamname = HTTP_R.url.substr(0, HTTP_R.url.size()-4);//strip the extension
|
||||
/// \todo VoD streams will need support for position reading from the URL parameters
|
||||
ready4data = true;
|
||||
#if DEBUG >= 4
|
||||
printf( "Opening progressive stream: %s\n", streamname.c_str());
|
||||
#endif
|
||||
}//PROGRESSIVE handler
|
||||
HTTP_R.Clean(); //clean for any possinble next requests
|
||||
}else{
|
||||
#if DEBUG >= 3
|
||||
fprintf(stderr, "Could not parse the following:\n%s\n", conn.Received().c_str());
|
||||
#endif
|
||||
streamname = Movie;
|
||||
ready4data = true;
|
||||
}//FLASH handler
|
||||
if (handler == HANDLER_PROGRESSIVE){
|
||||
//we assume the URL is the stream name with a 3 letter extension
|
||||
std::string extension = HTTP_R.url.substr(HTTP_R.url.size()-4);
|
||||
streamname = HTTP_R.url.substr(0, HTTP_R.url.size()-4);//strip the extension
|
||||
/// \todo VoD streams will need support for position reading from the URL parameters
|
||||
ready4data = true;
|
||||
#if DEBUG >= 4
|
||||
printf( "Opening progressive stream: %s\n", streamname.c_str());
|
||||
#endif
|
||||
}//PROGRESSIVE handler
|
||||
HTTP_R.CleanForNext(); //clean for any possinble next requests
|
||||
}
|
||||
}
|
||||
if (ready4data){
|
||||
if (!inited){
|
||||
|
@ -277,22 +288,18 @@ namespace Connector_HTTP{
|
|||
HTTP_S.SetHeader("Content-Type","video/mp4");
|
||||
HTTP_S.SetBody(MP4::mdatFold(Flash_FragBuffer.front()));
|
||||
Flash_FragBuffer.pop();
|
||||
HTTP_S.SendResponse(conn, "200", "OK");//schrijf de HTTP response header
|
||||
conn.Send(HTTP_S.BuildResponse("200", "OK"));
|
||||
Flash_RequestPending--;
|
||||
#if DEBUG >= 3
|
||||
fprintf(stderr, "Sending a video fragment. %i left in buffer, %i requested\n", (int)Flash_FragBuffer.size(), Flash_RequestPending);
|
||||
#endif
|
||||
}
|
||||
if (inited){
|
||||
unsigned int now = time(0);
|
||||
if (now != lastStats){
|
||||
lastStats = now;
|
||||
std::string stat = "S "+conn.getStats("HTTP");
|
||||
ss.write(stat);
|
||||
}
|
||||
unsigned int now = time(0);
|
||||
if (now != lastStats){
|
||||
lastStats = now;
|
||||
ss.Send("S "+conn.getStats("HTTP"));
|
||||
}
|
||||
if (ss.canRead()){
|
||||
ss.spool();
|
||||
if (ss.spool() || ss.Received() != ""){
|
||||
if (Strm.parsePacket(ss.Received())){
|
||||
tag.DTSCLoader(Strm);
|
||||
if (handler == HANDLER_FLASH){
|
||||
|
|
|
@ -88,7 +88,6 @@ void WriteFile( std::string Filename, std::string contents ) {
|
|||
|
||||
class ConnectedUser{
|
||||
public:
|
||||
std::string writebuffer;
|
||||
Socket::Connection C;
|
||||
HTTP::Parser H;
|
||||
bool Authorized;
|
||||
|
@ -439,7 +438,7 @@ int main(int argc, char ** argv){
|
|||
uplink->H.Clean();
|
||||
uplink->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
||||
uplink->H.BuildRequest();
|
||||
uplink->writebuffer += uplink->H.BuildResponse("200", "OK");
|
||||
uplink->C.Send(uplink->H.BuildResponse("200", "OK"));
|
||||
uplink->H.Clean();
|
||||
//Log("UPLK", "Sending server data to uplink.");
|
||||
}else{
|
||||
|
@ -459,8 +458,7 @@ int main(int argc, char ** argv){
|
|||
buffers.erase(it);
|
||||
break;
|
||||
}
|
||||
it->spool();
|
||||
if (it->Received() != ""){
|
||||
if (it->spool()){
|
||||
size_t newlines = it->Received().find("\n\n");
|
||||
while (newlines != std::string::npos){
|
||||
Request = it->Received().substr(0, newlines);
|
||||
|
@ -489,85 +487,84 @@ int main(int argc, char ** argv){
|
|||
users.erase(it);
|
||||
break;
|
||||
}
|
||||
if (it->writebuffer != ""){
|
||||
it->C.iwrite(it->writebuffer);
|
||||
}
|
||||
if (it->H.Read(it->C)){
|
||||
Response.null(); //make sure no data leaks from previous requests
|
||||
if (it->clientMode){
|
||||
// In clientMode, requests are reversed. These are connections we initiated to GearBox.
|
||||
// They are assumed to be authorized, but authorization to gearbox is still done.
|
||||
// This authorization uses the compiled-in username and password (account).
|
||||
Request = JSON::fromString(it->H.body);
|
||||
if (Request["authorize"]["status"] != "OK"){
|
||||
if (Request["authorize"].isMember("challenge")){
|
||||
it->logins++;
|
||||
if (it->logins > 2){
|
||||
Log("UPLK", "Max login attempts passed - dropping connection to uplink.");
|
||||
it->C.close();
|
||||
}else{
|
||||
Response["config"] = Storage["config"];
|
||||
Response["streams"] = Storage["streams"];
|
||||
Response["log"] = Storage["log"];
|
||||
Response["statistics"] = Storage["statistics"];
|
||||
Response["authorize"]["username"] = TOSTRING(COMPILED_USERNAME);
|
||||
Log("UPLK", "Responding to login challenge: " + (std::string)Request["authorize"]["challenge"]);
|
||||
Response["authorize"]["password"] = md5(TOSTRING(COMPILED_PASSWORD) + (std::string)Request["authorize"]["challenge"]);
|
||||
it->H.Clean();
|
||||
it->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
||||
it->H.BuildRequest();
|
||||
it->writebuffer += it->H.BuildResponse("200", "OK");
|
||||
it->H.Clean();
|
||||
Log("UPLK", "Attempting login to uplink.");
|
||||
if (it->C.spool()){
|
||||
if (it->H.Read(it->C.Received())){
|
||||
Response.null(); //make sure no data leaks from previous requests
|
||||
if (it->clientMode){
|
||||
// In clientMode, requests are reversed. These are connections we initiated to GearBox.
|
||||
// They are assumed to be authorized, but authorization to gearbox is still done.
|
||||
// This authorization uses the compiled-in username and password (account).
|
||||
Request = JSON::fromString(it->H.body);
|
||||
if (Request["authorize"]["status"] != "OK"){
|
||||
if (Request["authorize"].isMember("challenge")){
|
||||
it->logins++;
|
||||
if (it->logins > 2){
|
||||
Log("UPLK", "Max login attempts passed - dropping connection to uplink.");
|
||||
it->C.close();
|
||||
}else{
|
||||
Response["config"] = Storage["config"];
|
||||
Response["streams"] = Storage["streams"];
|
||||
Response["log"] = Storage["log"];
|
||||
Response["statistics"] = Storage["statistics"];
|
||||
Response["authorize"]["username"] = TOSTRING(COMPILED_USERNAME);
|
||||
Log("UPLK", "Responding to login challenge: " + (std::string)Request["authorize"]["challenge"]);
|
||||
Response["authorize"]["password"] = md5(TOSTRING(COMPILED_PASSWORD) + (std::string)Request["authorize"]["challenge"]);
|
||||
it->H.Clean();
|
||||
it->H.SetBody("command="+HTTP::Parser::urlencode(Response.toString()));
|
||||
it->H.BuildRequest();
|
||||
it->C.Send(it->H.BuildResponse("200", "OK"));
|
||||
it->H.Clean();
|
||||
Log("UPLK", "Attempting login to uplink.");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if (Request.isMember("config")){CheckConfig(Request["config"], Storage["config"]);}
|
||||
if (Request.isMember("streams")){CheckStreams(Request["streams"], Storage["streams"]);}
|
||||
if (Request.isMember("clearstatlogs")){
|
||||
Storage["log"].null();
|
||||
Storage["statistics"].null();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if (Request.isMember("config")){CheckConfig(Request["config"], Storage["config"]);}
|
||||
if (Request.isMember("streams")){CheckStreams(Request["streams"], Storage["streams"]);}
|
||||
if (Request.isMember("clearstatlogs")){
|
||||
Request = JSON::fromString(it->H.GetVar("command"));
|
||||
std::cout << "Request: " << Request.toString() << std::endl;
|
||||
Authorize(Request, Response, (*it));
|
||||
if (it->Authorized){
|
||||
//Parse config and streams from the request.
|
||||
if (Request.isMember("config")){CheckConfig(Request["config"], Storage["config"]);}
|
||||
if (Request.isMember("streams")){CheckStreams(Request["streams"], Storage["streams"]);}
|
||||
if (Request.isMember("save")){
|
||||
WriteFile("config.json", Storage.toString());
|
||||
Log("CONF", "Config written to file on request through API");
|
||||
}
|
||||
//sent current configuration, no matter if it was changed or not
|
||||
//Response["streams"] = Storage["streams"];
|
||||
Response["config"] = Storage["config"];
|
||||
Response["streams"] = Storage["streams"];
|
||||
//add required data to the current unix time to the config, for syncing reasons
|
||||
Response["config"]["time"] = (long long int)time(0);
|
||||
if (!Response["config"].isMember("serverid")){Response["config"]["serverid"] = "";}
|
||||
//sent any available logs and statistics
|
||||
Response["log"] = Storage["log"];
|
||||
Response["statistics"] = Storage["statistics"];
|
||||
//clear log and statistics to prevent useless data transfer
|
||||
Storage["log"].null();
|
||||
Storage["statistics"].null();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
Request = JSON::fromString(it->H.GetVar("command"));
|
||||
std::cout << "Request: " << Request.toString() << std::endl;
|
||||
Authorize(Request, Response, (*it));
|
||||
if (it->Authorized){
|
||||
//Parse config and streams from the request.
|
||||
if (Request.isMember("config")){CheckConfig(Request["config"], Storage["config"]);}
|
||||
if (Request.isMember("streams")){CheckStreams(Request["streams"], Storage["streams"]);}
|
||||
if (Request.isMember("save")){
|
||||
WriteFile("config.json", Storage.toString());
|
||||
Log("CONF", "Config written to file on request through API");
|
||||
jsonp = "";
|
||||
if (it->H.GetVar("callback") != ""){jsonp = it->H.GetVar("callback");}
|
||||
if (it->H.GetVar("jsonp") != ""){jsonp = it->H.GetVar("jsonp");}
|
||||
it->H.Clean();
|
||||
it->H.protocol = "HTTP/1.0";
|
||||
it->H.SetHeader("Content-Type", "text/javascript");
|
||||
if (jsonp == ""){
|
||||
it->H.SetBody(Response.toString()+"\n\n");
|
||||
}else{
|
||||
it->H.SetBody(jsonp+"("+Response.toString()+");\n\n");
|
||||
}
|
||||
//sent current configuration, no matter if it was changed or not
|
||||
//Response["streams"] = Storage["streams"];
|
||||
Response["config"] = Storage["config"];
|
||||
Response["streams"] = Storage["streams"];
|
||||
//add required data to the current unix time to the config, for syncing reasons
|
||||
Response["config"]["time"] = (long long int)time(0);
|
||||
if (!Response["config"].isMember("serverid")){Response["config"]["serverid"] = "";}
|
||||
//sent any available logs and statistics
|
||||
Response["log"] = Storage["log"];
|
||||
Response["statistics"] = Storage["statistics"];
|
||||
//clear log and statistics to prevent useless data transfer
|
||||
Storage["log"].null();
|
||||
Storage["statistics"].null();
|
||||
it->C.Send(it->H.BuildResponse("200", "OK"));
|
||||
it->H.Clean();
|
||||
}
|
||||
jsonp = "";
|
||||
if (it->H.GetVar("callback") != ""){jsonp = it->H.GetVar("callback");}
|
||||
if (it->H.GetVar("jsonp") != ""){jsonp = it->H.GetVar("jsonp");}
|
||||
it->H.Clean();
|
||||
it->H.protocol = "HTTP/1.0";
|
||||
it->H.SetHeader("Content-Type", "text/javascript");
|
||||
if (jsonp == ""){
|
||||
it->H.SetBody(Response.toString()+"\n\n");
|
||||
}else{
|
||||
it->H.SetBody(jsonp+"("+Response.toString()+");\n\n");
|
||||
}
|
||||
it->writebuffer += it->H.BuildResponse("200", "OK");
|
||||
it->H.Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue