diff --git a/.augment-guidelines b/.augment-guidelines index c8223c089..f73db8bbd 100644 --- a/.augment-guidelines +++ b/.augment-guidelines @@ -893,6 +893,21 @@ documentation: description: | SRS documentation source files are located in the 3rdparty/srs-docs directory usage: | - When looking for documentation or need to update docs, check this directory for markdown + When looking for documentation or need to update docs, check this directory for markdown files and documentation structure. Do not search ossrs.io or ossrs.net for documentation, use the local files instead. +faq: + rtmps_forward: + question: "Why doesn't SRS support RTMPS in the forward feature? Why does SRS only support RTMPS server but not forwarding to RTMPS endpoints?" + + answer: | + SRS doesn't support RTMPS (RTMP over SSL/TLS) in the forward feature because: + 1. SRS SSL is designed for server-side only (accepting connections), not client-side (initiating connections) + 2. Forward feature uses SrsSimpleRtmpClient which only supports plain RTMP protocol + 3. Adding RTMPS client support would add significant complexity for a rare use case + + Recommended solution: Use FFmpeg with SRS HTTP Hooks + - on_publish event: Automatically start FFmpeg to relay stream to RTMPS destination (e.g., AWS IVS) + - on_unpublish event: Automatically stop FFmpeg process when stream ends + - This provides fully automated, production-ready RTMPS relay without adding complexity to SRS core + diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 740a7f373..04f8cdf7e 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-10-20, Merge [#4537](https://github.com/ossrs/srs/pull/4537): Forward: Reject RTMPS destinations with clear error message. v7.0.100 (#4537) * v7.0, 2025-10-17, Merge [#4534](https://github.com/ossrs/srs/pull/4534): HLS: Fix a iterator bug in hls_ctx cleanup function. v7.0.99 (#4534) * v7.0, 2025-10-16, Merge [#4530](https://github.com/ossrs/srs/pull/4530): fix crash issue caused by reload configuration file. v7.0.98 (#4530) * v7.0, 2025-10-15, Merge [#4520](https://github.com/ossrs/srs/pull/4520): srs_app_rtc_conn: fix illegal memory access. v7.0.97 (#4520) diff --git a/trunk/src/app/srs_app_forward.cpp b/trunk/src/app/srs_app_forward.cpp index f7b5c3862..f7962001e 100644 --- a/trunk/src/app/srs_app_forward.cpp +++ b/trunk/src/app/srs_app_forward.cpp @@ -75,6 +75,12 @@ srs_error_t SrsForwarder::initialize(ISrsRequest *r, string ep) // the ep(endpoint) to forward to ep_forward_ = ep; + // Check if the forward destination is RTMPS URL + // SRS forward only supports plain RTMP protocol, not RTMPS (RTMP over SSL/TLS) + if (ep_forward_.find("rtmps://") != string::npos) { + return srs_error_new(ERROR_NOT_SUPPORTED, "forward does not support RTMPS destination=%s", ep_forward_.c_str()); + } + // Remember the source context id. source_cid_ = _srs_context->get_id(); diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp index d5ffe5c74..3d199c7ba 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 99 +#define VERSION_REVISION 100 #endif \ No newline at end of file diff --git a/trunk/src/utest/srs_utest_ai14.cpp b/trunk/src/utest/srs_utest_ai14.cpp index b4393e672..6146726bb 100644 --- a/trunk/src/utest/srs_utest_ai14.cpp +++ b/trunk/src/utest/srs_utest_ai14.cpp @@ -2892,6 +2892,38 @@ VOID TEST(AppOriginHubTest, CreateBackendForwardersTypicalScenario) srs_freep(mock_hooks); } +// Unit test for SrsForwarder RTMPS detection +VOID TEST(AppForwarderTest, RejectRtmpsDestination) +{ + srs_error_t err; + + // Create mock origin hub + MockLiveSourceForOriginHub *mock_source = new MockLiveSourceForOriginHub(); + SrsUniquePtr hub(new SrsOriginHub()); + hub->source_ = mock_source; + + // Create forwarder + SrsUniquePtr forwarder(new SrsForwarder(hub.get())); + + // Create mock request + SrsUniquePtr req(new MockHlsRequest()); + + // Test the hostport spliting + std::string server; + int port = SRS_CONSTS_RTMP_DEFAULT_PORT; + srs_net_split_hostport("rtmps://fake.demo.ossrs.io:443/app", server, port); + EXPECT_STREQ("rtmps://fake.demo.ossrs.io:443/app", server.c_str()); + + // Test 1: RTMPS URL should be rejected + HELPER_ASSERT_FAILED(forwarder->initialize(req.get(), "rtmps://fake.demo.ossrs.io:443/app")); + + // Test 2: Plain RTMP URL should be accepted + HELPER_EXPECT_SUCCESS(forwarder->initialize(req.get(), "127.0.0.1:1935")); + + // Cleanup + srs_freep(mock_source); +} + VOID TEST(SrsLiveSourceTest, OnAggregateSelectionTypical) { srs_error_t err;