| | 1 | | using System; |
| | 2 | | using System.IO; |
| | 3 | | using System.Xml; |
| | 4 | | using System.Xml.Serialization; |
| | 5 | | using Emby.Server.Implementations; |
| | 6 | | using Microsoft.Extensions.Logging; |
| | 7 | |
|
| | 8 | | namespace Jellyfin.Server.Migrations.PreStartupRoutines; |
| | 9 | |
|
| | 10 | | /// <inheritdoc /> |
| | 11 | | #pragma warning disable CS0618 // Type or member is obsolete |
| | 12 | | [JellyfinMigration("2025-04-20T00:00:00", nameof(CreateNetworkConfiguration), "9B354818-94D5-4B68-AC49-E35CB85F9D84", St |
| | 13 | | public class CreateNetworkConfiguration : IMigrationRoutine |
| | 14 | | #pragma warning restore CS0618 // Type or member is obsolete |
| | 15 | | { |
| | 16 | | private readonly ServerApplicationPaths _applicationPaths; |
| | 17 | | private readonly ILogger<CreateNetworkConfiguration> _logger; |
| | 18 | |
|
| | 19 | | /// <summary> |
| | 20 | | /// Initializes a new instance of the <see cref="CreateNetworkConfiguration"/> class. |
| | 21 | | /// </summary> |
| | 22 | | /// <param name="applicationPaths">An instance of <see cref="ServerApplicationPaths"/>.</param> |
| | 23 | | /// <param name="loggerFactory">An instance of the <see cref="ILoggerFactory"/> interface.</param> |
| | 24 | | public CreateNetworkConfiguration(ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory) |
| | 25 | | { |
| 0 | 26 | | _applicationPaths = applicationPaths; |
| 0 | 27 | | _logger = loggerFactory.CreateLogger<CreateNetworkConfiguration>(); |
| 0 | 28 | | } |
| | 29 | |
|
| | 30 | | /// <inheritdoc /> |
| | 31 | | public void Perform() |
| | 32 | | { |
| 0 | 33 | | string path = Path.Combine(_applicationPaths.ConfigurationDirectoryPath, "network.xml"); |
| 0 | 34 | | if (File.Exists(path)) |
| | 35 | | { |
| 0 | 36 | | _logger.LogDebug("Network configuration file already exists, skipping"); |
| 0 | 37 | | return; |
| | 38 | | } |
| | 39 | |
|
| 0 | 40 | | var serverConfigSerializer = new XmlSerializer(typeof(OldNetworkConfiguration), new XmlRootAttribute("ServerConf |
| 0 | 41 | | using var xmlReader = XmlReader.Create(_applicationPaths.SystemConfigurationFilePath); |
| 0 | 42 | | var networkSettings = serverConfigSerializer.Deserialize(xmlReader); |
| | 43 | |
|
| 0 | 44 | | var networkConfigSerializer = new XmlSerializer(typeof(OldNetworkConfiguration), new XmlRootAttribute("NetworkCo |
| 0 | 45 | | var xmlWriterSettings = new XmlWriterSettings { Indent = true }; |
| 0 | 46 | | using var xmlWriter = XmlWriter.Create(path, xmlWriterSettings); |
| 0 | 47 | | networkConfigSerializer.Serialize(xmlWriter, networkSettings); |
| 0 | 48 | | } |
| | 49 | |
|
| | 50 | | #pragma warning disable |
| | 51 | | public sealed class OldNetworkConfiguration |
| | 52 | | { |
| | 53 | | public const int DefaultHttpPort = 8096; |
| | 54 | |
|
| | 55 | | public const int DefaultHttpsPort = 8920; |
| | 56 | |
|
| 0 | 57 | | private string _baseUrl = string.Empty; |
| | 58 | |
|
| | 59 | | public bool RequireHttps { get; set; } |
| | 60 | |
|
| | 61 | | public string CertificatePath { get; set; } = string.Empty; |
| | 62 | |
|
| | 63 | | public string CertificatePassword { get; set; } = string.Empty; |
| | 64 | |
|
| | 65 | | public string BaseUrl |
| | 66 | | { |
| 0 | 67 | | get => _baseUrl; |
| | 68 | | set |
| | 69 | | { |
| | 70 | | // Normalize the start of the string |
| 0 | 71 | | if (string.IsNullOrWhiteSpace(value)) |
| | 72 | | { |
| | 73 | | // If baseUrl is empty, set an empty prefix string |
| 0 | 74 | | _baseUrl = string.Empty; |
| 0 | 75 | | return; |
| | 76 | | } |
| | 77 | |
|
| 0 | 78 | | if (value[0] != '/') |
| | 79 | | { |
| | 80 | | // If baseUrl was not configured with a leading slash, append one for consistency |
| 0 | 81 | | value = "/" + value; |
| | 82 | | } |
| | 83 | |
|
| | 84 | | // Normalize the end of the string |
| 0 | 85 | | if (value[^1] == '/') |
| | 86 | | { |
| | 87 | | // If baseUrl was configured with a trailing slash, remove it for consistency |
| 0 | 88 | | value = value.Remove(value.Length - 1); |
| | 89 | | } |
| | 90 | |
|
| 0 | 91 | | _baseUrl = value; |
| 0 | 92 | | } |
| | 93 | | } |
| | 94 | |
|
| | 95 | | public int PublicHttpsPort { get; set; } = DefaultHttpsPort; |
| | 96 | |
|
| | 97 | | public int HttpServerPortNumber { get; set; } = DefaultHttpPort; |
| | 98 | |
|
| | 99 | | public int HttpsPortNumber { get; set; } = DefaultHttpsPort; |
| | 100 | |
|
| | 101 | | public bool EnableHttps { get; set; } |
| | 102 | |
|
| | 103 | | public int PublicPort { get; set; } = DefaultHttpPort; |
| | 104 | |
|
| | 105 | | public bool EnableIPV6 { get; set; } |
| | 106 | |
|
| | 107 | | public bool EnableIPV4 { get; set; } = true; |
| | 108 | |
|
| | 109 | | public bool IgnoreVirtualInterfaces { get; set; } = true; |
| | 110 | |
|
| 0 | 111 | | public string[] VirtualInterfaceNames { get; set; } = new string[] { "veth" }; |
| | 112 | |
|
| | 113 | | public string[] PublishedServerUriBySubnet { get; set; } = Array.Empty<string>(); |
| | 114 | |
|
| | 115 | | public string[] RemoteIPFilter { get; set; } = Array.Empty<string>(); |
| | 116 | |
|
| | 117 | | public bool IsRemoteIPFilterBlacklist { get; set; } |
| | 118 | |
|
| | 119 | | public bool EnableUPnP { get; set; } |
| | 120 | |
|
| | 121 | | public bool EnableRemoteAccess { get; set; } = true; |
| | 122 | |
|
| | 123 | | public string[] LocalNetworkSubnets { get; set; } = Array.Empty<string>(); |
| | 124 | |
|
| | 125 | | public string[] LocalNetworkAddresses { get; set; } = Array.Empty<string>(); |
| | 126 | |
|
| | 127 | | public string[] KnownProxies { get; set; } = Array.Empty<string>(); |
| | 128 | | } |
| | 129 | | } |