AI: Edge: Fix stream names with dots being incorrectly truncated in source URL generation. v7.0.109 (#4011)

This commit is contained in:
OSSRS-AI 2025-10-26 18:44:10 -04:00 committed by winlin
parent 19b603a0d7
commit 547b0c0ed5
4 changed files with 62 additions and 4 deletions

View File

@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v7-changes"></a>
## SRS 7.0 Changelog
* v7.0, 2025-10-26, AI: Edge: Fix stream names with dots being incorrectly truncated in source URL generation. v7.0.109 (#4011)
* v7.0, 2025-10-26, AI: HTTPS: Handle SSL_ERROR_ZERO_RETURN as graceful connection closure. v7.0.108 (#4036)
* v7.0, 2025-10-26, AI: API: Add clients field to on_play/on_stop webhooks and total field to HTTP API. v7.0.107 (#4147)
* v7.0, 2025-10-26, AI: WebRTC: Fix camera/microphone not released after closing publisher. v7.0.106 (#4261)

View File

@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
#define VERSION_REVISION 108
#define VERSION_REVISION 109
#endif

View File

@ -260,9 +260,21 @@ string srs_net_url_encode_sid(string vhost, string app, string stream)
url += vhost;
}
url += "/" + app;
// Note that we ignore any extension.
SrsPath path;
url += "/" + path.filepath_filename(stream);
// Strip only known streaming extensions, not arbitrary dots in stream names.
// This fixes issue 4011 where stream names like "WavMain.exe_rooms_290" were
// incorrectly truncated to "WavMain" because filepath_filename() stripped
// everything after any dot.
std::string stream_name = stream;
size_t pos = stream_name.rfind(".");
if (pos != string::npos) {
std::string ext = stream_name.substr(pos);
// Only strip known streaming extensions
if (ext == ".flv" || ext == ".m3u8" || ext == ".mp4" || ext == ".ts") {
stream_name = stream_name.substr(0, pos);
}
}
url += "/" + stream_name;
return url;
}

View File

@ -4972,6 +4972,51 @@ VOID TEST(ProtocolKbpsTest, StreamIdentify)
EXPECT_STREQ("ossrs.io/live/livestream", srs_net_url_encode_sid("ossrs.io", "live", "livestream.m3u8").c_str());
}
// Reproduce bug from issue 4011: Stream names with dots get truncated incorrectly
// https://github.com/ossrs/srs/issues/4011
// The filepath_filename() function removes everything after the LAST dot in the stream name.
// This was intended to strip extensions like .flv, but it breaks stream names that contain
// dots as part of the identifier (like WavMain.exe_rooms_290_20240402).
// This causes edge servers to treat different streams as the same source.
//
// This test FAILS to demonstrate the bug - when the bug is fixed, this test should PASS.
VOID TEST(ProtocolKbpsTest, StreamIdentifyWithDotsInName_Issue4011)
{
// Case 1: THE ACTUAL BUG from issue 4011
// Stream names like "WavMain.exe_rooms_290_20240402" contain a dot in ".exe"
// Expected: Each stream should have a unique source URL preserving the full name
// Actual (BUG): filepath_filename() strips everything after the dot in ".exe"
std::string url1 = srs_net_url_encode_sid("", "imlive", "WavMain.exe_rooms_290_20240402");
std::string url2 = srs_net_url_encode_sid("", "imlive", "WavMain.exe_rooms_311_20240402");
std::string url3 = srs_net_url_encode_sid("", "imlive", "WavMain.exe_rooms_222_20240402");
// EXPECTED: Each stream should preserve its full name
EXPECT_STREQ("/imlive/WavMain.exe_rooms_290_20240402", url1.c_str());
EXPECT_STREQ("/imlive/WavMain.exe_rooms_311_20240402", url2.c_str());
EXPECT_STREQ("/imlive/WavMain.exe_rooms_222_20240402", url3.c_str());
// EXPECTED: Different streams should have different URLs
EXPECT_STRNE(url1.c_str(), url2.c_str());
EXPECT_STRNE(url1.c_str(), url3.c_str());
EXPECT_STRNE(url2.c_str(), url3.c_str());
// Case 2: Stream names with multiple dots should preserve the full name
// (only strip known extensions like .flv, .m3u8, not arbitrary suffixes)
EXPECT_STREQ("/live/test.backup.stream", srs_net_url_encode_sid("", "live", "test.backup.stream").c_str());
EXPECT_STREQ("/live/my.stream.v2", srs_net_url_encode_sid("", "live", "my.stream.v2").c_str());
EXPECT_STREQ("/live/camera.1.hd", srs_net_url_encode_sid("", "live", "camera.1.hd").c_str());
// Case 3: Different streams with same prefix should be different
std::string backup1 = srs_net_url_encode_sid("", "live", "test.backup.stream");
std::string backup2 = srs_net_url_encode_sid("", "live", "test.backup.stream2");
EXPECT_STRNE(backup1.c_str(), backup2.c_str()); // Should be different
// Case 4: The intended behavior - stripping ONLY known extensions
// These should work correctly (strip .flv and .m3u8)
EXPECT_STREQ("/live/livestream", srs_net_url_encode_sid("", "live", "livestream.flv").c_str());
EXPECT_STREQ("/live/livestream", srs_net_url_encode_sid("", "live", "livestream.m3u8").c_str());
}
VOID TEST(ProtocolHTTPTest, ParseHTTPMessage)
{
srs_error_t err = srs_success;