winlin

for #324, refine code for hstrs, support hijack handler.

@@ -495,6 +495,14 @@ SrsHttpMuxEntry::~SrsHttpMuxEntry() @@ -495,6 +495,14 @@ SrsHttpMuxEntry::~SrsHttpMuxEntry()
495 srs_freep(handler); 495 srs_freep(handler);
496 } 496 }
497 497
  498 +ISrsHttpMatchHijacker::ISrsHttpMatchHijacker()
  499 +{
  500 +}
  501 +
  502 +ISrsHttpMatchHijacker::~ISrsHttpMatchHijacker()
  503 +{
  504 +}
  505 +
498 SrsHttpServeMux::SrsHttpServeMux() 506 SrsHttpServeMux::SrsHttpServeMux()
499 { 507 {
500 } 508 }
@@ -509,6 +517,7 @@ SrsHttpServeMux::~SrsHttpServeMux() @@ -509,6 +517,7 @@ SrsHttpServeMux::~SrsHttpServeMux()
509 entries.clear(); 517 entries.clear();
510 518
511 vhosts.clear(); 519 vhosts.clear();
  520 + hijackers.clear();
512 } 521 }
513 522
514 int SrsHttpServeMux::initialize() 523 int SrsHttpServeMux::initialize()
@@ -518,6 +527,24 @@ int SrsHttpServeMux::initialize() @@ -518,6 +527,24 @@ int SrsHttpServeMux::initialize()
518 return ret; 527 return ret;
519 } 528 }
520 529
  530 +void SrsHttpServeMux::hijack(ISrsHttpMatchHijacker* h)
  531 +{
  532 + std::vector<ISrsHttpMatchHijacker*>::iterator it = ::find(hijackers.begin(), hijackers.end(), h);
  533 + if (it != hijackers.end()) {
  534 + return;
  535 + }
  536 + hijackers.push_back(h);
  537 +}
  538 +
  539 +void SrsHttpServeMux::unhijack(ISrsHttpMatchHijacker* h)
  540 +{
  541 + std::vector<ISrsHttpMatchHijacker*>::iterator it = ::find(hijackers.begin(), hijackers.end(), h);
  542 + if (it == hijackers.end()) {
  543 + return;
  544 + }
  545 + hijackers.erase(it);
  546 +}
  547 +
521 int SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler* handler) 548 int SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler* handler)
522 { 549 {
523 int ret = ERROR_SUCCESS; 550 int ret = ERROR_SUCCESS;
@@ -630,7 +657,21 @@ int SrsHttpServeMux::find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph) @@ -630,7 +657,21 @@ int SrsHttpServeMux::find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph)
630 return ret; 657 return ret;
631 } 658 }
632 659
  660 + // always hijack.
  661 + if (!hijackers.empty()) {
  662 + // notice all hijacker the match failed.
  663 + std::vector<ISrsHttpMatchHijacker*>::iterator it;
  664 + for (it = hijackers.begin(); it != hijackers.end(); ++it) {
  665 + ISrsHttpMatchHijacker* hijacker = *it;
  666 + if ((ret = hijacker->hijack(r, ph)) != ERROR_SUCCESS) {
  667 + srs_error("hijacker match failed. ret=%d", ret);
  668 + return ret;
  669 + }
  670 + }
  671 + }
  672 +
633 if (*ph == NULL) { 673 if (*ph == NULL) {
  674 + // TODO: FIXME: memory leak.
634 *ph = new SrsHttpNotFoundHandler(); 675 *ph = new SrsHttpNotFoundHandler();
635 } 676 }
636 677
@@ -1066,6 +1107,14 @@ int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body, @@ -1066,6 +1107,14 @@ int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body,
1066 _query[k] = v; 1107 _query[k] = v;
1067 } 1108 }
1068 1109
  1110 + // parse ext.
  1111 + _ext = _uri->get_path();
  1112 + if ((pos = _ext.rfind(".")) != string::npos) {
  1113 + _ext = _ext.substr(pos);
  1114 + } else {
  1115 + _ext = "";
  1116 + }
  1117 +
1069 return ret; 1118 return ret;
1070 } 1119 }
1071 1120
@@ -1162,6 +1211,11 @@ string SrsHttpMessage::path() @@ -1162,6 +1211,11 @@ string SrsHttpMessage::path()
1162 return _uri->get_path(); 1211 return _uri->get_path();
1163 } 1212 }
1164 1213
  1214 +string SrsHttpMessage::ext()
  1215 +{
  1216 + return _ext;
  1217 +}
  1218 +
