diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index aa5b7d962..b1be0803f 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 5.0 Changelog +* v5.0, 2022-08-31, Fix URL parsing bug for `__defaultVhost__`. v5.0.55 * v5.0, 2022-08-30, Fix [#2837](https://github.com/ossrs/srs/issues/2837): Callback: Support stream_url and stream_id. v5.0.55 * v5.0, 2022-08-30, STAT: Refine tcUrl for SRT/RTC. v5.0.54 * v5.0, 2022-08-30, Refactor: Extract SrsNetworkKbps from SrsKbps. v5.0.53 diff --git a/trunk/research/console/js/srs.console.js b/trunk/research/console/js/srs.console.js index 46c833598..d23929587 100644 --- a/trunk/research/console/js/srs.console.js +++ b/trunk/research/console/js/srs.console.js @@ -584,8 +584,10 @@ scApp.filter('sc_filter_streamURL', function(){ const pos = v.url.lastIndexOf('/'); const stream = pos < 0 ? '' : v.url.substr(pos); + // Use name or extract from url. - const streamName = v.name ? v.name : stream; + let streamName = v.name ? v.name : stream; + if (streamName && streamName.indexOf('/') !== 0) streamName = `/${streamName}`; const pos2 = v.tcUrl.indexOf('?'); const tcUrl = pos2 < 0 ? v.tcUrl : v.tcUrl.substr(0, pos2); diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index 3e3eb5815..8f375ae43 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 55 +#define VERSION_REVISION 56 #endif diff --git a/trunk/src/protocol/srs_protocol_http_stack.cpp b/trunk/src/protocol/srs_protocol_http_stack.cpp index b6346a0be..1786765da 100644 --- a/trunk/src/protocol/srs_protocol_http_stack.cpp +++ b/trunk/src/protocol/srs_protocol_http_stack.cpp @@ -904,29 +904,41 @@ SrsHttpUri::~SrsHttpUri() { } -srs_error_t SrsHttpUri::initialize(string _url) +srs_error_t SrsHttpUri::initialize(string url) { schema = host = path = query = ""; + url_ = url; - url = _url; - const char* purl = url.c_str(); - - http_parser_url hp_u; - int r0; - if ((r0 = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){ - return srs_error_new(ERROR_HTTP_PARSE_URI, "parse url %s failed, code=%d", purl, r0); + // Replace the default vhost to a domain like string, or parse failed. + string parsing_url = url; + size_t pos_default_vhost = url.find("://__defaultVhost__"); + if (pos_default_vhost != string::npos) { + parsing_url = srs_string_replace(parsing_url, "://__defaultVhost__", "://safe.vhost.default.ossrs.io"); } - std::string field = get_uri_field(url, &hp_u, UF_SCHEMA); + http_parser_url hp_u; + http_parser_url_init(&hp_u); + + int r0; + if ((r0 = http_parser_parse_url(parsing_url.c_str(), parsing_url.length(), 0, &hp_u)) != 0){ + return srs_error_new(ERROR_HTTP_PARSE_URI, "parse url %s as %s failed, code=%d", url.c_str(), parsing_url.c_str(), r0); + } + + std::string field = get_uri_field(parsing_url, &hp_u, UF_SCHEMA); if (!field.empty()){ schema = field; } - host = get_uri_field(url, &hp_u, UF_HOST); + // Restore the default vhost. + if (pos_default_vhost == string::npos) { + host = get_uri_field(parsing_url, &hp_u, UF_HOST); + } else { + host = SRS_CONSTS_RTMP_DEFAULT_VHOST; + } - field = get_uri_field(url, &hp_u, UF_PORT); + field = get_uri_field(parsing_url, &hp_u, UF_PORT); if (!field.empty()) { - port = atoi(field.c_str()); + port = ::atoi(field.c_str()); } if (port <= 0) { if (schema == "https") { @@ -940,10 +952,10 @@ srs_error_t SrsHttpUri::initialize(string _url) } } - path = get_uri_field(url, &hp_u, UF_PATH); - query = get_uri_field(url, &hp_u, UF_QUERY); + path = get_uri_field(parsing_url, &hp_u, UF_PATH); + query = get_uri_field(parsing_url, &hp_u, UF_QUERY); - username_ = get_uri_field(url, &hp_u, UF_USERINFO); + username_ = get_uri_field(parsing_url, &hp_u, UF_USERINFO); size_t pos = username_.find(":"); if (pos != string::npos) { password_ = username_.substr(pos+1); @@ -958,15 +970,15 @@ void SrsHttpUri::set_schema(std::string v) schema = v; // Update url with new schema. - size_t pos = url.find("://"); + size_t pos = url_.find("://"); if (pos != string::npos) { - url = schema + "://" + url.substr(pos + 3); + url_ = schema + "://" + url_.substr(pos + 3); } } string SrsHttpUri::get_url() { - return url; + return url_; } string SrsHttpUri::get_schema() @@ -1013,7 +1025,7 @@ std::string SrsHttpUri::password() return password_; } -string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) +string SrsHttpUri::get_uri_field(const string& uri, void* php_u, int ifield) { http_parser_url* hp_u = (http_parser_url*)php_u; http_parser_url_fields field = (http_parser_url_fields)ifield; diff --git a/trunk/src/protocol/srs_protocol_http_stack.hpp b/trunk/src/protocol/srs_protocol_http_stack.hpp index c382ff286..1ebac924f 100644 --- a/trunk/src/protocol/srs_protocol_http_stack.hpp +++ b/trunk/src/protocol/srs_protocol_http_stack.hpp @@ -505,7 +505,7 @@ public: class SrsHttpUri { private: - std::string url; + std::string url_; std::string schema; std::string host; int port; @@ -535,7 +535,7 @@ public: private: // Get the parsed url field. // @return return empty string if not set. - virtual std::string get_uri_field(std::string uri, void* hp_u, int field); + virtual std::string get_uri_field(const std::string& uri, void* hp_u, int field); srs_error_t parse_query(); public: static std::string query_escape(std::string s); diff --git a/trunk/src/utest/srs_utest_protocol2.cpp b/trunk/src/utest/srs_utest_protocol2.cpp index 92bf733b4..50afde854 100644 --- a/trunk/src/utest/srs_utest_protocol2.cpp +++ b/trunk/src/utest/srs_utest_protocol2.cpp @@ -20,17 +20,6 @@ using namespace std; #include #include -VOID TEST(ProtocolKbpsTest, ParseUrlFailed) -{ - string tcUrl = "rtmp://__defaultVhost__/live", stream = "livestream"; - string schema, host, vhost, app, param; int port = 0; - srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); - EXPECT_STREQ("rtmp", schema.c_str()); - EXPECT_STREQ("__defaultVhost__", host.c_str()); - EXPECT_STREQ("__defaultVhost__", vhost.c_str()); - EXPECT_EQ(1935, port); -} - /** * recv video, audio, video and video, interlaced in chunks. * the continue chunks use fmt=1, last video with fmt=1 header @@ -3606,3 +3595,116 @@ VOID TEST(ProtocolHTTPTest, HTTPParser) } } +VOID TEST(ProtocolKbpsTest, ParseUrlFailed) +{ + if (true) { + string tcUrl = "rtmp://__defaultVhost__/live", stream = "livestream"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("rtmp", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(1935, port); + } + + if (true) { + string tcUrl = "rtmp://__defaultVhost__:1936/live", stream = "livestream"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("rtmp", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(1936, port); + } + + if (true) { + string tcUrl = "http://__defaultVhost__/live", stream = "livestream.flv"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("http", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(80, port); + } + + if (true) { + string tcUrl = "http://__defaultVhost__/live", stream = "livestream.m3u8"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("http", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(80, port); + } + + if (true) { + string tcUrl = "http://__defaultVhost__:8080/live", stream = "livestream.m3u8"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("http", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(8080, port); + } + + if (true) { + string tcUrl = "https://__defaultVhost__/live", stream = "livestream.flv"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("https", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(443, port); + } + + if (true) { + string tcUrl = "https://__defaultVhost__/live", stream = "livestream.m3u8"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("https", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(443, port); + } + + if (true) { + string tcUrl = "https://__defaultVhost__:8088/live", stream = "livestream.m3u8"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("https", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(8088, port); + } + + if (true) { + string tcUrl = "webrtc://__defaultVhost__/live", stream = "livestream"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("webrtc", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(80, port); + } + + if (true) { + string tcUrl = "webrtc://__defaultVhost__:8080/live", stream = "livestream"; + string schema, host, vhost, app, param; + int port = 0; + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, stream, port, param); + EXPECT_STREQ("webrtc", schema.c_str()); + EXPECT_STREQ("__defaultVhost__", host.c_str()); + EXPECT_STREQ("__defaultVhost__", vhost.c_str()); + EXPECT_EQ(8080, port); + } +} +