From 35431749c431eb7b5e28d6cf4ec07157a577b67f Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 24 Dec 2020 18:59:29 +0800 Subject: [PATCH] Live: Support follow client protocol for edge. --- trunk/conf/full.conf | 5 ++++ trunk/src/app/srs_app_config.cpp | 24 +++++++++++++++++++- trunk/src/app/srs_app_config.hpp | 2 ++ trunk/src/app/srs_app_edge.cpp | 13 ++++++++++- trunk/src/protocol/srs_rtmp_stack.cpp | 6 +++++ trunk/src/protocol/srs_rtmp_stack.hpp | 6 +++++ trunk/src/protocol/srs_service_http_conn.cpp | 3 +++ 7 files changed, 57 insertions(+), 2 deletions(-) diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index e1b64f10d..70d199e4a 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -708,6 +708,11 @@ vhost cluster.srs.com { # flvs, Connect origin by HTTPS-FLV # Default: rtmp protocol rtmp; + + # Whether follow client protocol to connect to origin. + # @remark The FLV might use different signature(in query string) to RTMP. + # Default: off + follow_client off; } } diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 7e538389b..cbf710c7a 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3829,7 +3829,7 @@ srs_error_t SrsConfig::check_normal_config() for (int j = 0; j < (int)conf->directives.size(); j++) { string m = conf->at(j)->name; if (m != "mode" && m != "origin" && m != "token_traverse" && m != "vhost" && m != "debug_srs_upnode" && m != "coworkers" - && m != "origin_cluster" && m != "protocol") { + && m != "origin_cluster" && m != "protocol" && m != "follow_client") { return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.cluster.%s of %s", m.c_str(), vhost->arg0().c_str()); } } @@ -6218,6 +6218,28 @@ string SrsConfig::get_vhost_edge_protocol(string vhost) return conf->arg0(); } +bool SrsConfig::get_vhost_edge_follow_client(string vhost) +{ + static bool DEFAULT = false; + + SrsConfDirective* conf = get_vhost(vhost); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("cluster"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("follow_client"); + if (!conf) { + return DEFAULT; + } + + return SRS_CONF_PERFER_FALSE(conf->arg0()); +} + bool SrsConfig::get_vhost_edge_token_traverse(string vhost) { static bool DEFAULT = false; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 0ace96eb6..f880da403 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -775,6 +775,8 @@ public: virtual SrsConfDirective* get_vhost_edge_origin(std::string vhost); // Get the procotol to connect to origin server. virtual std::string get_vhost_edge_protocol(std::string vhost); + // Whether follow client protocol to connect to origin. + virtual bool get_vhost_edge_follow_client(std::string vhost); // Whether edge token tranverse is enabled, // If true, edge will send connect origin to verfy the token of client. // For example, we verify all clients on the origin FMS by server-side as, diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index 64fbe61fa..20b0b39ed 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -240,6 +240,8 @@ srs_error_t SrsEdgeFlvUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb) return srs_error_wrap(err, "edge get %s failed, path=%s", url.c_str(), path.c_str()); } + srs_trace("Edge: Connect to %s ok", url.c_str()); + srs_freep(reader_); reader_ = new SrsHttpFileReader(hr_->body_reader()); @@ -446,8 +448,17 @@ srs_error_t SrsEdgeIngester::do_cycle() return srs_error_wrap(err, "do cycle pull"); } - srs_freep(upstream); + // Use protocol in config. string edge_protocol = _srs_config->get_vhost_edge_protocol(req->vhost); + + // If follow client protocol, change to protocol of client. + bool follow_client = _srs_config->get_vhost_edge_follow_client(req->vhost); + if (follow_client && !req->protocol.empty()) { + edge_protocol = req->protocol; + } + + // Create object by protocol. + srs_freep(upstream); if (edge_protocol == "flv" || edge_protocol == "flvs") { upstream = new SrsEdgeFlvUpstream(edge_protocol == "flv"? "http" : "https"); } else { diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index f80cf77cd..25c0b7acc 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -1578,6 +1578,8 @@ SrsRequest::SrsRequest() duration = -1; port = SRS_CONSTS_RTMP_DEFAULT_PORT; args = NULL; + + protocol = "rtmp"; } SrsRequest::~SrsRequest() @@ -1605,6 +1607,8 @@ SrsRequest* SrsRequest::copy() if (args) { cp->args = args->copy()->to_object(); } + + cp->protocol = protocol; return cp; } @@ -1632,6 +1636,8 @@ void SrsRequest::update_auth(SrsRequest* req) if (req->args) { args = req->args->copy()->to_object(); } + + protocol = req->protocol; srs_info("update req of soruce for auth ok"); } diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index 6f311383f..2f4741fe2 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -489,6 +489,12 @@ public: public: // Transform it as HTTP request. virtual SrsRequest* as_http(); +public: + // The protocol of client: + // rtmp, Adobe RTMP protocol. + // flv, HTTP-FLV protocol. + // flvs, HTTPS-FLV protocol. + std::string protocol; }; // The response to client. diff --git a/trunk/src/protocol/srs_service_http_conn.cpp b/trunk/src/protocol/srs_service_http_conn.cpp index d239972b2..49b3defdd 100644 --- a/trunk/src/protocol/srs_service_http_conn.cpp +++ b/trunk/src/protocol/srs_service_http_conn.cpp @@ -680,6 +680,9 @@ SrsRequest* SrsHttpMessage::to_request(string vhost) if (!oip.empty()) { req->ip = oip; } + + // The request streaming protocol. + req->protocol = (schema_ == "http")? "flv" : "flvs"; return req; }