1165 int SrsHttpMessage::body_read_all(string& body) 1219 int SrsHttpMessage::body_read_all(string& body)
1166 { 1220 {
1167 int ret = ERROR_SUCCESS; 1221 int ret = ERROR_SUCCESS;
@@ -288,6 +288,7 @@ protected: @@ -288,6 +288,7 @@ protected:
288 }; 288 };
289 289
290 // the mux entry for server mux. 290 // the mux entry for server mux.
  291 +// the matcher info, for example, the pattern and handler.
291 class SrsHttpMuxEntry 292 class SrsHttpMuxEntry
292 { 293 {
293 public: 294 public:
@@ -300,6 +301,23 @@ public: @@ -300,6 +301,23 @@ public:
300 virtual ~SrsHttpMuxEntry(); 301 virtual ~SrsHttpMuxEntry();
301 }; 302 };
302 303
  304 +/**
  305 +* the hijacker for http pattern match.
  306 +*/
  307 +class ISrsHttpMatchHijacker
  308 +{
  309 +public:
  310 + ISrsHttpMatchHijacker();
  311 + virtual ~ISrsHttpMatchHijacker();
  312 +public:
  313 + /**
  314 + * when match the request failed, no handler to process request.
  315 + * @param request the http request message to match the handler.
  316 + * @param ph the already matched handler, hijack can rewrite it.
  317 + */
  318 + virtual int hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) = 0;
  319 +};
  320 +
303 // ServeMux is an HTTP request multiplexer. 321 // ServeMux is an HTTP request multiplexer.
304 // It matches the URL of each incoming request against a list of registered 322 // It matches the URL of each incoming request against a list of registered
305 // patterns and calls the handler for the pattern that 323 // patterns and calls the handler for the pattern that
@@ -338,6 +356,10 @@ private: @@ -338,6 +356,10 @@ private:
338 // for example, for pattern /live/livestream.flv of vhost ossrs.net, 356 // for example, for pattern /live/livestream.flv of vhost ossrs.net,
339 // the path will rewrite to ossrs.net/live/livestream.flv 357 // the path will rewrite to ossrs.net/live/livestream.flv
340 std::map<std::string, ISrsHttpHandler*> vhosts; 358 std::map<std::string, ISrsHttpHandler*> vhosts;
  359 + // all hijackers for http match.
  360 + // for example, the hstrs(http stream trigger rtmp source)
  361 + // can hijack and install handler when request incoming and no handler.
  362 + std::vector<ISrsHttpMatchHijacker*> hijackers;
341 public: 363 public:
342 SrsHttpServeMux(); 364 SrsHttpServeMux();
343 virtual ~SrsHttpServeMux(); 365 virtual ~SrsHttpServeMux();
@@ -346,6 +368,11 @@ public: @@ -346,6 +368,11 @@ public:
346 * initialize the http serve mux. 368 * initialize the http serve mux.
347 */ 369 */
348 virtual int initialize(); 370 virtual int initialize();
  371 + /**
  372 + * hijack the http match.
  373 + */
  374 + virtual void hijack(ISrsHttpMatchHijacker* h);
  375 + virtual void unhijack(ISrsHttpMatchHijacker* h);
349 public: 376 public:
350 // Handle registers the handler for the given pattern. 377 // Handle registers the handler for the given pattern.
351 // If a handler already exists for pattern, Handle panics. 378 // If a handler already exists for pattern, Handle panics.
@@ -442,6 +469,10 @@ private: @@ -442,6 +469,10 @@ private:
442 */ 469 */
443 std::string _url; 470 std::string _url;
444 /** 471 /**
  472 + * the extension of file, for example, .flv
  473 + */
  474 + std::string _ext;
  475 + /**
445 * parsed http header. 476 * parsed http header.
446 */ 477 */
447 http_parser _header; 478 http_parser _header;
@@ -505,6 +536,7 @@ public: @@ -505,6 +536,7 @@ public:
505 virtual std::string url(); 536 virtual std::string url();
506 virtual std::string host(); 537 virtual std::string host();
507 virtual std::string path(); 538 virtual std::string path();
  539 + virtual std::string ext();
