Forward: Reject RTMPS destinations with clear error message. v7.0.100 (#4537)

SRS forward feature only supports plain RTMP protocol, not RTMPS (RTMP over SSL/TLS). This is by design - SRS SSL is server-side only (accepting connections), not client-side (initiating connections). The forward feature uses SrsSimpleRtmpClient which has no SSL handshake or encryption capabilities for outgoing connections.

Changes:
1. Add RTMPS URL detection in SrsForwarder::initialize()
2. Return ERROR_NOT_SUPPORTED error when RTMPS destination is detected
3. Add unit test to verify RTMPS URLs are properly rejected
4. Add FAQ section to .augment-guidelines explaining the limitation

For users who need to forward to RTMPS destinations (e.g., AWS IVS), the recommended solution is to use FFmpeg with SRS HTTP Hooks:
- on_publish event: Automatically start FFmpeg to relay stream to RTMPS destination
- on_unpublish event: Automatically stop FFmpeg process when stream ends

This provides a fully automated, production-ready RTMPS relay solution without adding complexity to SRS core.

Related: #4536

---------

Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This commit is contained in:
Winlin 2025-10-20 08:03:07 -04:00 committed by GitHub
parent 4e35b6cacc
commit 845e0287c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 56 additions and 2 deletions

View File

@ -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

View File

@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v7-changes"></a>
## 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)

View File

@ -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();

View File

@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
#define VERSION_REVISION 99
#define VERSION_REVISION 100
#endif

View File

@ -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<SrsOriginHub> hub(new SrsOriginHub());
hub->source_ = mock_source;
// Create forwarder
SrsUniquePtr<SrsForwarder> forwarder(new SrsForwarder(hub.get()));
// Create mock request
SrsUniquePtr<MockHlsRequest> 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;