diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs
index ec87160293..9a2d524d16 100644
--- a/Emby.Dlna/Main/DlnaEntryPoint.cs
+++ b/Emby.Dlna/Main/DlnaEntryPoint.cs
@@ -316,7 +316,7 @@ namespace Emby.Dlna.Main
_logger.LogInformation("Registering publisher for {0} on {1}", fullService, address);
var uri = new UriBuilder(_appHost.GetSmartApiUrl(address.Address) + descriptorUri);
- if (_appHost.PublishedServerUrl == null)
+ if (!string.IsNullOrEmpty(_appHost.PublishedServerUrl))
{
// DLNA will only work over http, so we must reset to http:// : {port}.
uri.Scheme = "http";
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 2ba585d304..aa7ddd7249 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -43,6 +43,7 @@ using Emby.Server.Implementations.Serialization;
using Emby.Server.Implementations.Session;
using Emby.Server.Implementations.SyncPlay;
using Emby.Server.Implementations.TV;
+using Emby.Server.Implementations.Udp;
using Emby.Server.Implementations.Updates;
using Jellyfin.Api.Helpers;
using Jellyfin.Networking.Configuration;
@@ -98,6 +99,7 @@ using MediaBrowser.Providers.Subtitles;
using MediaBrowser.XbmcMetadata.Providers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Prometheus.DotNetRuntime;
@@ -117,6 +119,7 @@ namespace Emby.Server.Implementations
private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" };
private readonly IFileSystem _fileSystemManager;
+ private readonly IConfiguration _startupConfig;
private readonly IXmlSerializer _xmlSerializer;
private readonly IJsonSerializer _jsonSerializer;
private readonly IStartupOptions _startupOptions;
@@ -134,9 +137,6 @@ namespace Emby.Server.Implementations
public bool CoreStartupHasCompleted { get; private set; }
- ///
- public Uri PublishedServerUrl => _startupOptions.PublishedServerUrl;
-
public virtual bool CanLaunchWebBrowser
{
get
@@ -230,6 +230,11 @@ namespace Emby.Server.Implementations
///
public int HttpsPort { get; private set; }
+ ///
+ /// Gets the value of the PublishedServerUrl setting.
+ ///
+ public string PublishedServerUrl => _startupOptions.PublishedServerUrl ?? _startupConfig[UdpServer.AddressOverrideConfigKey];
+
///
/// Gets the server configuration manager.
///
@@ -242,12 +247,14 @@ namespace Emby.Server.Implementations
/// Instance of the interface.
/// Instance of the interface.
/// Instance of the interface.
+ /// The interface.
/// Instance of the interface.
/// Instance of the interface.
public ApplicationHost(
IServerApplicationPaths applicationPaths,
ILoggerFactory loggerFactory,
IStartupOptions options,
+ IConfiguration startupConfig,
IFileSystem fileSystem,
IServiceCollection serviceCollection)
{
@@ -271,6 +278,7 @@ namespace Emby.Server.Implementations
Logger = LoggerFactory.CreateLogger();
_startupOptions = options;
+ _startupConfig = startupConfig;
// Initialize runtime stat collection
if (ServerConfigurationManager.Configuration.EnableMetrics)
@@ -1151,10 +1159,10 @@ namespace Emby.Server.Implementations
public string GetSmartApiUrl(IPAddress ipAddress, int? port = null)
{
// Published server ends with a /
- if (_startupOptions.PublishedServerUrl != null)
+ if (!string.IsNullOrEmpty(PublishedServerUrl))
{
// Published server ends with a '/', so we need to remove it.
- return _startupOptions.PublishedServerUrl.ToString().Trim('/');
+ return PublishedServerUrl.Trim('/');
}
string smart = NetManager.GetBindInterface(ipAddress, out port);
@@ -1171,10 +1179,10 @@ namespace Emby.Server.Implementations
public string GetSmartApiUrl(HttpRequest request, int? port = null)
{
// Published server ends with a /
- if (_startupOptions.PublishedServerUrl != null)
+ if (!string.IsNullOrEmpty(PublishedServerUrl))
{
// Published server ends with a '/', so we need to remove it.
- return _startupOptions.PublishedServerUrl.ToString().Trim('/');
+ return PublishedServerUrl.Trim('/');
}
string smart = NetManager.GetBindInterface(request, out port);
@@ -1191,10 +1199,10 @@ namespace Emby.Server.Implementations
public string GetSmartApiUrl(string hostname, int? port = null)
{
// Published server ends with a /
- if (_startupOptions.PublishedServerUrl != null)
+ if (!string.IsNullOrEmpty(PublishedServerUrl))
{
// Published server ends with a '/', so we need to remove it.
- return _startupOptions.PublishedServerUrl.ToString().Trim('/');
+ return PublishedServerUrl.Trim('/');
}
string smart = NetManager.GetBindInterface(hostname, out port);
diff --git a/Emby.Server.Implementations/IStartupOptions.cs b/Emby.Server.Implementations/IStartupOptions.cs
index 4bef59543f..0b823ff063 100644
--- a/Emby.Server.Implementations/IStartupOptions.cs
+++ b/Emby.Server.Implementations/IStartupOptions.cs
@@ -1,5 +1,5 @@
#pragma warning disable CS1591
-
+#nullable enable
using System;
namespace Emby.Server.Implementations
@@ -9,7 +9,7 @@ namespace Emby.Server.Implementations
///
/// Gets the value of the --ffmpeg command line option.
///
- string FFmpegPath { get; }
+ string? FFmpegPath { get; }
///
/// Gets the value of the --service command line option.
@@ -19,21 +19,21 @@ namespace Emby.Server.Implementations
///
/// Gets the value of the --package-name command line option.
///
- string PackageName { get; }
+ string? PackageName { get; }
///
/// Gets the value of the --restartpath command line option.
///
- string RestartPath { get; }
+ string? RestartPath { get; }
///
/// Gets the value of the --restartargs command line option.
///
- string RestartArgs { get; }
+ string? RestartArgs { get; }
///
/// Gets the value of the --published-server-url command line option.
///
- Uri PublishedServerUrl { get; }
+ string? PublishedServerUrl { get; }
}
}
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index b76aa5e141..1daa32deea 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -21,6 +21,7 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.IO;
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -37,18 +38,21 @@ namespace Jellyfin.Server
/// The to be used by the .
/// The to be used by the .
/// The to be used by the .
+ /// The to be used by the .
/// The to be used by the .
/// The to be used by the .
public CoreAppHost(
IServerApplicationPaths applicationPaths,
ILoggerFactory loggerFactory,
IStartupOptions options,
+ IConfiguration startupConfig,
IFileSystem fileSystem,
IServiceCollection collection)
: base(
applicationPaths,
loggerFactory,
options,
+ startupConfig,
fileSystem,
collection)
{
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 6823a43016..0517b6a2f3 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -164,6 +164,7 @@ namespace Jellyfin.Server
appPaths,
_loggerFactory,
options,
+ startupConfig,
new ManagedFileSystem(_loggerFactory.CreateLogger(), appPaths),
serviceCollection);
diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs
index b634340927..6d8210527c 100644
--- a/Jellyfin.Server/StartupOptions.cs
+++ b/Jellyfin.Server/StartupOptions.cs
@@ -77,7 +77,7 @@ namespace Jellyfin.Server
///
[Option("published-server-url", Required = false, HelpText = "Jellyfin Server URL to publish via auto discover process")]
- public Uri? PublishedServerUrl { get; set; }
+ public string? PublishedServerUrl { get; set; }
///
/// Gets the command line options as a dictionary that can be used in the .NET configuration system.
@@ -94,7 +94,7 @@ namespace Jellyfin.Server
if (PublishedServerUrl != null)
{
- config.Add(UdpServer.AddressOverrideConfigKey, PublishedServerUrl.ToString());
+ config.Add(UdpServer.AddressOverrideConfigKey, PublishedServerUrl);
}
if (FFmpegPath != null)
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index 6378625e87..20bfa697e5 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -55,7 +55,7 @@ namespace MediaBrowser.Controller
///
/// Gets the configured published server url.
///
- Uri PublishedServerUrl { get; }
+ string PublishedServerUrl { get; }
///
/// Gets the system info.
diff --git a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
index 54f8eb225f..262e8f9120 100644
--- a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
+++ b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Common;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
@@ -77,6 +78,7 @@ namespace Jellyfin.Api.Tests
appPaths,
loggerFactory,
commandLineOpts,
+ new ConfigurationBuilder().Build(),
new ManagedFileSystem(loggerFactory.CreateLogger(), appPaths),
serviceCollection);
_disposableComponents.Add(appHost);
diff --git a/tests/Jellyfin.Api.Tests/TestAppHost.cs b/tests/Jellyfin.Api.Tests/TestAppHost.cs
new file mode 100644
index 0000000000..eb4c9b3055
--- /dev/null
+++ b/tests/Jellyfin.Api.Tests/TestAppHost.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+using System.Reflection;
+using Emby.Server.Implementations;
+using Jellyfin.Server;
+using MediaBrowser.Controller;
+using MediaBrowser.Model.IO;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace Jellyfin.Api.Tests
+{
+ ///
+ /// Implementation of the abstract class.
+ ///
+ public class TestAppHost : CoreAppHost
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The to be used by the .
+ /// The to be used by the .
+ /// The to be used by the .
+ /// The to be used by the .
+ /// The to be used by the .
+ /// The to be used by the .
+ public TestAppHost(
+ IServerApplicationPaths applicationPaths,
+ ILoggerFactory loggerFactory,
+ IStartupOptions options,
+ IConfiguration startup,
+ IFileSystem fileSystem,
+ IServiceCollection collection)
+ : base(
+ applicationPaths,
+ loggerFactory,
+ options,
+ startup,
+ fileSystem,
+ collection)
+ {
+ }
+
+ ///
+ protected override IEnumerable GetAssembliesWithPartsInternal()
+ {
+ foreach (var a in base.GetAssembliesWithPartsInternal())
+ {
+ yield return a;
+ }
+
+ yield return typeof(TestPlugin).Assembly;
+ }
+ }
+}