508 public: 540 public:
509 /** 541 /**
510 * read body to string. 542 * read body to string.
@@ -689,10 +689,43 @@ int SrsLiveStream::streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrM @@ -689,10 +689,43 @@ int SrsLiveStream::streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrM
689 return ret; 689 return ret;
690 } 690 }
691 691
692 -SrsLiveEntry::SrsLiveEntry() 692 +SrsLiveEntry::SrsLiveEntry(std::string m, bool h)
693 { 693 {
  694 + mount = m;
  695 + hstrs = h;
  696 +
694 stream = NULL; 697 stream = NULL;
695 cache = NULL; 698 cache = NULL;
  699 +
  700 + std::string ext;
  701 + size_t pos = string::npos;
  702 + if ((pos = m.rfind(".")) != string::npos) {
  703 + ext = m.substr(pos);
  704 + }
  705 + _is_flv = (ext == ".flv");
  706 + _is_ts = (ext == ".ts");
  707 + _is_mp3 = (ext == ".mp3");
  708 + _is_aac = (ext == ".aac");
  709 +}
  710 +
  711 +bool SrsLiveEntry::is_flv()
  712 +{
  713 + return _is_flv;
  714 +}
  715 +
  716 +bool SrsLiveEntry::is_ts()
  717 +{
  718 + return _is_ts;
  719 +}
  720 +
  721 +bool SrsLiveEntry::is_aac()
  722 +{
  723 + return _is_aac;
  724 +}
  725 +
  726 +bool SrsLiveEntry::is_mp3()
  727 +{
  728 + return _is_mp3;
696 } 729 }
697 730
698 SrsHlsM3u8Stream::SrsHlsM3u8Stream() 731 SrsHlsM3u8Stream::SrsHlsM3u8Stream()
@@ -765,10 +798,13 @@ SrsHlsEntry::SrsHlsEntry() @@ -765,10 +798,13 @@ SrsHlsEntry::SrsHlsEntry()
765 798
766 SrsHttpServer::SrsHttpServer() 799 SrsHttpServer::SrsHttpServer()
767 { 800 {
  801 + mux.hijack(this);
768 } 802 }
769 803
770 SrsHttpServer::~SrsHttpServer() 804 SrsHttpServer::~SrsHttpServer()
771 { 805 {
  806 + mux.unhijack(this);
  807 +
772 if (true) { 808 if (true) {
773 std::map<std::string, SrsLiveEntry*>::iterator it; 809 std::map<std::string, SrsLiveEntry*>::iterator it;
774 for (it = tflvs.begin(); it != tflvs.end(); ++it) { 810 for (it = tflvs.begin(); it != tflvs.end(); ++it) {
@@ -853,8 +889,7 @@ int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r) @@ -853,8 +889,7 @@ int SrsHttpServer::http_mount(SrsSource* s, SrsRequest* r)
853 // remove the default vhost mount 889 // remove the default vhost mount
854 mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); 890 mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
855 891
856 - entry = new SrsLiveEntry();  
857 - entry->mount = mount; 892 + entry = new SrsLiveEntry(mount, tmpl->hstrs);
858 893
859 entry->cache = new SrsStreamCache(s, r); 894 entry->cache = new SrsStreamCache(s, r);
860 entry->stream = new SrsLiveStream(s, r, entry->cache); 895 entry->stream = new SrsLiveStream(s, r, entry->cache);
@@ -1060,6 +1095,29 @@ int SrsHttpServer::on_reload_vhost_hls(string vhost) @@ -1060,6 +1095,29 @@ int SrsHttpServer::on_reload_vhost_hls(string vhost)
1060 return ret; 1095 return ret;
1061 } 1096 }
1062 1097
  1098 +int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph)
  1099 +{
  1100 + int ret = ERROR_SUCCESS;
  1101 +
  1102 + // when handler not the root, we think the handler is ok.
  1103 + ISrsHttpHandler* h = ph? *ph : NULL;
  1104 + if (h->entry && h->entry->pattern != "/") {
  1105 + return ret;
  1106 + }
  1107 +
  1108 + // only hijack for http streaming, http-flv/ts/mp3/aac.
  1109 + std::string ext = request->ext();
  1110 + if (ext.empty()) {
  1111 + return ret;
  1112 + }
  1113 + if (ext != ".flv" && ext != ".ts" && ext != ".mp3" && ext != ".aac") {
  1114 + return ret;
  1115 + }
  1116 +
  1117 + // TODO: FIXME: implements it.
  1118 + return ret;
  1119 +}
  1120 +
1063 int SrsHttpServer::initialize_static_file() 1121 int SrsHttpServer::initialize_static_file()
1064 { 1122 {
1065 int ret = ERROR_SUCCESS; 1123 int ret = ERROR_SUCCESS;
@@ -1138,8 +1196,10 @@ int SrsHttpServer::initialize_flv_streaming() @@ -1138,8 +1196,10 @@ int SrsHttpServer::initialize_flv_streaming()
1138 continue; 1196 continue;
1139 } 1197 }
1140 1198
1141 - SrsLiveEntry* entry = new SrsLiveEntry();  
1142 - entry->mount = _srs_config->get_vhost_http_remux_mount(vhost); 1199 + SrsLiveEntry* entry = new SrsLiveEntry(
  1200 + _srs_config->get_vhost_http_remux_mount(vhost),
  1201 + _srs_config->get_vhost_http_remux_hstrs(vhost)
  1202 + );
1143 tflvs[vhost] = entry; 1203 tflvs[vhost] = entry;
1144 srs_trace("http flv live stream, vhost=%s, mount=%s", 1204 srs_trace("http flv live stream, vhost=%s, mount=%s",
1145 vhost.c_str(), entry->mount.c_str()); 1205 vhost.c_str(), entry->mount.c_str());
@@ -252,14 +252,27 @@ private: @@ -252,14 +252,27 @@ private:
252 */ 252 */
253 struct SrsLiveEntry 253 struct SrsLiveEntry
254 { 254 {
  255 +private:
  256 + bool _is_flv;
  257 + bool _is_ts;
  258 + bool _is_aac;
  259 + bool _is_mp3;
  260 +public:
255 // for template, the mount contains variables. 261 // for template, the mount contains variables.
256 // for concrete stream, the mount is url to access. 262 // for concrete stream, the mount is url to access.
257 std::string mount; 263 std::string mount;
  264 + // whether hstrs(http stream trigger rtmp source)
  265 + bool hstrs;
258 266
259 SrsLiveStream* stream; 267 SrsLiveStream* stream;
260 SrsStreamCache* cache; 268 SrsStreamCache* cache;
261 269
262 - SrsLiveEntry(); 270 + SrsLiveEntry(std::string m, bool h);
  271 +
  272 + bool is_flv();
  273 + bool is_ts();
  274 + bool is_mp3();
  275 + bool is_aac();
263 }; 276 };
264 277
265 /** 278 /**
@@ -314,13 +327,14 @@ struct SrsHlsEntry @@ -314,13 +327,14 @@ struct SrsHlsEntry
314 * the http server instance, 327 * the http server instance,
315 * serve http static file, flv vod stream and flv live stream. 328 * serve http static file, flv vod stream and flv live stream.
316 */ 329 */
317 -class SrsHttpServer : public ISrsReloadHandler 330 +class SrsHttpServer : virtual public ISrsReloadHandler
  331 + , virtual public ISrsHttpMatchHijacker
