Added --public-address option to HTTP output, for address overwriting
This commit is contained in:
parent
543ae0882b
commit
5000afe768
3 changed files with 75 additions and 39 deletions
|
@ -74,11 +74,7 @@ HTTP::URL::URL(const std::string & url){
|
|||
port = host;
|
||||
host = "";
|
||||
}
|
||||
EXTREME_MSG("URL host: %s", host.c_str());
|
||||
EXTREME_MSG("URL protocol: %s", protocol.c_str());
|
||||
EXTREME_MSG("URL port: %s", port.c_str());
|
||||
EXTREME_MSG("URL path: %s", path.c_str());
|
||||
EXTREME_MSG("URL args: %s", args.c_str());
|
||||
EXTREME_MSG("URL: %s", getUrl().c_str());
|
||||
}
|
||||
|
||||
///Returns the port in numeric format
|
||||
|
@ -87,6 +83,19 @@ uint32_t HTTP::URL::getPort() const{
|
|||
return atoi(port.c_str());
|
||||
}
|
||||
|
||||
///Returns the full URL in string format
|
||||
std::string HTTP::URL::getUrl() const{
|
||||
std::string ret;
|
||||
if (protocol.size()){
|
||||
ret = protocol + "://" + host;
|
||||
}else{
|
||||
ret = "//" + host;
|
||||
}
|
||||
if (port.size()){ret += ":" + port;}
|
||||
if (path.size()){ret += "/" + path;}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// This constructor creates an empty HTTP::Parser, ready for use for either reading or writing.
|
||||
/// All this constructor does is call HTTP::Parser::Clean().
|
||||
HTTP::Parser::Parser() {
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace HTTP {
|
|||
public:
|
||||
URL(const std::string & url);
|
||||
uint32_t getPort() const;
|
||||
std::string getUrl() const;
|
||||
std::string host;///< Hostname or IP address of URL
|
||||
std::string protocol;///<Protocol of URL
|
||||
std::string port;///<Port of URL
|
||||
|
|
|
@ -100,6 +100,12 @@ namespace Mist {
|
|||
capa["optional"]["nostreamtext"]["default"] = "";
|
||||
capa["optional"]["nostreamtext"]["type"] = "str";
|
||||
capa["optional"]["nostreamtext"]["option"] = "--nostreamtext";
|
||||
cfg->addOption("pubaddr", JSON::fromString("{\"arg\":\"string\", \"default\":\"\", \"short\":\"A\",\"long\":\"public-address\",\"help\":\"Full public address this output is available as.\"}"));
|
||||
capa["optional"]["pubaddr"]["name"] = "Public address";
|
||||
capa["optional"]["pubaddr"]["help"] = "Full public address this output is available as, if being proxied";
|
||||
capa["optional"]["pubaddr"]["default"] = "";
|
||||
capa["optional"]["pubaddr"]["type"] = "str";
|
||||
capa["optional"]["pubaddr"]["option"] = "--public-address";
|
||||
/*LTS-END*/
|
||||
}
|
||||
|
||||
|
@ -138,7 +144,7 @@ namespace Mist {
|
|||
}
|
||||
};
|
||||
|
||||
void addSource(const std::string & rel, std::set<JSON::Value, sourceCompare> & sources, std::string & host, const std::string & port, JSON::Value & conncapa, unsigned int most_simul, unsigned int total_matches, const std::string & protocol){
|
||||
void addSource(const std::string & rel, std::set<JSON::Value, sourceCompare> & sources, const HTTP::URL & url, JSON::Value & conncapa, unsigned int most_simul, unsigned int total_matches){
|
||||
JSON::Value tmp;
|
||||
tmp["type"] = conncapa["type"];
|
||||
tmp["relurl"] = rel;
|
||||
|
@ -146,12 +152,16 @@ namespace Mist {
|
|||
if (conncapa.isMember("player_url")){tmp["player_url"] = conncapa["player_url"].asStringRef();}
|
||||
tmp["simul_tracks"] = most_simul;
|
||||
tmp["total_matches"] = total_matches;
|
||||
tmp["url"] = protocol + host + ":" + port + rel;
|
||||
if (url.path.size()){
|
||||
tmp["url"] = url.protocol + "://" + url.host + ":" + url.port + "/" + url.path + rel;
|
||||
}else{
|
||||
tmp["url"] = url.protocol + "://" + url.host + ":" + url.port + rel;
|
||||
}
|
||||
sources.insert(tmp);
|
||||
}
|
||||
|
||||
|
||||
void addSources(std::string & streamname, std::set<JSON::Value, sourceCompare> & sources, std::string & host, const std::string & port, JSON::Value & conncapa, JSON::Value & strmMeta, const std::string httpHost, JSON::Value * mainconn_capa = 0){
|
||||
void addSources(std::string & streamname, std::set<JSON::Value, sourceCompare> & sources, HTTP::URL url, JSON::Value & conncapa, JSON::Value & strmMeta){
|
||||
const std::string & rel = conncapa["url_rel"].asStringRef();
|
||||
unsigned int most_simul = 0;
|
||||
unsigned int total_matches = 0;
|
||||
|
@ -189,10 +199,6 @@ namespace Mist {
|
|||
}else{
|
||||
relurl = "/";
|
||||
}
|
||||
std::string protocol;
|
||||
if (mainconn_capa && mainconn_capa->isMember("protocol")){
|
||||
protocol = (*mainconn_capa)["protocol"].asStringRef();
|
||||
}
|
||||
jsonForEach(conncapa["methods"], it) {
|
||||
if (it->isMember("url_rel")){
|
||||
size_t foundb = (*it)["url_rel"].asStringRef().find('$');
|
||||
|
@ -201,10 +207,10 @@ namespace Mist {
|
|||
}
|
||||
}
|
||||
if (!strmMeta.isMember("live") || !it->isMember("nolive")){
|
||||
if (!protocol.size() && it->isMember("handler")){
|
||||
protocol = (*it)["handler"].asStringRef() + "://";
|
||||
if (!url.protocol.size() && it->isMember("handler")){
|
||||
url.protocol = (*it)["handler"].asStringRef();
|
||||
}
|
||||
addSource(relurl, sources, host, port, *it, most_simul, total_matches, protocol);
|
||||
addSource(relurl, sources, url, *it, most_simul, total_matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +276,16 @@ namespace Mist {
|
|||
|
||||
// send generic HTML page
|
||||
if (H.url.length() > 6 && H.url.substr(H.url.length() - 5, 5) == ".html"){
|
||||
std::string fullHost = H.GetHeader("Host");
|
||||
HTTP::URL fullURL(H.GetHeader("Host"));
|
||||
/*LTS-START*/
|
||||
if (config->getString("pubaddr") != ""){
|
||||
HTTP::URL altURL(config->getString("pubaddr"));
|
||||
fullURL.protocol = altURL.protocol;
|
||||
if (altURL.host.size()){fullURL.host = altURL.host;}
|
||||
fullURL.port = altURL.port;
|
||||
fullURL.path = altURL.path;
|
||||
}
|
||||
/*LTS-END*/
|
||||
std::string uAgent = H.GetHeader("User-Agent");
|
||||
H.Clean();
|
||||
H.SetHeader("Content-Type", "text/html");
|
||||
|
@ -285,7 +300,7 @@ namespace Mist {
|
|||
std::string hlsUrl = "/hls/"+streamName+"/index.m3u8";
|
||||
std::string mp4Url = "/"+streamName+".mp4";
|
||||
|
||||
H.SetBody("<!DOCTYPE html><html><head><title>"+streamName+"</title><style>body{color:white;background:black;}</style></head><body><div class=mistvideo id=\""+streamName+"\"><noscript><video controls autoplay><source src=\""+hlsUrl+"\" type=\"application/vnd.apple.mpegurl\"><source src=\""+mp4Url+"\" type=\"video/mp4\"><a href=\""+hlsUrl+"\">Click here to play the video [Apple]</a><br><a href=\""+mp4Url+"\">Click here to play the video [MP4]</a></video></noscript><script src=\"/player.js\"></script><script>mistPlay('"+streamName+"',{host:'//"+fullHost+"',target:document.getElementById('"+streamName+"')})</script></div></body></html>");
|
||||
H.SetBody("<!DOCTYPE html><html><head><title>"+streamName+"</title><style>body{color:white;background:black;}</style></head><body><div class=mistvideo id=\""+streamName+"\"><noscript><video controls autoplay><source src=\""+hlsUrl+"\" type=\"application/vnd.apple.mpegurl\"><source src=\""+mp4Url+"\" type=\"video/mp4\"><a href=\""+hlsUrl+"\">Click here to play the video [Apple]</a><br><a href=\""+mp4Url+"\">Click here to play the video [MP4]</a></video></noscript><script src=\"/player.js\"></script><script>mistPlay('"+streamName+"',{host:'"+fullURL.getUrl()+"',target:document.getElementById('"+streamName+"')})</script></div></body></html>");
|
||||
if ((uAgent.find("iPad") != std::string::npos) || (uAgent.find("iPod") != std::string::npos) || (uAgent.find("iPhone") != std::string::npos)) {
|
||||
H.SetHeader("Location",hlsUrl);
|
||||
H.SendResponse("307", "HLS redirect", myConn);
|
||||
|
@ -297,11 +312,7 @@ namespace Mist {
|
|||
|
||||
// send smil MBR index
|
||||
if (H.url.length() > 6 && H.url.substr(H.url.length() - 5, 5) == ".smil"){
|
||||
std::string host = H.GetHeader("Host");
|
||||
if (host.rfind(':') != std::string::npos && *host.rbegin() != ']'){
|
||||
host.resize(host.rfind(':'));
|
||||
}
|
||||
|
||||
std::string reqHost = HTTP::URL(H.GetHeader("Host")).host;
|
||||
std::string port, url_rel;
|
||||
|
||||
IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
|
||||
|
@ -347,20 +358,16 @@ namespace Mist {
|
|||
H.Clean();
|
||||
return;
|
||||
}
|
||||
H.SetBody("<smil>\n <head>\n <meta base='rtmp://" + host + ":" + port + url_rel + "' />\n </head>\n <body>\n <switch>\n"+trackSources+" </switch>\n </body>\n</smil>");
|
||||
H.SetBody("<smil>\n <head>\n <meta base='rtmp://" + reqHost + ":" + port + url_rel + "' />\n </head>\n <body>\n <switch>\n"+trackSources+" </switch>\n </body>\n</smil>");
|
||||
H.SendResponse("200", "OK", myConn);
|
||||
H.Clean();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((H.url.length() > 9 && H.url.substr(0, 6) == "/info_" && H.url.substr(H.url.length() - 3, 3) == ".js") || (H.url.length() > 10 && H.url.substr(0, 7) == "/embed_" && H.url.substr(H.url.length() - 3, 3) == ".js") || (H.url.length() > 9 && H.url.substr(0, 6) == "/json_" && H.url.substr(H.url.length() - 3, 3) == ".js")){
|
||||
std::string fullHost = H.GetHeader("Host");
|
||||
std::string reqHost = HTTP::URL(H.GetHeader("Host")).host;
|
||||
std::string response;
|
||||
std::string rURL = H.url;
|
||||
std::string host = H.GetHeader("Host");
|
||||
if (host.rfind(':') != std::string::npos && *host.rbegin() != ']'){
|
||||
host.resize(host.rfind(':'));
|
||||
}
|
||||
H.Clean();
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
H.setCORSHeaders();
|
||||
|
@ -458,15 +465,29 @@ namespace Mist {
|
|||
DTSC::Scan capa = DTSC::Scan(serverCfg.mapped, serverCfg.len).getMember("capabilities").getMember("connectors").getMember(cName);
|
||||
//if the connector has a port,
|
||||
if (capa.getMember("optional").getMember("port")){
|
||||
HTTP::URL outURL(reqHost);
|
||||
//get the default port if none is set
|
||||
std::string port = prots.getIndice(i).getMember("port").asString();
|
||||
if (!port.size()){
|
||||
port = capa.getMember("optional").getMember("port").getMember("default").asString();
|
||||
outURL.port = prots.getIndice(i).getMember("port").asString();
|
||||
if (!outURL.port.size()){
|
||||
outURL.port = capa.getMember("optional").getMember("port").getMember("default").asString();
|
||||
}
|
||||
outURL.protocol = capa.getMember("protocol").asString();
|
||||
if (outURL.protocol.find(':') != std::string::npos){
|
||||
outURL.protocol.erase(outURL.protocol.find(':'));
|
||||
}
|
||||
/*LTS-START*/
|
||||
if (prots.getIndice(i).hasMember("pubaddr") && prots.getIndice(i).getMember("pubaddr").asString().size()){
|
||||
HTTP::URL altURL(prots.getIndice(i).getMember("pubaddr").asString());
|
||||
outURL.protocol = altURL.protocol;
|
||||
if (altURL.host.size()){outURL.host = altURL.host;}
|
||||
outURL.port = altURL.port;
|
||||
outURL.path = altURL.path;
|
||||
}
|
||||
/*LTS-END*/
|
||||
//and a URL - then list the URL
|
||||
JSON::Value capa_json = capa.asJSON();
|
||||
if (capa.getMember("url_rel") || capa.getMember("methods")){
|
||||
addSources(streamName, sources, host, port, capa_json, json_resp["meta"], fullHost);
|
||||
addSources(streamName, sources, outURL, capa_json, json_resp["meta"]);
|
||||
}
|
||||
//Make note if this connector can be depended upon by other connectors
|
||||
if (capa.getMember("provides")){
|
||||
|
@ -479,7 +500,7 @@ namespace Mist {
|
|||
//if it depends on this connector and has a URL, list it
|
||||
if (conns.count(capa_lst.getIndiceName(j)) && capa_lst.getIndice(j).getMember("deps").asString() == cProv && capa_lst.getIndice(j).getMember("methods")){
|
||||
JSON::Value subcapa_json = capa_lst.getIndice(j).asJSON();
|
||||
addSources(streamName, sources, host, port, subcapa_json, json_resp["meta"], fullHost, &capa_json);
|
||||
addSources(streamName, sources, outURL, subcapa_json, json_resp["meta"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -524,13 +545,18 @@ namespace Mist {
|
|||
|
||||
|
||||
if (H.url == "/player.js"){
|
||||
std::string fullHost = H.GetHeader("Host");
|
||||
HTTP::URL fullURL(H.GetHeader("Host"));
|
||||
/*LTS-START*/
|
||||
if (config->getString("pubaddr") != ""){
|
||||
HTTP::URL altURL(config->getString("pubaddr"));
|
||||
fullURL.protocol = altURL.protocol;
|
||||
if (altURL.host.size()){fullURL.host = altURL.host;}
|
||||
fullURL.port = altURL.port;
|
||||
fullURL.path = altURL.path;
|
||||
}
|
||||
/*LTS-END*/
|
||||
std::string response;
|
||||
std::string rURL = H.url;
|
||||
std::string host = H.GetHeader("Host");
|
||||
if (host.rfind(':') != std::string::npos && *host.rbegin() != ']'){
|
||||
host.resize(host.rfind(':'));
|
||||
}
|
||||
H.Clean();
|
||||
H.SetHeader("Server", "MistServer/" PACKAGE_VERSION);
|
||||
H.setCORSHeaders();
|
||||
|
@ -541,7 +567,7 @@ namespace Mist {
|
|||
return;
|
||||
}
|
||||
|
||||
response.append("if (typeof mistoptions == 'undefined') { mistoptions = {}; }\nif (!('host' in mistoptions)) { mistoptions.host = 'http://"+fullHost+"'; }\n");
|
||||
response.append("if (typeof mistoptions == 'undefined') { mistoptions = {}; }\nif (!('host' in mistoptions)) { mistoptions.host = '"+fullURL.getUrl()+"'; }\n");
|
||||
#include "core.js.h"
|
||||
response.append((char*)core_js, (size_t)core_js_len);
|
||||
jsonForEach(config->getOption("wrappers",true),it){
|
||||
|
|
Loading…
Add table
Reference in a new issue