正在显示
4 个修改的文件
包含
172 行增加
和
9 行删除
| @@ -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; |
| @@ -629,8 +656,22 @@ int SrsHttpServeMux::find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph) | @@ -629,8 +656,22 @@ int SrsHttpServeMux::find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph) | ||
| 629 | srs_error("http match handler failed. ret=%d", ret); | 656 | srs_error("http match handler failed. ret=%d", ret); |
| 630 | return ret; | 657 | return ret; |
| 631 | } | 658 | } |
| 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 | + } | ||
| 632 | 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(); |
-
请 注册 或 登录 后发表评论