From 27cb62b7aa4a9f55328a8dfac59169edf120e8d2 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 14 Mar 2015 19:45:13 +0800 Subject: [PATCH] for #324, support hstrs(http stream trigger rtmp source) origin mode. 2.0.139. --- README.md | 5 +- trunk/src/app/srs_app_http.cpp | 28 +++++++++++ trunk/src/app/srs_app_http.hpp | 6 +++ trunk/src/app/srs_app_http_conn.cpp | 75 +++++++++++++++++++++++++++-- trunk/src/app/srs_app_http_conn.hpp | 4 +- trunk/src/app/srs_app_rtmp_conn.cpp | 14 +++--- trunk/src/app/srs_app_server.cpp | 2 +- trunk/src/core/srs_core.hpp | 2 +- 8 files changed, 123 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 25b8e61bd..c2bc75bb3 100755 --- a/README.md +++ b/README.md @@ -21,7 +21,9 @@ Download from ossrs.net: RTSP/MPEGTS-over-UDP. 1. Popular internet delivery: RTMP/HDS for flash, HLS for mobile(IOS/IPad/MAC/Android), HTTP flv/ts/mp3/aac streaming for user prefered. -1. Enhanced DVR: segment/session/append plan, customer path and HTTP callback. +1. Enhanced DVR and hstrs: segment/session/append plan, customer path and HTTP callback. +the hstrs(http stream trigger rtmp source) enable the http-flv stream standby util encoder +start publish, similar to rtmp, which will trigger edge to fetch from origin. 1. Multiple feature: transcode, forward, ingest, http hooks, dvr, hls, rtsp, http streaming, http api, refer, log, bandwith test and srs-librtmp. 1. Best maintainess: simple arch over state-threads(coroutine), single thread, single process @@ -558,6 +560,7 @@ Supported operating systems and hardware: ### SRS 2.0 history +* v2.0, 2015-03-14, for [#324](https://github.com/winlinvip/simple-rtmp-server/issues/324), support hstrs(http stream trigger rtmp source) origin mode. 2.0.139. * v2.0, 2015-03-12, fix [#328](https://github.com/winlinvip/simple-rtmp-server/issues/328), support adobe hds. 2.0.138. * v2.0, 2015-03-10, fix [#155](https://github.com/winlinvip/simple-rtmp-server/issues/155), support osx(darwin) for mac pro. 2.0.137. * v2.0, 2015-03-08, fix [#316](https://github.com/winlinvip/simple-rtmp-server/issues/316), http api provides stream/vhost/srs/server bytes, codec and count. 2.0.136. diff --git a/trunk/src/app/srs_app_http.cpp b/trunk/src/app/srs_app_http.cpp index d156c6ce3..0de1a7e66 100644 --- a/trunk/src/app/srs_app_http.cpp +++ b/trunk/src/app/srs_app_http.cpp @@ -40,6 +40,8 @@ using namespace std; #include #include #include +#include +#include #define SRS_DEFAULT_HTTP_PORT 80 @@ -1286,6 +1288,32 @@ string SrsHttpMessage::get_request_header(string name) return ""; } +SrsRequest* SrsHttpMessage::to_request(string vhost) +{ + SrsRequest* req = new SrsRequest(); + + req->app = _uri->get_path(); + ssize_t pos = string::npos; + if ((pos = req->app.rfind("/")) != string::npos) { + req->stream = req->app.substr(pos + 1); + req->app = req->app.substr(0, pos); + } + if ((pos = req->stream.rfind(".")) != string::npos) { + req->stream = req->stream.substr(0, pos); + } + + req->tcUrl = "rtmp://" + vhost + req->app; + req->pageUrl = get_request_header("Referer"); + req->objectEncoding = 0; + + srs_discovery_tc_url(req->tcUrl, + req->schema, req->host, req->vhost, req->app, req->port, + req->param); + req->strip(); + + return req; +} + SrsHttpParser::SrsHttpParser() { buffer = new SrsFastBuffer(); diff --git a/trunk/src/app/srs_app_http.hpp b/trunk/src/app/srs_app_http.hpp index c056cb2dd..5bacb1ea8 100644 --- a/trunk/src/app/srs_app_http.hpp +++ b/trunk/src/app/srs_app_http.hpp @@ -565,6 +565,12 @@ public: virtual std::string request_header_key_at(int index); virtual std::string request_header_value_at(int index); virtual std::string get_request_header(std::string name); +public: + /** + * convert the http message to a request. + * @remark user must free the return request. + */ + virtual SrsRequest* to_request(std::string vhost); }; /** diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp index 33dcd4143..2567719bd 100644 --- a/trunk/src/app/srs_app_http_conn.cpp +++ b/trunk/src/app/srs_app_http_conn.cpp @@ -48,6 +48,8 @@ using namespace std; #include #include #include +#include +#include SrsVodStream::SrsVodStream(string root_dir) : SrsHttpFileServer(root_dir) @@ -796,8 +798,10 @@ SrsHlsEntry::SrsHlsEntry() { } -SrsHttpServer::SrsHttpServer() +SrsHttpServer::SrsHttpServer(SrsServer* svr) { + server = svr; + mux.hijack(this); } @@ -1110,11 +1114,76 @@ int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) if (ext.empty()) { return ret; } - if (ext != ".flv" && ext != ".ts" && ext != ".mp3" && ext != ".aac") { + + // find the actually request vhost. + SrsConfDirective* vhost = _srs_config->get_vhost(request->host()); + if (!vhost || !_srs_config->get_vhost_enabled(vhost)) { return ret; } - // TODO: FIXME: implements it. + // find the entry template for the stream. + SrsLiveEntry* entry = NULL; + if (true) { + // no http streaming on vhost, ignore. + std::map::iterator it = tflvs.find(vhost->arg0()); + if (it == tflvs.end()) { + return ret; + } + + // hstrs not enabled, ignore. + entry = it->second; + if (!entry->hstrs) { + return ret; + } + + // check entry and request extension. + if (entry->is_flv()) { + if (ext != ".flv") { + return ret; + } + } else if (entry->is_ts()) { + if (ext != ".ts") { + return ret; + } + } else if (entry->is_mp3()) { + if (ext != ".mp3") { + return ret; + } + } else if (entry->is_aac()) { + if (ext != ".aac") { + return ret; + } + } else { + return ret; + } + } + + // hijack for entry. + SrsRequest* r = request->to_request(vhost->arg0()); + SrsAutoFree(SrsRequest, r); + SrsSource* s = SrsSource::fetch(r); + if (!s) { + if ((ret = SrsSource::create(r, server, server, &s)) != ERROR_SUCCESS) { + return ret; + } + } + srs_assert(s != NULL); + + // create http streaming handler. + if ((ret = http_mount(s, r)) != ERROR_SUCCESS) { + return ret; + } + + // use the handler if exists. + if (ph) { + std::string sid = r->get_stream_url(); + if (sflvs.find(sid) != sflvs.end()) { + entry = sflvs[sid]; + *ph = entry->stream; + srs_trace("hstrs sid=%s", sid.c_str()); + } + } + return ret; } diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index 6d4b02672..9cb803365 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -330,6 +330,8 @@ struct SrsHlsEntry class SrsHttpServer : virtual public ISrsReloadHandler , virtual public ISrsHttpMatchHijacker { +private: + SrsServer* server; public: SrsHttpServeMux mux; // the http live streaming template, to create streams. @@ -341,7 +343,7 @@ public: // the hls live streaming streams, crote by template. std::map shls; public: - SrsHttpServer(); + SrsHttpServer(SrsServer* svr); virtual ~SrsHttpServer(); public: virtual int initialize(); diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 8ddeeac6e..f887bfceb 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -296,12 +296,14 @@ int SrsRtmpConn::service_cycle() // do token traverse before serve it. // @see https://github.com/winlinvip/simple-rtmp-server/pull/239 - bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost); - bool edge_traverse = _srs_config->get_vhost_edge_token_traverse(req->vhost); - if (vhost_is_edge && edge_traverse) { - if ((ret = check_edge_token_traverse_auth()) != ERROR_SUCCESS) { - srs_warn("token auth failed, ret=%d", ret); - return ret; + if (true) { + bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost); + bool edge_traverse = _srs_config->get_vhost_edge_token_traverse(req->vhost); + if (vhost_is_edge && edge_traverse) { + if ((ret = check_edge_token_traverse_auth()) != ERROR_SUCCESS) { + srs_warn("token auth failed, ret=%d", ret); + return ret; + } } } diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 5bcbba897..6aaf07539 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -401,7 +401,7 @@ SrsServer::SrsServer() http_api_mux = new SrsHttpServeMux(); #endif #ifdef SRS_AUTO_HTTP_SERVER - http_stream_mux = new SrsHttpServer(); + http_stream_mux = new SrsHttpServer(this); #endif #ifdef SRS_AUTO_HTTP_PARSER http_heartbeat = NULL; diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 643d4936f..0c0c85d5d 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR 2 #define VERSION_MINOR 0 -#define VERSION_REVISION 138 +#define VERSION_REVISION 139 // server info. #define RTMP_SIG_SRS_KEY "SRS"