diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 51d5e4375..707ecd9a7 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 7.0 Changelog +* v7.0, 2025-09-01, Merge [#4462](https://github.com/ossrs/srs/pull/4462): HTTP: Rename HTTP hijack to dynamic match for better clarity. v7.0.71 (#4462) * v7.0, 2025-08-31, Merge [#4461](https://github.com/ossrs/srs/pull/4461): AI: Extract shared components and improve SRS server architecture. v7.0.70 (#4461) * v7.0, 2025-08-31, Merge [#4460](https://github.com/ossrs/srs/pull/4460): AI: Always enable SRT protocol. v7.0.69 (#4460) * v7.0, 2025-08-31, Merge [#4459](https://github.com/ossrs/srs/pull/4459): AI: Merge SRT and RTC servers into unified SrsServer. v7.0.68 (#4459) diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index 250a3ed84..0b5d3a8ec 100644 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -1020,13 +1020,13 @@ SrsHttpStreamServer::SrsHttpStreamServer(SrsServer *svr) server = svr; async_ = new SrsAsyncCallWorker(); - mux.hijack(this); + mux.add_dynamic_matcher(this); _srs_config->subscribe(this); } SrsHttpStreamServer::~SrsHttpStreamServer() { - mux.unhijack(this); + mux.remove_dynamic_matcher(this); _srs_config->unsubscribe(this); async_->stop(); @@ -1168,7 +1168,7 @@ void SrsHttpStreamServer::http_unmount(ISrsRequest *r) } } -srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage *request, ISrsHttpHandler **ph) +srs_error_t SrsHttpStreamServer::dynamic_match(ISrsHttpMessage *request, ISrsHttpHandler **ph) { srs_error_t err = srs_success; @@ -1178,7 +1178,7 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage *request, ISrsHttpHandle return err; } - // only hijack for http streaming, http-flv/ts/mp3/aac. + // only match for http streaming, http-flv/ts/mp3/aac. std::string ext = request->ext(); if (ext.empty()) { return err; @@ -1203,7 +1203,7 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage *request, ISrsHttpHandle // for origin, the http stream will be mount already when publish, // so it must never enter this line for stream already mounted. // for edge, the http stream is trigger by hstrs and mount by it, - // so we only hijack when only edge and hstrs is on. + // so we only match when only edge and hstrs is on. entry = it->second; // check entry and request extension. @@ -1244,7 +1244,7 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage *request, ISrsHttpHandle SrsHttpMessage *hreq = dynamic_cast(request); srs_assert(hreq); - // hijack for entry. + // match for entry. SrsUniquePtr r(hreq->to_request(vhost->arg0())); std::string sid = r->get_stream_url(); @@ -1254,10 +1254,10 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage *request, ISrsHttpHandle SrsLiveEntry *s_entry = streamHandlers[sid]; if (!s_entry->stream->entry->enabled) { // only when the http entry is disabled, check the config whether http flv disable, - // for the http flv edge use hijack to trigger the edge ingester, we always mount it + // for the http flv edge use match to trigger the edge ingester, we always mount it // eventhough the origin does not exists the specified stream. if (!_srs_config->get_vhost_http_remux_enabled(r->vhost)) { - return srs_error_new(ERROR_HTTP_HIJACK, "stream disabled"); + return srs_error_new(ERROR_HTTP_DYNAMIC_MATCH, "stream disabled"); } } } @@ -1273,7 +1273,7 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage *request, ISrsHttpHandle *ph = entry->stream; } - srs_trace("flv: hijack %s ok", upath.c_str()); + srs_trace("flv: dynamic match %s ok", upath.c_str()); return err; } diff --git a/trunk/src/app/srs_app_http_stream.hpp b/trunk/src/app/srs_app_http_stream.hpp index 352ce4cfa..64ee5d145 100644 --- a/trunk/src/app/srs_app_http_stream.hpp +++ b/trunk/src/app/srs_app_http_stream.hpp @@ -276,7 +276,7 @@ public: // The HTTP Live Streaming Server, to serve FLV/TS/MP3/AAC stream. // TODO: Support multiple stream. -class SrsHttpStreamServer : public ISrsReloadHandler, public ISrsHttpMatchHijacker +class SrsHttpStreamServer : public ISrsReloadHandler, public ISrsHttpDynamicMatcher { private: SrsServer *server; @@ -300,9 +300,10 @@ public: // HTTP flv/ts/mp3/aac stream virtual srs_error_t http_mount(ISrsRequest *r); virtual void http_unmount(ISrsRequest *r); - // Interface ISrsHttpMatchHijacker + + // Interface ISrsHttpDynamicMatcher public: - virtual srs_error_t hijack(ISrsHttpMessage *request, ISrsHttpHandler **ph); + virtual srs_error_t dynamic_match(ISrsHttpMessage *request, ISrsHttpHandler **ph); private: virtual srs_error_t initialize_flv_streaming(); diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp index e064f5b00..4e21271f8 100644 --- a/trunk/src/core/srs_core_version7.hpp +++ b/trunk/src/core/srs_core_version7.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 7 #define VERSION_MINOR 0 -#define VERSION_REVISION 70 +#define VERSION_REVISION 71 #endif \ No newline at end of file diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index dfa1b588e..341bba819 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -161,7 +161,7 @@ XX(ERROR_RTMP_CLIENT_NOT_FOUND, 2049, "ClientNotFound", "Request client is not found") \ XX(ERROR_OpenSslCreateHMAC, 2050, "SslCreateHmac", "Failed to create HMAC for SSL") \ XX(ERROR_RTMP_STREAM_NAME_EMPTY, 2051, "StreamNameEmpty", "Invalid stream for name is empty") \ - XX(ERROR_HTTP_HIJACK, 2052, "HttpHijack", "Failed to hijack HTTP handler") \ + XX(ERROR_HTTP_DYNAMIC_MATCH, 2052, "HttpDynamicMatch", "Failed to dynamic match HTTP handler") \ XX(ERROR_RTMP_MESSAGE_CREATE, 2053, "MessageCreate", "Failed to create shared pointer message") \ XX(ERROR_RTMP_PROXY_EXCEED, 2054, "RtmpProxy", "Failed to decode message of RTMP proxy") \ XX(ERROR_RTMP_CREATE_STREAM_DEPTH, 2055, "RtmpIdentify", "Failed to identify RTMP client") \ diff --git a/trunk/src/protocol/srs_protocol_http_stack.cpp b/trunk/src/protocol/srs_protocol_http_stack.cpp index 736ada6c9..1586d9073 100644 --- a/trunk/src/protocol/srs_protocol_http_stack.cpp +++ b/trunk/src/protocol/srs_protocol_http_stack.cpp @@ -785,11 +785,11 @@ SrsHttpMuxEntry::~SrsHttpMuxEntry() srs_freep(handler); } -ISrsHttpMatchHijacker::ISrsHttpMatchHijacker() +ISrsHttpDynamicMatcher::ISrsHttpDynamicMatcher() { } -ISrsHttpMatchHijacker::~ISrsHttpMatchHijacker() +ISrsHttpDynamicMatcher::~ISrsHttpDynamicMatcher() { } @@ -808,14 +808,14 @@ SrsHttpServeMux::SrsHttpServeMux() SrsHttpServeMux::~SrsHttpServeMux() { std::map::iterator it; - for (it = entries.begin(); it != entries.end(); ++it) { + for (it = static_matchers_.begin(); it != static_matchers_.end(); ++it) { SrsHttpMuxEntry *entry = it->second; srs_freep(entry); } - entries.clear(); + static_matchers_.clear(); - vhosts.clear(); - hijackers.clear(); + vhosts_.clear(); + dynamic_matchers_.clear(); } srs_error_t SrsHttpServeMux::initialize() @@ -827,22 +827,24 @@ srs_error_t SrsHttpServeMux::initialize() return err; } -void SrsHttpServeMux::hijack(ISrsHttpMatchHijacker *h) +void SrsHttpServeMux::add_dynamic_matcher(ISrsHttpDynamicMatcher *h) { - std::vector::iterator it = std::find(hijackers.begin(), hijackers.end(), h); - if (it != hijackers.end()) { + std::vector::iterator it; + it = std::find(dynamic_matchers_.begin(), dynamic_matchers_.end(), h); + if (it != dynamic_matchers_.end()) { return; } - hijackers.push_back(h); + dynamic_matchers_.push_back(h); } -void SrsHttpServeMux::unhijack(ISrsHttpMatchHijacker *h) +void SrsHttpServeMux::remove_dynamic_matcher(ISrsHttpDynamicMatcher *h) { - std::vector::iterator it = std::find(hijackers.begin(), hijackers.end(), h); - if (it == hijackers.end()) { + std::vector::iterator it; + it = std::find(dynamic_matchers_.begin(), dynamic_matchers_.end(), h); + if (it == dynamic_matchers_.end()) { return; } - it = hijackers.erase(it); + it = dynamic_matchers_.erase(it); } srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler *handler) @@ -853,8 +855,8 @@ srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler *handle return srs_error_new(ERROR_HTTP_PATTERN_EMPTY, "empty pattern"); } - if (entries.find(pattern) != entries.end()) { - SrsHttpMuxEntry *exists = entries[pattern]; + if (static_matchers_.find(pattern) != static_matchers_.end()) { + SrsHttpMuxEntry *exists = static_matchers_[pattern]; if (exists->explicit_match) { return srs_error_new(ERROR_HTTP_PATTERN_DUPLICATED, "pattern=%s exists", pattern.c_str()); } @@ -865,7 +867,7 @@ srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler *handle if (pattern.find("/") != string::npos) { vhost = pattern.substr(0, pattern.find("/")); } - vhosts[vhost] = handler; + vhosts_[vhost] = handler; } if (true) { @@ -875,11 +877,11 @@ srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler *handle entry->pattern = pattern; entry->handler->entry = entry; - if (entries.find(pattern) != entries.end()) { - SrsHttpMuxEntry *exists = entries[pattern]; + if (static_matchers_.find(pattern) != static_matchers_.end()) { + SrsHttpMuxEntry *exists = static_matchers_[pattern]; srs_freep(exists); } - entries[pattern] = entry; + static_matchers_[pattern] = entry; } // Helpful behavior: @@ -890,8 +892,8 @@ srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler *handle SrsHttpMuxEntry *entry = NULL; // free the exists implicit entry - if (entries.find(rpattern) != entries.end()) { - entry = entries[rpattern]; + if (static_matchers_.find(rpattern) != static_matchers_.end()) { + entry = static_matchers_[rpattern]; } // create implicit redirect. @@ -904,7 +906,7 @@ srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler *handle entry->pattern = pattern; entry->handler->entry = entry; - entries[rpattern] = entry; + static_matchers_[rpattern] = entry; } } @@ -914,10 +916,10 @@ srs_error_t SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler *handle void SrsHttpServeMux::unhandle(std::string pattern, ISrsHttpHandler *handler) { if (true) { - std::map::iterator it = entries.find(pattern); - if (it != entries.end()) { + std::map::iterator it = static_matchers_.find(pattern); + if (it != static_matchers_.end()) { SrsHttpMuxEntry *entry = it->second; - entries.erase(it); + static_matchers_.erase(it); // We don't free the handler, because user should free it. if (entry->handler == handler) { @@ -935,9 +937,9 @@ void SrsHttpServeMux::unhandle(std::string pattern, ISrsHttpHandler *handler) vhost = pattern.substr(0, pattern.find("/")); } - std::map::iterator it = vhosts.find(vhost); - if (it != vhosts.end()) - vhosts.erase(it); + std::map::iterator it = vhosts_.find(vhost); + if (it != vhosts_.end()) + vhosts_.erase(it); } } @@ -971,14 +973,14 @@ srs_error_t SrsHttpServeMux::find_handler(ISrsHttpMessage *r, ISrsHttpHandler ** return srs_error_wrap(err, "http match"); } - // always hijack. - if (!hijackers.empty()) { - // notify all hijackers unless matching failed. - std::vector::iterator it; - for (it = hijackers.begin(); it != hijackers.end(); ++it) { - ISrsHttpMatchHijacker *hijacker = *it; - if ((err = hijacker->hijack(r, ph)) != srs_success) { - return srs_error_wrap(err, "http hijack"); + // always try to handle by dynamic matchers. + if (!dynamic_matchers_.empty()) { + // notify all dynamic matchers unless matching failed. + std::vector::iterator it; + for (it = dynamic_matchers_.begin(); it != dynamic_matchers_.end(); ++it) { + ISrsHttpDynamicMatcher *matcher = *it; + if ((err = matcher->dynamic_match(r, ph)) != srs_success) { + return srs_error_wrap(err, "http dynamic match"); } } } @@ -996,7 +998,7 @@ srs_error_t SrsHttpServeMux::match(ISrsHttpMessage *r, ISrsHttpHandler **ph) std::string path = r->path(); // Host-specific pattern takes precedence over generic ones - if (!vhosts.empty() && vhosts.find(r->host()) != vhosts.end()) { + if (!vhosts_.empty() && vhosts_.find(r->host()) != vhosts_.end()) { path = r->host() + path; } @@ -1004,7 +1006,7 @@ srs_error_t SrsHttpServeMux::match(ISrsHttpMessage *r, ISrsHttpHandler **ph) ISrsHttpHandler *h = NULL; std::map::iterator it; - for (it = entries.begin(); it != entries.end(); ++it) { + for (it = static_matchers_.begin(); it != static_matchers_.end(); ++it) { std::string pattern = it->first; SrsHttpMuxEntry *entry = it->second; diff --git a/trunk/src/protocol/srs_protocol_http_stack.hpp b/trunk/src/protocol/srs_protocol_http_stack.hpp index 7a4ff54bf..9327f67f0 100644 --- a/trunk/src/protocol/srs_protocol_http_stack.hpp +++ b/trunk/src/protocol/srs_protocol_http_stack.hpp @@ -409,18 +409,18 @@ public: virtual ~SrsHttpMuxEntry(); }; -// The hijacker for http pattern match. -class ISrsHttpMatchHijacker +// The dynamic matcher for http pattern match. +class ISrsHttpDynamicMatcher { public: - ISrsHttpMatchHijacker(); - virtual ~ISrsHttpMatchHijacker(); + ISrsHttpDynamicMatcher(); + virtual ~ISrsHttpDynamicMatcher(); public: // When match the request failed, no handler to process request. // @param request the http request message to match the handler. - // @param ph the already matched handler, hijack can rewrite it. - virtual srs_error_t hijack(ISrsHttpMessage *request, ISrsHttpHandler **ph) = 0; + // @param ph the already matched handler, dynamic matcher can rewrite it. + virtual srs_error_t dynamic_match(ISrsHttpMessage *request, ISrsHttpHandler **ph) = 0; }; // The server mux, all http server should implements it. @@ -466,17 +466,19 @@ class SrsHttpServeMux : public ISrsHttpServeMux { private: // The pattern handler, to handle the http request. - std::map entries; + std::map static_matchers_; // The vhost handler. // When find the handler to process the request, // append the matched vhost when pattern not starts with /, // For example, for pattern /live/livestream.flv of vhost ossrs.net, // The path will rewrite to ossrs.net/live/livestream.flv - std::map vhosts; - // all hijackers for http match. + std::map vhosts_; + +private: + // all dynamic matcher for http match. // For example, the hstrs(http stream trigger rtmp source) - // can hijack and install handler when request incoming and no handler. - std::vector hijackers; + // can dynamic match and install handler when request incoming and no handler. + std::vector dynamic_matchers_; public: SrsHttpServeMux(); @@ -485,9 +487,11 @@ public: public: // Initialize the http serve mux. virtual srs_error_t initialize(); - // hijack the http match. - virtual void hijack(ISrsHttpMatchHijacker *h); - virtual void unhijack(ISrsHttpMatchHijacker *h); + +public: + // Add a dynamic matcher for the http match. + virtual void add_dynamic_matcher(ISrsHttpDynamicMatcher *h); + virtual void remove_dynamic_matcher(ISrsHttpDynamicMatcher *h); public: // Handle registers the handler for the given pattern. diff --git a/trunk/src/utest/srs_utest_http.cpp b/trunk/src/utest/srs_utest_http.cpp index d0891fc75..492b70b91 100644 --- a/trunk/src/utest/srs_utest_http.cpp +++ b/trunk/src/utest/srs_utest_http.cpp @@ -178,7 +178,7 @@ public: } }; -class MockHttpHandler : public ISrsHttpHandler, public ISrsHttpMatchHijacker +class MockHttpHandler : public ISrsHttpHandler, public ISrsHttpDynamicMatcher { public: string bytes; @@ -193,7 +193,7 @@ public: { return w->write((char *)bytes.data(), (int)bytes.length()); } - virtual srs_error_t hijack(ISrsHttpMessage * /*r*/, ISrsHttpHandler **ph) + virtual srs_error_t dynamic_match(ISrsHttpMessage * /*r*/, ISrsHttpHandler **ph) { if (ph) { *ph = this; @@ -840,10 +840,10 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerHijack) HELPER_ASSERT_SUCCESS(s.initialize()); MockHttpHandler h1("Done"); - s.hijack(&h1); + s.add_dynamic_matcher(&h1); MockHttpHandler h0("Hello, world!"); - s.hijack(&h0); + s.add_dynamic_matcher(&h0); MockResponseWriter w; SrsHttpMessage r(NULL, NULL); @@ -859,10 +859,10 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerHijack) HELPER_ASSERT_SUCCESS(s.initialize()); MockHttpHandler h0("Hello, world!"); - s.hijack(&h0); + s.add_dynamic_matcher(&h0); MockHttpHandler h1("Done"); - s.hijack(&h1); + s.add_dynamic_matcher(&h1); MockResponseWriter w; SrsHttpMessage r(NULL, NULL); @@ -877,8 +877,8 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerHijack) HELPER_ASSERT_SUCCESS(s.initialize()); MockHttpHandler hroot("Hello, world!"); - s.hijack(&hroot); - s.unhijack(&hroot); + s.add_dynamic_matcher(&hroot); + s.remove_dynamic_matcher(&hroot); MockResponseWriter w; SrsHttpMessage r(NULL, NULL); @@ -893,7 +893,7 @@ VOID TEST(ProtocolHTTPTest, HTTPServerMuxerHijack) HELPER_ASSERT_SUCCESS(s.initialize()); MockHttpHandler hroot("Hello, world!"); - s.hijack(&hroot); + s.add_dynamic_matcher(&hroot); MockResponseWriter w; SrsHttpMessage r(NULL, NULL); diff --git a/trunk/src/utest/srs_utest_st.cpp b/trunk/src/utest/srs_utest_st.cpp index f0428f21c..57a6b3621 100644 --- a/trunk/src/utest/srs_utest_st.cpp +++ b/trunk/src/utest/srs_utest_st.cpp @@ -26,9 +26,9 @@ VOID TEST(StTest, StUtimeInMicroseconds) EXPECT_GT(st_time_1, 0); EXPECT_GT(st_time_2, 0); EXPECT_GE(st_time_2, st_time_1); - // st_time_2 - st_time_1 should be in range of [1, 150] microseconds + // st_time_2 - st_time_1 should be in range of [1, 300] microseconds EXPECT_GE(st_time_2 - st_time_1, 0); - EXPECT_LE(st_time_2 - st_time_1, 150); + EXPECT_LE(st_time_2 - st_time_1, 300); } static inline st_utime_t time_gettimeofday()