Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SRT: url supports multiple QueryStrings #2908

Merged
merged 8 commits into from
Mar 19, 2022
88 changes: 47 additions & 41 deletions trunk/src/srt/srt_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "srt_log.hpp"
#include <vector>

#include <srs_protocol_utility.hpp>
#include <srs_app_config.hpp>

bool is_streamid_valid(const std::string& streamid) {
Expand All @@ -24,20 +25,18 @@ bool is_streamid_valid(const std::string& streamid) {

int mode;
std::string subpath;
std::string vhost;

bool ret = get_streamid_info(streamid, mode, subpath);
bool ret = get_streamid_info(streamid, mode, vhost, subpath);
if (!ret) {
return false;
}

if ((mode != PUSH_SRT_MODE) && (mode != PULL_SRT_MODE)) {
return false;
}

std::vector<std::string> info_vec;
string_split(subpath, "/", info_vec);

if (info_vec.size() < 2) {//it must be appname/stream at least.
if (info_vec.size() != 2) {
srt_log_warn("path format must be appname/stream?key=value...");
return false;
}

Expand Down Expand Up @@ -70,11 +69,9 @@ bool get_key_value(const std::string& info, std::string& key, std::string& value
}

//eg. streamid=#!::h:live/livestream,m:publish
bool get_streamid_info(const std::string& streamid, int& mode, std::string& url_subpath) {
std::vector<std::string> info_vec;
std::string real_streamid;
bool get_streamid_info(const std::string& streamid, int& mode, std::string& vhost, std::string& url_subpath) {

mode = PUSH_SRT_MODE;
mode = PULL_SRT_MODE;

size_t pos = streamid.find("#!::");
if (pos != 0) {
Expand All @@ -86,56 +83,65 @@ bool get_streamid_info(const std::string& streamid, int& mode, std::string& url_
url_subpath = streamid;
return true;
}
real_streamid = streamid.substr(4);

string_split(real_streamid, ",", info_vec);
if (info_vec.size() < 2) {
return false;
}

for (size_t index = 0; index < info_vec.size(); index++) {
std::string key;
std::string value;
//SRT url supports multiple QueryStrings, which are passed to RTMP to realize authentication and other capabilities
//@see https://github.com/ossrs/srs/issues/2893
std::string params;
std::string real_streamid;
real_streamid = streamid.substr(4);

bool ret = get_key_value(info_vec[index], key, value);
if (!ret) {
continue;
}

if (key == "h") {
url_subpath = value;//eg. h=live/stream
} else if (key == "m") {
std::string mode_str = string_lower(value);//m=publish or m=request
std::map<std::string, std::string> query;
srs_parse_query_string(real_streamid, query);
for (std::map<std::string, std::string>::iterator it = query.begin(); it != query.end(); ++it) {
if (it->first == "h") {
params.append("vhost=");
params.append(it->second);
params.append("&");
vhost = it->second;
} else if (it->first == "r") {
url_subpath = it->second;
} else if (it->first == "m") {
std::string mode_str = it->second; // support m=publish or m=request
std::transform(it->second.begin(), it->second.end(), mode_str.begin(), ::tolower);
if (mode_str == "publish") {
mode = PUSH_SRT_MODE;
} else if (mode_str == "request") {
} else if (mode_str == "request") {
mode = PULL_SRT_MODE;
} else {
mode = PUSH_SRT_MODE;
} else {
srt_log_warn("unknown mode_str:%s", mode_str.c_str());
return false;
}
} else {//not suport
continue;
} else {
params.append(it->first);
params.append("=");
params.append(it->second);
params.append("&");
}
}

if (url_subpath.empty())
return false;

if (!params.empty()) {
url_subpath.append("?");
url_subpath.append(params);
url_subpath.pop_back(); // remove last '&'
}

return true;
}

srt_conn::srt_conn(SRTSOCKET conn_fd, const std::string& streamid):_conn_fd(conn_fd),
_streamid(streamid),
write_fail_cnt_(0) {
get_streamid_info(streamid, _mode, _url_subpath);
get_streamid_info(streamid, _mode, _vhost, _url_subpath);

_update_timestamp = now_ms();

std::vector<std::string> path_vec;

string_split(_url_subpath, "/", path_vec);
if (path_vec.size() >= 3) {
_vhost = path_vec[0];
} else {

if (_vhost.empty()) {
_vhost = "__default_host__";
}

srt_log_trace("srt connect construct streamid:%s, mode:%d, subpath:%s, vhost:%s",
streamid.c_str(), _mode, _url_subpath.c_str(), _vhost.c_str());
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/srt/srt_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

bool is_streamid_valid(const std::string& streamid);
bool get_key_value(const std::string& info, std::string& key, std::string& value);
bool get_streamid_info(const std::string& streamid, int& mode, std::string& url_subpash);
bool get_streamid_info(const std::string& streamid, int& mode, std::string& vhost, std::string& url_subpash);
winlinvip marked this conversation as resolved.
Show resolved Hide resolved

class srt_conn {
public:
Expand Down
14 changes: 4 additions & 10 deletions trunk/src/srt/srt_handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,24 +336,18 @@ void srt_handle::handle_pull_data(SRT_SOCKSTATUS status, const std::string& subp

void srt_handle::handle_srt_socket(SRT_SOCKSTATUS status, SRTSOCKET conn_fd)
{
std::string subpath;
int mode;
auto conn_ptr = get_srt_conn(conn_fd);

if (!conn_ptr) {
if (status != SRTS_CLOSED) {
srt_log_error("handle_srt_socket find srt connection error, fd:%d, status:%d",
conn_fd, status);
}
return;
}
bool ret = get_streamid_info(conn_ptr->get_streamid(), mode, subpath);
if (!ret) {
conn_ptr->close();
conn_ptr = nullptr;
return;
}


std::string subpath = conn_ptr->get_subpath();

int mode = conn_ptr->get_mode();
if (mode == PUSH_SRT_MODE) {
switch (status)
{
Expand Down