diff --git a/README.md b/README.md index 19910903f7..52d166fce5 100755 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ Please select according to languages: ### V3 changes +* v3.0, 2018-08-11, For [#910][bug #910], Support HTTP FLV with HTTP callback. 3.0.39 * v3.0, 2018-08-05, Refine HTTP-FLV latency, support realtime mode.3.0.38 * v3.0, 2018-08-05, Fix [#1087][bug #1087], Ignore iface without address. 3.0.37 * v3.0, 2018-08-04, For [#1110][bug #1110], Support params in http callback. 3.0.36 @@ -229,6 +230,7 @@ Please select according to languages: ### V2 changes +* v2.0, 2018-08-11, For [#910][bug #910], Support HTTP FLV with HTTP callback. 2.0.254 * v2.0, 2018-08-11, For [#1110][bug #1110], Refine params in http callback. 2.0.253 * v2.0, 2018-08-05, Refine HTTP-FLV latency, support realtime mode. 2.0.252 * v2.0, 2018-08-04, For [#1110][bug #1110], Support params in http callback. 2.0.251 @@ -1443,6 +1445,7 @@ Winlin [bug #1119]: https://github.com/ossrs/srs/issues/1119 [bug #1031]: https://github.com/ossrs/srs/issues/1031 [bug #1110]: https://github.com/ossrs/srs/issues/1110 +[bug #910]: https://github.com/ossrs/srs/issues/910 [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx [bug #735]: https://github.com/ossrs/srs/issues/735 diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index 7c16da63e9..865f2e2cfb 100755 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -54,10 +54,11 @@ using namespace std; #include #include #include +#include SrsBufferCache::SrsBufferCache(SrsSource* s, SrsRequest* r) { - req = r->copy(); + req = r->copy()->as_http(); source = s; queue = new SrsMessageQueue(true); trd = new SrsSTCoroutine("http-stream", this); @@ -466,7 +467,7 @@ SrsLiveStream::SrsLiveStream(SrsSource* s, SrsRequest* r, SrsBufferCache* c) { source = s; cache = c; - req = r->copy(); + req = r->copy()->as_http(); } SrsLiveStream::~SrsLiveStream() @@ -476,9 +477,10 @@ SrsLiveStream::~SrsLiveStream() srs_error_t SrsLiveStream::update(SrsSource* s, SrsRequest* r) { - srs_freep(req); source = s; - req = r->copy(); + + srs_freep(req); + req = r->copy()->as_http(); return srs_success; } @@ -487,6 +489,21 @@ srs_error_t SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage { srs_error_t err = srs_success; + if ((err = http_hooks_on_play()) != srs_success) { + return srs_error_wrap(err, "http hook"); + } + + err = do_serve_http(w, r); + + http_hooks_on_stop(); + + return err; +} + +srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) +{ + srs_error_t err = srs_success; + string enc_desc; ISrsBufferEncoder* enc = NULL; @@ -641,6 +658,69 @@ srs_error_t SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage return err; } +srs_error_t SrsLiveStream::http_hooks_on_play() +{ + srs_error_t err = srs_success; + + if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) { + return err; + } + + // the http hooks will cause context switch, + // so we must copy all hooks for the on_connect may freed. + // @see https://github.com/ossrs/srs/issues/475 + vector hooks; + + if (true) { + SrsConfDirective* conf = _srs_config->get_vhost_on_play(req->vhost); + + if (!conf) { + return err; + } + + hooks = conf->args; + } + + for (int i = 0; i < (int)hooks.size(); i++) { + std::string url = hooks.at(i); + if ((err = SrsHttpHooks::on_play(url, req)) != srs_success) { + return srs_error_wrap(err, "rtmp on_play %s", url.c_str()); + } + } + + return err; +} + +void SrsLiveStream::http_hooks_on_stop() +{ + if (!_srs_config->get_vhost_http_hooks_enabled(req->vhost)) { + return; + } + + // the http hooks will cause context switch, + // so we must copy all hooks for the on_connect may freed. + // @see https://github.com/ossrs/srs/issues/475 + vector hooks; + + if (true) { + SrsConfDirective* conf = _srs_config->get_vhost_on_stop(req->vhost); + + if (!conf) { + srs_info("ignore the empty http callback: on_stop"); + return; + } + + hooks = conf->args; + } + + for (int i = 0; i < (int)hooks.size(); i++) { + std::string url = hooks.at(i); + SrsHttpHooks::on_stop(url, req); + } + + return; +} + srs_error_t SrsLiveStream::streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs) { srs_error_t err = srs_success; @@ -786,7 +866,7 @@ srs_error_t SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r) srs_freep(tmpl->req); tmpl->source = s; - tmpl->req = r->copy(); + tmpl->req = r->copy()->as_http(); sflvs[sid] = entry; diff --git a/trunk/src/app/srs_app_http_stream.hpp b/trunk/src/app/srs_app_http_stream.hpp index 128bcaaa00..02de95f642 100755 --- a/trunk/src/app/srs_app_http_stream.hpp +++ b/trunk/src/app/srs_app_http_stream.hpp @@ -228,6 +228,9 @@ class SrsLiveStream : public ISrsHttpHandler public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); private: + virtual srs_error_t do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); + virtual srs_error_t http_hooks_on_play(); + virtual void http_hooks_on_stop(); virtual srs_error_t streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs); }; diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index dd60634c7f..98ae270283 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // current release version #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 38 +#define VERSION_REVISION 39 // generated by configure, only macros. #include diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index 11ee6486c6..402875f353 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -113,6 +113,11 @@ void srs_discovery_tc_url(string tcUrl, string& schema, string& host, string& vh vhost = host; srs_vhost_resolve(vhost, app, param); srs_vhost_resolve(vhost, stream, param); + + // Ignore when the param only contains the default vhost. + if (param == "?vhost="SRS_CONSTS_RTMP_DEFAULT_VHOST) { + param = ""; + } } void srs_parse_query_string(string q, map& query) diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index 683c726535..acd590fbef 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -1624,6 +1624,12 @@ void SrsRequest::strip() stream = srs_string_trim_start(stream, "/"); } +SrsRequest* SrsRequest::as_http() +{ + schema = "http"; + return this; +} + SrsResponse::SrsResponse() { stream_id = SRS_DEFAULT_SID; diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index ed1947457c..8840b72a54 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -602,6 +602,9 @@ class SrsRequest * strip url, user must strip when update the url. */ virtual void strip(); +public: + // Transform it as HTTP request. + virtual SrsRequest* as_http(); }; /**