winlin

for #324, support hstrs(http stream trigger rtmp source) origin mode. 2.0.139.

@@ -21,7 +21,9 @@ Download from ossrs.net: @@ -21,7 +21,9 @@ Download from ossrs.net:
21 RTSP/MPEGTS-over-UDP. 21 RTSP/MPEGTS-over-UDP.
22 1. Popular internet delivery: RTMP/HDS for flash, HLS for mobile(IOS/IPad/MAC/Android), HTTP 22 1. Popular internet delivery: RTMP/HDS for flash, HLS for mobile(IOS/IPad/MAC/Android), HTTP
23 flv/ts/mp3/aac streaming for user prefered. 23 flv/ts/mp3/aac streaming for user prefered.
24 -1. Enhanced DVR: segment/session/append plan, customer path and HTTP callback. 24 +1. Enhanced DVR and hstrs: segment/session/append plan, customer path and HTTP callback.
  25 +the hstrs(http stream trigger rtmp source) enable the http-flv stream standby util encoder
  26 +start publish, similar to rtmp, which will trigger edge to fetch from origin.
25 1. Multiple feature: transcode, forward, ingest, http hooks, dvr, hls, rtsp, http streaming, 27 1. Multiple feature: transcode, forward, ingest, http hooks, dvr, hls, rtsp, http streaming,
26 http api, refer, log, bandwith test and srs-librtmp. 28 http api, refer, log, bandwith test and srs-librtmp.
27 1. Best maintainess: simple arch over state-threads(coroutine), single thread, single process 29 1. Best maintainess: simple arch over state-threads(coroutine), single thread, single process
@@ -558,6 +560,7 @@ Supported operating systems and hardware: @@ -558,6 +560,7 @@ Supported operating systems and hardware:
558 560
559 ### SRS 2.0 history 561 ### SRS 2.0 history
560 562
  563 +* 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.
561 * v2.0, 2015-03-12, fix [#328](https://github.com/winlinvip/simple-rtmp-server/issues/328), support adobe hds. 2.0.138. 564 * v2.0, 2015-03-12, fix [#328](https://github.com/winlinvip/simple-rtmp-server/issues/328), support adobe hds. 2.0.138.
562 * 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. 565 * 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.
563 * 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. 566 * 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.
@@ -40,6 +40,8 @@ using namespace std; @@ -40,6 +40,8 @@ using namespace std;
40 #include <srs_kernel_file.hpp> 40 #include <srs_kernel_file.hpp>
41 #include <srs_core_autofree.hpp> 41 #include <srs_core_autofree.hpp>
42 #include <srs_rtmp_buffer.hpp> 42 #include <srs_rtmp_buffer.hpp>
  43 +#include <srs_rtmp_sdk.hpp>
  44 +#include <srs_rtmp_utility.hpp>
43 45
44 #define SRS_DEFAULT_HTTP_PORT 80 46 #define SRS_DEFAULT_HTTP_PORT 80
45 47
@@ -1286,6 +1288,32 @@ string SrsHttpMessage::get_request_header(string name) @@ -1286,6 +1288,32 @@ string SrsHttpMessage::get_request_header(string name)
1286 return ""; 1288 return "";
1287 } 1289 }
1288 1290
  1291 +SrsRequest* SrsHttpMessage::to_request(string vhost)
  1292 +{
  1293 + SrsRequest* req = new SrsRequest();
  1294 +
  1295 + req->app = _uri->get_path();
  1296 + ssize_t pos = string::npos;
  1297 + if ((pos = req->app.rfind("/")) != string::npos) {
  1298 + req->stream = req->app.substr(pos + 1);
  1299 + req->app = req->app.substr(0, pos);
  1300 + }
  1301 + if ((pos = req->stream.rfind(".")) != string::npos) {
  1302 + req->stream = req->stream.substr(0, pos);
  1303 + }
  1304 +
  1305 + req->tcUrl = "rtmp://" + vhost + req->app;
  1306 + req->pageUrl = get_request_header("Referer");
  1307 + req->objectEncoding = 0;
  1308 +
  1309 + srs_discovery_tc_url(req->tcUrl,
  1310 + req->schema, req->host, req->vhost, req->app, req->port,
  1311 + req->param);
  1312 + req->strip();
  1313 +
  1314 + return req;
  1315 +}
  1316 +
