Forward: Reject RTMPS destinations with clear error message.

This commit is contained in:
OSSRS-AI 2025-10-20 07:57:22 -04:00 committed by winlin
parent 4e35b6cacc
commit 6a9735b06a
3 changed files with 54 additions and 1 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

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

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