318 { 332 {
319 public: 333 public:
320 SrsHttpServeMux mux; 334 SrsHttpServeMux mux;
321 - // the flv live streaming template, to create streams. 335 + // the http live streaming template, to create streams.
322 std::map<std::string, SrsLiveEntry*> tflvs; 336 std::map<std::string, SrsLiveEntry*> tflvs;
323 - // the flv live streaming streams, crote by template. 337 + // the http live streaming streams, crote by template.
324 std::map<std::string, SrsLiveEntry*> sflvs; 338 std::map<std::string, SrsLiveEntry*> sflvs;
325 // the hls live streaming template, to create streams. 339 // the hls live streaming template, to create streams.
326 std::map<std::string, SrsHlsEntry*> thls; 340 std::map<std::string, SrsHlsEntry*> thls;
@@ -346,6 +360,9 @@ public: @@ -346,6 +360,9 @@ public:
346 virtual int on_reload_vhost_http_updated(); 360 virtual int on_reload_vhost_http_updated();
347 virtual int on_reload_vhost_http_remux_updated(); 361 virtual int on_reload_vhost_http_remux_updated();
348 virtual int on_reload_vhost_hls(std::string vhost); 362 virtual int on_reload_vhost_hls(std::string vhost);
  363 +// interface ISrsHttpMatchHijacker
  364 +public:
  365 + virtual int hijack(SrsHttpMessage* request, ISrsHttpHandler** ph);
349 private: 366 private:
350 virtual int initialize_static_file(); 367 virtual int initialize_static_file();
351 virtual int initialize_flv_streaming(); 368 virtual int initialize_flv_streaming();