diff --git a/trunk/conf/edge.conf b/trunk/conf/edge.conf index 71b03e3a9..b70175c7b 100644 --- a/trunk/conf/edge.conf +++ b/trunk/conf/edge.conf @@ -12,6 +12,26 @@ http_server { listen 8080; dir ./objs/nginx/html; } +http_api { + enabled on; + listen 1985; +} + +# Edge does not support WebRTC, so even if enabled in config, +# it will be automatically disabled at runtime. +rtc_server { + enabled on; + listen 8000; + candidate $CANDIDATE; +} + +# Edge does not support SRT, so even if enabled in config, +# it will be automatically disabled at runtime. +srt_server { + enabled on; + listen 10080; +} + vhost __defaultVhost__ { cluster { mode remote; @@ -21,4 +41,50 @@ vhost __defaultVhost__ { enabled on; mount [vhost]/[app]/[stream].flv; } + + # Edge does not support WebRTC, so even if enabled in config, + # it will be automatically disabled at runtime. + rtc { + enabled on; + rtmp_to_rtc on; + rtc_to_rtmp on; + } + + # Edge does not support SRT, so even if enabled in config, + # it will be automatically disabled at runtime. + srt { + enabled on; + srt_to_rtmp on; + } + + # Edge does not support HDS, so even if enabled in config, + # it will be automatically disabled at runtime. + hds { + enabled on; + } + + # Edge does not support HLS, so even if enabled in config, + # it will be automatically disabled at runtime. + hls { + enabled on; + } + + # Edge does not support MPEG-DASH, so even if enabled in config, + # it will be automatically disabled at runtime. + dash { + enabled on; + } + + # Edge does not support forwarding, so even if enabled in config, + # it will be automatically disabled at runtime. + forward { + enabled on; + destination 127.0.0.1:19350; + } + + # Edge does not support DVR, so even if enabled in config, + # it will be automatically disabled at runtime. + dvr { + enabled on; + } } diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 1e9877d94..73db6d868 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 6.0 Changelog +* v6.0, 2025-09-27, For Edge, only support RTMP or HTTP-FLV. v6.0.179 (#4512) * v6.0, 2025-09-20, Fix WHIP with transcoding bug. v6.0.178 (#4495) * v6.0, 2025-09-15, RTC2RTMP: Fix sequence number wraparound assertion crashes. v6.0.177 (#4491) * v6.0, 2025-09-05, RTX: Fix race condition for timer. v6.0.176 (#4470) (#4474) diff --git a/trunk/src/app/srs_app_rtc_api.cpp b/trunk/src/app/srs_app_rtc_api.cpp index 985c41af7..d08b5c1eb 100644 --- a/trunk/src/app/srs_app_rtc_api.cpp +++ b/trunk/src/app/srs_app_rtc_api.cpp @@ -206,6 +206,13 @@ srs_error_t SrsGoApiRtcPlay::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa // Whether enabled. bool server_enabled = _srs_config->get_rtc_server_enabled(); bool rtc_enabled = _srs_config->get_rtc_enabled(ruc->req_->vhost); + bool edge = _srs_config->get_vhost_is_edge(ruc->req_->vhost); + + if (rtc_enabled && edge) { + rtc_enabled = false; + srs_warn("disable WebRTC for edge vhost=%s", ruc->req_->vhost.c_str()); + } + if (server_enabled && !rtc_enabled) { srs_warn("RTC disabled in vhost %s", ruc->req_->vhost.c_str()); } @@ -222,7 +229,13 @@ srs_error_t SrsGoApiRtcPlay::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa } // For RTMP to RTC, fail if disabled and RTMP is active, see https://github.com/ossrs/srs/issues/2728 - if (!is_rtc_stream_active && !_srs_config->get_rtc_from_rtmp(ruc->req_->vhost)) { + bool rtmp_to_rtc = _srs_config->get_rtc_from_rtmp(ruc->req_->vhost); + if (rtmp_to_rtc && edge) { + rtmp_to_rtc = false; + srs_warn("disable RTMP to WebRTC for edge vhost=%s", ruc->req_->vhost.c_str()); + } + + if (!is_rtc_stream_active && !rtmp_to_rtc) { SrsSharedPtr live_source = _srs_sources->fetch(ruc->req_); if (live_source.get() && !live_source->inactive()) { return srs_error_new(ERROR_RTC_DISABLED, "Disabled rtmp_to_rtc of %s, see #2728", ruc->req_->vhost.c_str()); @@ -494,6 +507,13 @@ srs_error_t SrsGoApiRtcPublish::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe // Whether enabled. bool server_enabled = _srs_config->get_rtc_server_enabled(); bool rtc_enabled = _srs_config->get_rtc_enabled(ruc->req_->vhost); + bool edge = _srs_config->get_vhost_is_edge(ruc->req_->vhost); + + if (rtc_enabled && edge) { + rtc_enabled = false; + srs_warn("disable WebRTC for edge vhost=%s", ruc->req_->vhost.c_str()); + } + if (server_enabled && !rtc_enabled) { srs_warn("RTC disabled in vhost %s", ruc->req_->vhost.c_str()); } diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index bd324d7a3..ac5d135b4 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1248,6 +1248,13 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest* r, SrsRtcSourceDescripti // Bridge to rtmp #if defined(SRS_RTC) && defined(SRS_FFMPEG_FIT) bool rtc_to_rtmp = _srs_config->get_rtc_to_rtmp(req_->vhost); + bool edge = _srs_config->get_vhost_is_edge(req_->vhost); + + if (rtc_to_rtmp && edge) { + rtc_to_rtmp = false; + srs_warn("disable WebRTC to RTMP for edge vhost=%s", req_->vhost.c_str()); + } + if (rtc_to_rtmp) { if ((err = _srs_sources->fetch_or_create(r, _srs_hybrid->srs()->instance(), live_source)) != srs_success) { return srs_error_wrap(err, "create source"); diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index b49b3fc6a..0e79a8c30 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -1083,6 +1083,13 @@ srs_error_t SrsRtmpConn::acquire_publish(SrsSharedPtr source) SrsSharedPtr rtc; bool rtc_server_enabled = _srs_config->get_rtc_server_enabled(); bool rtc_enabled = _srs_config->get_rtc_enabled(req->vhost); + bool edge = _srs_config->get_vhost_is_edge(req->vhost); + + if (rtc_enabled && edge) { + rtc_enabled = false; + srs_warn("disable WebRTC for edge vhost=%s", req->vhost.c_str()); + } + if (rtc_server_enabled && rtc_enabled && !info->edge) { if ((err = _srs_rtc_sources->fetch_or_create(req, rtc)) != srs_success) { return srs_error_wrap(err, "create source"); @@ -1112,7 +1119,13 @@ srs_error_t SrsRtmpConn::acquire_publish(SrsSharedPtr source) // Bridge to RTC streaming. #if defined(SRS_RTC) && defined(SRS_FFMPEG_FIT) - if (rtc.get() && _srs_config->get_rtc_from_rtmp(req->vhost)) { + bool rtmp_to_rtc = _srs_config->get_rtc_from_rtmp(req->vhost); + if (rtmp_to_rtc && edge) { + rtmp_to_rtc = false; + srs_warn("disable RTMP to WebRTC for edge vhost=%s", req->vhost.c_str()); + } + + if (rtc.get() && rtmp_to_rtc) { SrsCompositeBridge* bridge = new SrsCompositeBridge(); bridge->append(new SrsFrameToRtcBridge(rtc)); diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index c17f85f2b..18b62f27a 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1896,7 +1896,7 @@ SrsLiveSource::SrsLiveSource() play_edge = new SrsPlayEdge(); publish_edge = new SrsPublishEdge(); gop_cache = new SrsGopCache(); - hub = new SrsOriginHub(); + hub = NULL; // Will be created conditionally in initialize() if not edge meta = new SrsMetaCache(); format_ = new SrsRtmpFormat(); @@ -1934,18 +1934,21 @@ SrsLiveSource::~SrsLiveSource() void SrsLiveSource::dispose() { - hub->dispose(); + if (hub) { + hub->dispose(); + } meta->dispose(); gop_cache->dispose(); } srs_error_t SrsLiveSource::cycle() { - srs_error_t err = hub->cycle(); - if (err != srs_success) { + srs_error_t err = srs_success; + + if (hub && (err = hub->cycle()) != srs_success) { return srs_error_wrap(err, "hub cycle"); } - + return srs_success; } @@ -1968,7 +1971,7 @@ bool SrsLiveSource::stream_is_dead() } // Origin hub delay cleanup. - if (now < stream_die_at_ + hub->cleanup_delay()) { + if (hub && now < stream_die_at_ + hub->cleanup_delay()) { return false; } @@ -2005,8 +2008,16 @@ srs_error_t SrsLiveSource::initialize(SrsSharedPtr wrapper, SrsRe // Setup the SPS/PPS parsing strategy. format_->try_annexb_first = _srs_config->try_annexb_first(r->vhost); - - if ((err = hub->initialize(wrapper, req)) != srs_success) { + + // Create and initialize origin hub only for origin servers, not edge servers + bool edge = _srs_config->get_vhost_is_edge(req->vhost); + if (!edge) { + srs_freep(hub); + hub = new SrsOriginHub(); + } else { + srs_warn("disable OriginHub creation for edge vhost=%s", req->vhost.c_str()); + } + if (hub && (err = hub->initialize(wrapper, req)) != srs_success) { return srs_error_wrap(err, "hub"); } @@ -2217,7 +2228,11 @@ srs_error_t SrsLiveSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPack } // Copy to hub to all utilities. - return hub->on_meta_data(meta->data(), metadata); + if (hub && (err = hub->on_meta_data(meta->data(), metadata)) != srs_success) { + return srs_error_wrap(err, "hub consume metadata"); + } + + return err; } srs_error_t SrsLiveSource::on_audio(SrsCommonMessage* shared_audio) @@ -2305,7 +2320,7 @@ srs_error_t SrsLiveSource::on_audio_imp(SrsSharedPtrMessage* msg) } // Copy to hub to all utilities. - if ((err = hub->on_audio(msg)) != srs_success) { + if (hub && (err = hub->on_audio(msg)) != srs_success) { return srs_error_wrap(err, "consume audio"); } @@ -2428,7 +2443,7 @@ srs_error_t SrsLiveSource::on_video_imp(SrsSharedPtrMessage* msg) } // Copy to hub to all utilities. - if ((err = hub->on_video(msg, is_sequence_header)) != srs_success) { + if (hub && (err = hub->on_video(msg, is_sequence_header)) != srs_success) { return srs_error_wrap(err, "hub consume video"); } @@ -2586,7 +2601,7 @@ srs_error_t SrsLiveSource::on_publish() last_packet_time = 0; // Notify the hub about the publish event. - if ((err = hub->on_publish()) != srs_success) { + if (hub && (err = hub->on_publish()) != srs_success) { return srs_error_wrap(err, "hub publish"); } @@ -2619,7 +2634,9 @@ void SrsLiveSource::on_unpublish() } // Notify the hub about the unpublish event. - hub->on_unpublish(); + if (hub) { + hub->on_unpublish(); + } // only clear the gop cache, // donot clear the sequence header, for it maybe not changed, @@ -2704,7 +2721,8 @@ srs_error_t SrsLiveSource::consumer_dumps(SrsLiveConsumer* consumer, bool ds, bo } // If stream is publishing, dumps the sequence header and gop cache. - if (hub->active()) { + bool hub_active = hub ? hub->active() : false; + if (hub_active) { // Copy metadata and sequence header to consumer. if ((err = meta->dumps(consumer, atc, jitter_algorithm, dm, ds)) != srs_success) { return srs_error_wrap(err, "meta dumps"); @@ -2718,9 +2736,9 @@ srs_error_t SrsLiveSource::consumer_dumps(SrsLiveConsumer* consumer, bool ds, bo // print status. if (dg) { - srs_trace("create consumer, active=%d, queue_size=%dms, jitter=%d", hub->active(), srsu2msi(queue_size), jitter_algorithm); + srs_trace("create consumer, active=%d, queue_size=%dms, jitter=%d", hub_active, srsu2msi(queue_size), jitter_algorithm); } else { - srs_trace("create consumer, active=%d, ignore gop cache, jitter=%d", hub->active(), jitter_algorithm); + srs_trace("create consumer, active=%d, ignore gop cache, jitter=%d", hub_active, jitter_algorithm); } return err; diff --git a/trunk/src/app/srs_app_srt_conn.cpp b/trunk/src/app/srs_app_srt_conn.cpp index 98a3e09df..594190155 100644 --- a/trunk/src/app/srs_app_srt_conn.cpp +++ b/trunk/src/app/srs_app_srt_conn.cpp @@ -277,7 +277,15 @@ srs_error_t SrsMpegtsSrtConn::do_cycle() req_->vhost = parsed_vhost->arg0(); } - if (! _srs_config->get_srt_enabled(req_->vhost)) { + bool srt_enabled = _srs_config->get_srt_enabled(req_->vhost); + bool edge = _srs_config->get_vhost_is_edge(req_->vhost); + + if (srt_enabled && edge) { + srt_enabled = false; + srs_warn("disable SRT for edge vhost=%s", req_->vhost.c_str()); + } + + if (! srt_enabled) { return srs_error_new(ERROR_SRT_CONN, "srt disabled, vhost=%s", req_->vhost.c_str()); } @@ -393,6 +401,12 @@ srs_error_t SrsMpegtsSrtConn::acquire_publish() bool rtc_server_enabled = _srs_config->get_rtc_server_enabled(); bool rtc_enabled = _srs_config->get_rtc_enabled(req_->vhost); bool edge = _srs_config->get_vhost_is_edge(req_->vhost); + + if (rtc_enabled && edge) { + rtc_enabled = false; + srs_warn("disable WebRTC for edge vhost=%s", req_->vhost.c_str()); + } + if (rtc_server_enabled && rtc_enabled && ! edge) { if ((err = _srs_rtc_sources->fetch_or_create(req_, rtc)) != srs_success) { return srs_error_wrap(err, "create source"); @@ -404,13 +418,25 @@ srs_error_t SrsMpegtsSrtConn::acquire_publish() } #endif - if (_srs_config->get_srt_to_rtmp(req_->vhost)) { + bool srt_to_rtmp = _srs_config->get_srt_to_rtmp(req_->vhost); + if (srt_to_rtmp && edge) { + srt_to_rtmp = false; + srs_warn("disable SRT to RTMP for edge vhost=%s", req_->vhost.c_str()); + } + + if (srt_to_rtmp) { // Bridge to RTMP and RTC streaming. SrsCompositeBridge* bridge = new SrsCompositeBridge(); bridge->append(new SrsFrameToRtmpBridge(live_source)); #if defined(SRS_RTC) && defined(SRS_FFMPEG_FIT) - if (rtc.get() && _srs_config->get_rtc_from_rtmp(req_->vhost)) { + bool rtmp_to_rtc = _srs_config->get_rtc_from_rtmp(req_->vhost); + if (rtmp_to_rtc && edge) { + rtmp_to_rtc = false; + srs_warn("disable RTMP to WebRTC for edge vhost=%s", req_->vhost.c_str()); + } + + if (rtc.get() && rtmp_to_rtc) { bridge->append(new SrsFrameToRtcBridge(rtc)); } #endif diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp index e81210619..2152ad512 100644 --- a/trunk/src/core/srs_core_version6.hpp +++ b/trunk/src/core/srs_core_version6.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 6 #define VERSION_MINOR 0 -#define VERSION_REVISION 178 +#define VERSION_REVISION 179 #endif diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp index 4b4010de2..96940e9de 100644 --- a/trunk/src/utest/srs_utest_config.cpp +++ b/trunk/src/utest/srs_utest_config.cpp @@ -5325,3 +5325,229 @@ VOID TEST(ConfigEnvTest, CheckEnvValuesHooksWithWhitespaces) } } + +VOID TEST(ConfigEdgeWebRTCTest, DisableWebRTCOnEdge) +{ + srs_error_t err; + + // Test that WebRTC configuration is loaded normally on edge servers + // The caller code should handle the edge logic + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "cluster {" + "mode remote;" + "origin 127.0.0.1:19350;" + "}" + "rtc {" + "enabled on;" + "rtmp_to_rtc on;" + "rtc_to_rtmp on;" + "}" + "}")); + + // Verify this is an edge vhost + EXPECT_TRUE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify WebRTC configuration is loaded normally (caller handles edge logic) + EXPECT_TRUE(conf.get_rtc_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_from_rtmp("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_to_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigEdgeWebRTCTest, EnableWebRTCOnOrigin) +{ + srs_error_t err; + + // Test that WebRTC works normally on origin servers + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "rtc {" + "enabled on;" + "rtmp_to_rtc on;" + "rtc_to_rtmp on;" + "}" + "}")); + + // Verify this is NOT an edge vhost + EXPECT_FALSE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify WebRTC is enabled on origin servers + EXPECT_TRUE(conf.get_rtc_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_from_rtmp("__defaultVhost__")); + EXPECT_TRUE(conf.get_rtc_to_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigEdgeWebRTCTest, DisableWebRTCOnEdgeEvenWhenDisabledInConfig) +{ + srs_error_t err; + + // Test that WebRTC configuration is loaded normally even when disabled in config + // The caller code should handle the edge logic + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "cluster {" + "mode remote;" + "origin 127.0.0.1:19350;" + "}" + "rtc {" + "enabled off;" + "rtmp_to_rtc off;" + "rtc_to_rtmp off;" + "}" + "}")); + + // Verify this is an edge vhost + EXPECT_TRUE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify WebRTC configuration reflects the config values (caller handles edge logic) + EXPECT_FALSE(conf.get_rtc_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_rtc_from_rtmp("__defaultVhost__")); + EXPECT_FALSE(conf.get_rtc_to_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigEdgeSRTTest, DisableSRTOnEdge) +{ + srs_error_t err; + + // Test that SRT configuration is loaded normally on edge servers + // The caller code should handle the edge logic + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "cluster {" + "mode remote;" + "origin 127.0.0.1:19350;" + "}" + "srt {" + "enabled on;" + "srt_to_rtmp on;" + "}" + "}")); + + // Verify this is an edge vhost + EXPECT_TRUE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify SRT configuration is loaded normally (caller handles edge logic) + EXPECT_TRUE(conf.get_srt_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_srt_to_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigEdgeSRTTest, EnableSRTOnOrigin) +{ + srs_error_t err; + + // Test that SRT works normally on origin servers + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "srt {" + "enabled on;" + "srt_to_rtmp on;" + "}" + "}")); + + // Verify this is NOT an edge vhost (origin server) + EXPECT_FALSE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify SRT is enabled on origin servers + EXPECT_TRUE(conf.get_srt_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_srt_to_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigEdgeSRTTest, DisableSRTOnEdgeEvenWhenDisabledInConfig) +{ + srs_error_t err; + + // Test that SRT configuration is loaded normally even when disabled in config + // The caller code should handle the edge logic + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "cluster {" + "mode remote;" + "origin 127.0.0.1:19350;" + "}" + "srt {" + "enabled off;" + "srt_to_rtmp off;" + "}" + "}")); + + // Verify this is an edge vhost + EXPECT_TRUE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify SRT configuration reflects the config values (caller handles edge logic) + EXPECT_FALSE(conf.get_srt_enabled("__defaultVhost__")); + EXPECT_FALSE(conf.get_srt_to_rtmp("__defaultVhost__")); + } +} + +VOID TEST(ConfigEdgeOriginHubTest, DisableOriginHubOnEdge) +{ + srs_error_t err; + + // Test that OriginHub components (HLS, DVR, etc.) are disabled on edge servers + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "cluster {" + "mode remote;" + "origin 127.0.0.1:19350;" + "}" + "hls {" + "enabled on;" + "}" + "dvr {" + "enabled on;" + "}" + "}")); + + // Verify this is an edge vhost + EXPECT_TRUE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify OriginHub components configuration is loaded normally (OriginHub handles edge logic) + EXPECT_TRUE(conf.get_hls_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_dvr_enabled("__defaultVhost__")); + } +} + +VOID TEST(ConfigEdgeOriginHubTest, EnableOriginHubOnOrigin) +{ + srs_error_t err; + + // Test that OriginHub components work normally on origin servers + if (true) { + MockSrsConfig conf; + HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF + "vhost __defaultVhost__ {" + "hls {" + "enabled on;" + "}" + "dvr {" + "enabled on;" + "}" + "}")); + + // Verify this is NOT an edge vhost (origin server) + EXPECT_FALSE(conf.get_vhost_is_edge("__defaultVhost__")); + + // Verify OriginHub components are enabled on origin servers + EXPECT_TRUE(conf.get_hls_enabled("__defaultVhost__")); + EXPECT_TRUE(conf.get_dvr_enabled("__defaultVhost__")); + } +}