1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00
srs/trunk/src/app/srs_app_srt_utility.cpp
2022-06-14 19:58:42 +08:00

143 lines
5.1 KiB
C++

//
// Copyright (c) 2013-2021 The SRS Authors
//
// SPDX-License-Identifier: MIT or MulanPSL-2.0
//
#include <srs_app_srt_utility.hpp>
using namespace std;
#include <srs_kernel_log.hpp>
#include <srs_app_config.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_kernel_error.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_rtmp_stack.hpp>
#include <srs_kernel_utility.hpp>
// See streamid of https://github.com/ossrs/srs/issues/2893
// TODO: FIMXE: We should parse SRT streamid to URL object, rather than a HTTP url subpath.
bool srs_srt_streamid_info(const std::string& streamid, SrtMode& mode, std::string& vhost, std::string& url_subpath)
{
mode = SrtModePull;
size_t pos = streamid.find("#!::");
if (pos != 0) {
pos = streamid.find("/");
if (pos == streamid.npos) {
url_subpath = _srs_config->get_default_app_name() + "/" + streamid;
return true;
}
url_subpath = streamid;
return true;
}
//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);
// Compatible with previous auth querystring, like this one:
// srt://127.0.0.1:10080?streamid=#!::h=live/livestream?secret=xxx,m=publish
real_streamid = srs_string_replace(real_streamid, "?", ",");
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") {
std::string host = it->second;
size_t r0 = host.find("/");
size_t r1 = host.rfind("/");
if (r0 != std::string::npos && r0 != std::string::npos) {
// Compatible with previous style, see https://github.com/ossrs/srs/issues/2893#compatible
// srt://127.0.0.1:10080?streamid=#!::h=live/livestream,m=publish
// srt://127.0.0.1:10080?streamid=#!::h=live/livestream,m=request
// srt://127.0.0.1:10080?streamid=#!::h=srs.srt.com.cn/live/livestream,m=publish
if (r0 != r1) {
// We got vhost in host.
url_subpath = host.substr(r0 + 1);
host = host.substr(0, r0);
params.append("vhost=");
params.append(host);
params.append("&");
vhost = host;
} else {
// Only stream in host.
url_subpath = host;
}
} else {
// New URL style, see https://github.com/ossrs/srs/issues/2893#solution
// srt://host.com:10080?streamid=#!::h=host.com,r=app/stream,key1=value1,key2=value2
// srt://1.2.3.4:10080?streamid=#!::h=host.com,r=app/stream,key1=value1,key2=value2
// srt://1.2.3.4:10080?streamid=#!::r=app/stream,key1=value1,key2=value2
params.append("vhost=");
params.append(host);
params.append("&");
vhost = host;
}
} 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 = SrtModePush;
} else if (mode_str == "request") {
mode = SrtModePull;
} else {
srs_warn("unknown mode_str:%s", mode_str.c_str());
return false;
}
} 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;
}
bool srs_srt_streamid_to_request(const std::string& streamid, SrtMode& mode, SrsRequest* request)
{
string url_subpath = "";
bool ret = srs_srt_streamid_info(streamid, mode, request->vhost, url_subpath);
if (! ret) {
return ret;
}
size_t pos = url_subpath.find("/");
string stream_with_params = "";
if (pos == string::npos) {
request->app = _srs_config->get_default_app_name();
stream_with_params = url_subpath;
} else {
request->app = url_subpath.substr(0, pos);
stream_with_params = url_subpath.substr(pos + 1);
}
pos = stream_with_params.find("?");
if (pos == string::npos) {
request->stream = stream_with_params;
} else {
request->stream = stream_with_params.substr(0, pos);
request->param = stream_with_params.substr(pos + 1);
}
return ret;
}