Added generic PUSH_REWRITE trigger, fixed request URL bug

This commit is contained in:
Thulinma 2020-11-30 15:19:55 +01:00
parent ea49344628
commit 7c6da9d455
9 changed files with 163 additions and 17 deletions

View file

@ -125,6 +125,16 @@ namespace Controller{
"If non-empty, overrides the full RTMP url to the response value. If empty, denies the " "If non-empty, overrides the full RTMP url to the response value. If empty, denies the "
"incoming RTMP push."; "incoming RTMP push.";
trgs["PUSH_REWRITE"]["when"] =
"On all incoming pushes on any protocol, allows parsing the push URL to/from custom formatting to an internal stream name";
trgs["PUSH_REWRITE"]["stream_specific"] = false;
trgs["PUSH_REWRITE"]["payload"] =
"full current push url (string)\nconnection hostname (string)\ncurrently parsed stream name (string)";
trgs["PUSH_REWRITE"]["response"] = "when-blocking";
trgs["PUSH_REWRITE"]["response_action"] =
"If non-empty, overrides the parsed stream name to the response value. If empty, denies the "
"incoming push.";
trgs["PUSH_OUT_START"]["when"] = "Before a push out (to file or other target type) is started"; trgs["PUSH_OUT_START"]["when"] = "Before a push out (to file or other target type) is started";
trgs["PUSH_OUT_START"]["stream_specific"] = true; trgs["PUSH_OUT_START"]["stream_specific"] = true;
trgs["PUSH_OUT_START"]["payload"] = "stream name (string)\npush target (string)"; trgs["PUSH_OUT_START"]["payload"] = "stream name (string)\npush target (string)";

View file

@ -295,7 +295,13 @@ namespace Mist{
void OutDTSC::handlePlay(DTSC::Scan &dScan){ void OutDTSC::handlePlay(DTSC::Scan &dScan){
streamName = dScan.getMember("stream").asString(); streamName = dScan.getMember("stream").asString();
Util::sanitizeName(streamName); Util::sanitizeName(streamName);
Util::streamName = streamName; Util::setStreamName(streamName);
HTTP::URL qUrl;
qUrl.protocol = "dtsc";
qUrl.host = myConn.getBoundAddress();
qUrl.port = config->getOption("port").asString();
qUrl.path = streamName;
reqUrl = qUrl.getUrl();
parseData = true; parseData = true;
INFO_MSG("Handled play for stream %s", streamName.c_str()); INFO_MSG("Handled play for stream %s", streamName.c_str());
setBlocking(false); setBlocking(false);
@ -305,7 +311,32 @@ namespace Mist{
streamName = dScan.getMember("stream").asString(); streamName = dScan.getMember("stream").asString();
std::string passString = dScan.getMember("password").asString(); std::string passString = dScan.getMember("password").asString();
Util::sanitizeName(streamName); Util::sanitizeName(streamName);
Util::streamName = streamName; Util::setStreamName(streamName);
HTTP::URL qUrl;
qUrl.protocol = "dtsc";
qUrl.host = myConn.getBoundAddress();
qUrl.port = config->getOption("port").asString();
qUrl.path = streamName;
qUrl.pass = passString;
reqUrl = qUrl.getUrl();
if (Triggers::shouldTrigger("PUSH_REWRITE")){
std::string payload = reqUrl + "\n" + getConnectedHost() + "\n" + streamName;
std::string newStream = streamName;
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
Util::logExitReason(
"Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
onFail("Push not allowed - rejected by trigger");
return;
}else{
streamName = newStream;
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
}
if (!allowPush(passString)){ if (!allowPush(passString)){
onFail("Push not allowed - stream and/or password incorrect", true); onFail("Push not allowed - stream and/or password incorrect", true);
return; return;

View file

@ -3,6 +3,7 @@
#include <mist/langcodes.h> #include <mist/langcodes.h>
#include <mist/stream.h> #include <mist/stream.h>
#include <mist/util.h> #include <mist/util.h>
#include <mist/url.h>
#include <set> #include <set>
#include <sys/stat.h> #include <sys/stat.h>
@ -234,7 +235,12 @@ namespace Mist{
} }
/*LTS-START*/ /*LTS-START*/
reqUrl = H.url + H.allVars(); {
HTTP::URL qUrl("http://"+H.GetHeader("Host")+"/"+H.url + H.allVars());
if (!qUrl.host.size()){qUrl.host = myConn.getBoundAddress();}
if (!qUrl.port.size() && config->hasOption("port")){qUrl.port = config->getOption("port").asString();}
reqUrl = qUrl.getUrl();
}
/*LTS-END*/ /*LTS-END*/
if (H.hasHeader("User-Agent")){UA = H.GetHeader("User-Agent");} if (H.hasHeader("User-Agent")){UA = H.GetHeader("User-Agent");}
if (hasSessionIDs()){ if (hasSessionIDs()){

View file

@ -1,6 +1,7 @@
#include "output_json.h" #include "output_json.h"
#include <iomanip> #include <iomanip>
#include <mist/stream.h> #include <mist/stream.h>
#include <mist/triggers.h>
namespace Mist{ namespace Mist{
OutJSON::OutJSON(Socket::Connection &conn) : HTTPOutput(conn){ OutJSON::OutJSON(Socket::Connection &conn) : HTTPOutput(conn){
@ -150,6 +151,21 @@ namespace Mist{
void OutJSON::onWebsocketFrame(){ void OutJSON::onWebsocketFrame(){
if (!isPushing()){ if (!isPushing()){
if (Triggers::shouldTrigger("PUSH_REWRITE")){
std::string payload = reqUrl + "\n" + getConnectedHost() + "\n" + streamName;
std::string newStream = streamName;
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
onFinish();
return;
}else{
streamName = newStream;
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
}
if (!allowPush(pushPass)){ if (!allowPush(pushPass)){
onFinish(); onFinish();
return; return;

View file

@ -876,6 +876,25 @@ namespace Mist{
Util::sanitizeName(streamName); Util::sanitizeName(streamName);
if (Triggers::shouldTrigger("PUSH_REWRITE")){
std::string payload = reqUrl + "\n" + getConnectedHost() + "\n" + streamName;
std::string newStream = streamName;
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
Util::logExitReason(
"Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
onFinish();
return;
}else{
streamName = newStream;
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
}
if (!allowPush(app_name)){ if (!allowPush(app_name)){
onFinish(); onFinish();
return; return;

View file

@ -431,6 +431,27 @@ namespace Mist{
continue; continue;
} }
if (HTTP_R.method == "ANNOUNCE"){ if (HTTP_R.method == "ANNOUNCE"){
if (Triggers::shouldTrigger("PUSH_REWRITE")){
HTTP::URL qUrl("rtsp://"+HTTP_R.GetHeader("Host")+"/"+HTTP_R.url);
if (!qUrl.host.size()){qUrl.host = myConn.getBoundAddress();}
if (!qUrl.port.size()){qUrl.port = config->getOption("port").asString();}
std::string payload = qUrl.getUrl() + "\n" + getConnectedHost() + "\n" + streamName;
std::string newStream = streamName;
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), qUrl.getUrl().c_str());
Util::logExitReason(
"Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), qUrl.getUrl().c_str());
onFinish();
return;
}else{
streamName = newStream;
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
}
if (!allowPush(HTTP_R.GetVar("pass"))){ if (!allowPush(HTTP_R.GetVar("pass"))){
onFinish(); onFinish();
return; return;

View file

@ -2,6 +2,8 @@
#include <mist/defines.h> #include <mist/defines.h>
#include <mist/http_parser.h> #include <mist/http_parser.h>
#include <mist/url.h> #include <mist/url.h>
#include <mist/triggers.h>
#include <mist/stream.h>
namespace Mist{ namespace Mist{
OutTS::OutTS(Socket::Connection &conn) : TSOutput(conn){ OutTS::OutTS(Socket::Connection &conn) : TSOutput(conn){
@ -48,6 +50,21 @@ namespace Mist{
wantRequest = pushing; wantRequest = pushing;
parseData = !pushing; parseData = !pushing;
if (pushing){ if (pushing){
if (Triggers::shouldTrigger("PUSH_REWRITE")){
std::string payload = "ts-tcp://" + myConn.getBoundAddress() + ":" + config->getOption("port").asString() + "\n" + getConnectedHost() + "\n" + streamName;
std::string newStream = streamName;
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
config->is_active = false;
return;
}else{
streamName = newStream;
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
}
if (!allowPush("")){ if (!allowPush("")){
FAIL_MSG("Pushing not allowed"); FAIL_MSG("Pushing not allowed");
config->is_active = false; config->is_active = false;
@ -164,6 +181,21 @@ namespace Mist{
} }
if (parseData){ if (parseData){
parseData = false; parseData = false;
if (Triggers::shouldTrigger("PUSH_REWRITE")){
std::string payload = "ts-tcp://" + myConn.getBoundAddress() + ":" + config->getOption("port").asString() + "\n" + getConnectedHost() + "\n" + streamName;
std::string newStream = "";
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
onFinish();
return;
}else{
streamName = newStream;
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
}
if (!allowPush("")){ if (!allowPush("")){
onFinish(); onFinish();
return; return;

View file

@ -94,10 +94,10 @@ namespace Mist{
reqUrl.port = config->getString("port"); reqUrl.port = config->getString("port");
reqUrl.host = config->getString("interface"); reqUrl.host = config->getString("interface");
reqUrl.args = "streamid="+Encodings::URL::encode(sName); reqUrl.args = "streamid="+Encodings::URL::encode(sName);
std::string payload = reqUrl.getUrl() + "\n" + getConnectedHost(); std::string payload = reqUrl.getUrl() + "\n" + getConnectedHost() + "\n" + streamName;
std::string newUrl = ""; std::string newStream = streamName;
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newUrl); Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newUrl.size()){ if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL", FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.getUrl().c_str()); getConnectedHost().c_str(), reqUrl.getUrl().c_str());
Util::logExitReason( Util::logExitReason(
@ -105,16 +105,9 @@ namespace Mist{
getConnectedHost().c_str(), reqUrl.getUrl().c_str()); getConnectedHost().c_str(), reqUrl.getUrl().c_str());
onFinish(); onFinish();
return; return;
} }else{
reqUrl = HTTP::URL(newUrl); streamName = newStream;
if (reqUrl.args.size()){ Util::sanitizeName(streamName);
std::map<std::string, std::string> args;
HTTP::parseVars(reqUrl.args, args);
if (args.count("streamid")){
streamName = args["streamid"];
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
} }
} }
myConn.setHost(srtConn.remotehost); myConn.setHost(srtConn.remotehost);

View file

@ -4,6 +4,8 @@
#include <mist/sdp.h> #include <mist/sdp.h>
#include <mist/timing.h> #include <mist/timing.h>
#include <mist/url.h> #include <mist/url.h>
#include <mist/stream.h>
#include <mist/triggers.h>
#include <netdb.h> // ifaddr, listing ip addresses. #include <netdb.h> // ifaddr, listing ip addresses.
#include <mist/stream.h> #include <mist/stream.h>
@ -820,6 +822,22 @@ namespace Mist{
} }
} }
if (Triggers::shouldTrigger("PUSH_REWRITE")){
std::string payload = reqUrl + "\n" + getConnectedHost() + "\n" + streamName;
std::string newStream = streamName;
Triggers::doTrigger("PUSH_REWRITE", payload, "", false, newStream);
if (!newStream.size()){
FAIL_MSG("Push from %s to URL %s rejected - PUSH_REWRITE trigger blanked the URL",
getConnectedHost().c_str(), reqUrl.c_str());
return false;
}else{
streamName = newStream;
Util::sanitizeName(streamName);
Util::setStreamName(streamName);
}
}
// allow peer to push video/audio // allow peer to push video/audio
if (!allowPush("")){ if (!allowPush("")){
FAIL_MSG("Failed to allow push"); FAIL_MSG("Failed to allow push");