1289 SrsHttpParser::SrsHttpParser() 1317 SrsHttpParser::SrsHttpParser()
1290 { 1318 {
1291 buffer = new SrsFastBuffer(); 1319 buffer = new SrsFastBuffer();
@@ -565,6 +565,12 @@ public: @@ -565,6 +565,12 @@ public:
565 virtual std::string request_header_key_at(int index); 565 virtual std::string request_header_key_at(int index);
566 virtual std::string request_header_value_at(int index); 566 virtual std::string request_header_value_at(int index);
567 virtual std::string get_request_header(std::string name); 567 virtual std::string get_request_header(std::string name);
  568 +public:
  569 + /**
  570 + * convert the http message to a request.
  571 + * @remark user must free the return request.
  572 + */
  573 + virtual SrsRequest* to_request(std::string vhost);
568 }; 574 };
569 575
570 /** 576 /**
@@ -48,6 +48,8 @@ using namespace std; @@ -48,6 +48,8 @@ using namespace std;
48 #include <srs_kernel_mp3.hpp> 48 #include <srs_kernel_mp3.hpp>
49 #include <srs_kernel_ts.hpp> 49 #include <srs_kernel_ts.hpp>
50 #include <srs_app_pithy_print.hpp> 50 #include <srs_app_pithy_print.hpp>
  51 +#include <srs_app_source.hpp>
  52 +#include <srs_app_server.hpp>
51 53
52 SrsVodStream::SrsVodStream(string root_dir) 54 SrsVodStream::SrsVodStream(string root_dir)
53 : SrsHttpFileServer(root_dir) 55 : SrsHttpFileServer(root_dir)
@@ -796,8 +798,10 @@ SrsHlsEntry::SrsHlsEntry() @@ -796,8 +798,10 @@ SrsHlsEntry::SrsHlsEntry()
796 { 798 {
797 } 799 }
798 800
799 -SrsHttpServer::SrsHttpServer() 801 +SrsHttpServer::SrsHttpServer(SrsServer* svr)
800 { 802 {
  803 + server = svr;
  804 +
801 mux.hijack(this); 805 mux.hijack(this);
802 } 806 }
803 807
@@ -1110,11 +1114,76 @@ int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) @@ -1110,11 +1114,76 @@ int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph)
1110 if (ext.empty()) { 1114 if (ext.empty()) {
1111 return ret; 1115 return ret;
1112 } 1116 }
1113 - if (ext != ".flv" && ext != ".ts" && ext != ".mp3" && ext != ".aac") { 1117 +
  1118 + // find the actually request vhost.
  1119 + SrsConfDirective* vhost = _srs_config->get_vhost(request->host());
  1120 + if (!vhost || !_srs_config->get_vhost_enabled(vhost)) {
1114 return ret; 1121 return ret;
1115 } 1122 }
1116 1123
1117 - // TODO: FIXME: implements it. 1124 + // find the entry template for the stream.
  1125 + SrsLiveEntry* entry = NULL;
  1126 + if (true) {
  1127 + // no http streaming on vhost, ignore.
  1128 + std::map<std::string, SrsLiveEntry*>::iterator it = tflvs.find(vhost->arg0());
  1129 + if (it == tflvs.end()) {
  1130 + return ret;
  1131 + }
  1132 +
  1133 + // hstrs not enabled, ignore.
  1134 + entry = it->second;
  1135 + if (!entry->hstrs) {
  1136 + return ret;
  1137 + }
  1138 +
  1139 + // check entry and request extension.
  1140 + if (entry->is_flv()) {
  1141 + if (ext != ".flv") {
  1142 + return ret;
  1143 + }
  1144 + } else if (entry->is_ts()) {
  1145 + if (ext != ".ts") {
  1146 + return ret;
  1147 + }
  1148 + } else if (entry->is_mp3()) {
  1149 + if (ext != ".mp3") {
  1150 + return ret;
  1151 + }
  1152 + } else if (entry->is_aac()) {
  1153 + if (ext != ".aac") {
  1154 + return ret;
  1155 + }
  1156 + } else {
  1157 + return ret;
  1158 + }
  1159 + }
  1160 +
  1161 + // hijack for entry.
  1162 + SrsRequest* r = request->to_request(vhost->arg0());
  1163 + SrsAutoFree(SrsRequest, r);
  1164 + SrsSource* s = SrsSource::fetch(r);
  1165 + if (!s) {
  1166 + if ((ret = SrsSource::create(r, server, server, &s)) != ERROR_SUCCESS) {
  1167 + return ret;
  1168 + }
  1169 + }
  1170 + srs_assert(s != NULL);
  1171 +
  1172 + // create http streaming handler.
  1173 + if ((ret = http_mount(s, r)) != ERROR_SUCCESS) {
  1174 + return ret;
  1175 + }
  1176 +
  1177 + // use the handler if exists.
  1178 + if (ph) {
  1179 + std::string sid = r->get_stream_url();
  1180 + if (sflvs.find(sid) != sflvs.end()) {
  1181 + entry = sflvs[sid];
  1182 + *ph = entry->stream;
  1183 + srs_trace("hstrs sid=%s", sid.c_str());
  1184 + }
  1185 + }
  1186 +
1118 return ret; 1187 return ret;
1119 } 1188 }
1120 1189
@@ -330,6 +330,8 @@ struct SrsHlsEntry @@ -330,6 +330,8 @@ struct SrsHlsEntry
330 class SrsHttpServer : virtual public ISrsReloadHandler 330 class SrsHttpServer : virtual public ISrsReloadHandler
331 , virtual public ISrsHttpMatchHijacker 331 , virtual public ISrsHttpMatchHijacker
332 { 332 {
  333 +private:
  334 + SrsServer* server;
333 public: 335 public:
334 SrsHttpServeMux mux; 336 SrsHttpServeMux mux;
335 // the http live streaming template, to create streams. 337 // the http live streaming template, to create streams.
@@ -341,7 +343,7 @@ public: @@ -341,7 +343,7 @@ public:
341 // the hls live streaming streams, crote by template. 343 // the hls live streaming streams, crote by template.
342 std::map<std::string, SrsHlsEntry*> shls; 344 std::map<std::string, SrsHlsEntry*> shls;
343 public: 345 public:
344 - SrsHttpServer(); 346 + SrsHttpServer(SrsServer* svr);
345 virtual ~SrsHttpServer(); 347 virtual ~SrsHttpServer();
346 public: 348 public:
347 virtual int initialize(); 349 virtual int initialize();
@@ -296,6 +296,7 @@ int SrsRtmpConn::service_cycle() @@ -296,6 +296,7 @@ int SrsRtmpConn::service_cycle()
296 296
297 // do token traverse before serve it. 297 // do token traverse before serve it.
298 // @see https://github.com/winlinvip/simple-rtmp-server/pull/239 298 // @see https://github.com/winlinvip/simple-rtmp-server/pull/239
  299 + if (true) {
299 bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost); 300 bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost);
300 bool edge_traverse = _srs_config->get_vhost_edge_token_traverse(req->vhost); 301 bool edge_traverse = _srs_config->get_vhost_edge_token_traverse(req->vhost);
301 if (vhost_is_edge && edge_traverse) { 302 if (vhost_is_edge && edge_traverse) {
@@ -304,6 +305,7 @@ int SrsRtmpConn::service_cycle() @@ -304,6 +305,7 @@ int SrsRtmpConn::service_cycle()
304 return ret; 305 return ret;
305 } 306 }
306 } 307 }
  308 + }
307 309
308 // response the client connect ok. 310 // response the client connect ok.
309 if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) { 311 if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) {
@@ -401,7 +401,7 @@ SrsServer::SrsServer() @@ -401,7 +401,7 @@ SrsServer::SrsServer()
401 http_api_mux = new SrsHttpServeMux(); 401 http_api_mux = new SrsHttpServeMux();
402 #endif 402 #endif
403 #ifdef SRS_AUTO_HTTP_SERVER 403 #ifdef SRS_AUTO_HTTP_SERVER
404 - http_stream_mux = new SrsHttpServer(); 404 + http_stream_mux = new SrsHttpServer(this);
405 #endif 405 #endif
406 #ifdef SRS_AUTO_HTTP_PARSER 406 #ifdef SRS_AUTO_HTTP_PARSER
407 http_heartbeat = NULL; 407 http_heartbeat = NULL;
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 138 34 +#define VERSION_REVISION 139
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"