diff --git a/Duplicati/Library/Backend/Duplicati/DuplicatiBackend.cs b/Duplicati/Library/Backend/Duplicati/DuplicatiBackend.cs index fcbf9b083..3401b7ab2 100644 --- a/Duplicati/Library/Backend/Duplicati/DuplicatiBackend.cs +++ b/Duplicati/Library/Backend/Duplicati/DuplicatiBackend.cs @@ -47,6 +47,15 @@ public class DuplicatiBackend : IBackend, IStreamingBackend, IQuotaEnabledBacken /// The endpoint option name /// public const string ENDPOINT_OPTION = "duplicati-endpoint"; + /// + /// The authentication timeout option name + /// + public const string AUTH_TIMEOUT_OPTION = "duplicati-auth-timeout"; + + /// + /// The default authentication timeout + /// + public const string DEFAULT_AUTH_TIMEOUT = "120s"; /// /// The protocol key for this backend @@ -79,6 +88,10 @@ public class DuplicatiBackend : IBackend, IStreamingBackend, IQuotaEnabledBacken /// The backup id /// private readonly string _backup_id; + /// + /// The authentication timeout + /// + private readonly TimeSpan _authTimeout; /// /// The HttpClient used for requests @@ -147,6 +160,8 @@ public class DuplicatiBackend : IBackend, IStreamingBackend, IQuotaEnabledBacken _auth = AuthOptionsHelper.ParseWithAlias(options, new Utility.Uri(url), AUTH_API_ID_OPTION, AUTH_API_KEY_OPTION) .RequireCredentials(); + _authTimeout = Utility.Utility.ParseTimespanOption(options, AUTH_TIMEOUT_OPTION, DEFAULT_AUTH_TIMEOUT); + _client.DefaultRequestHeaders.Add("X-Api-Key", _auth.Password); _client.DefaultRequestHeaders.Add("X-Organization-Id", _auth.Username); _client.DefaultRequestHeaders.Add("X-Machine-Id", System.Uri.EscapeDataString(AutoUpdater.DataFolderManager.MachineID)); @@ -237,7 +252,7 @@ public class DuplicatiBackend : IBackend, IStreamingBackend, IQuotaEnabledBacken return; using var request = new HttpRequestMessage(HttpMethod.Get, "/credentials"); - using var response = await Utility.Utility.WithTimeout(_timeouts.ShortTimeout, cancelToken, ct => + using var response = await Utility.Utility.WithTimeout(_authTimeout, cancelToken, ct => _client.SendAsync(request, ct) ).ConfigureAwait(false); response.EnsureSuccessStatusCode(); @@ -474,6 +489,7 @@ public class DuplicatiBackend : IBackend, IStreamingBackend, IQuotaEnabledBacken new CommandLineArgument(AUTH_API_KEY_OPTION, CommandLineArgument.ArgumentType.Password, Strings.DuplicatiBackend.AuthKeyOptionsShort, Strings.DuplicatiBackend.AuthKeyOptionsLong, null, [AuthOptionsHelper.AuthPasswordOption]), new CommandLineArgument(BACKUP_ID_OPTION, CommandLineArgument.ArgumentType.String, Strings.DuplicatiBackend.BackupIdOptionsShort, Strings.DuplicatiBackend.BackupIdOptionsLong), new CommandLineArgument(ENDPOINT_OPTION, CommandLineArgument.ArgumentType.String, Strings.DuplicatiBackend.EndpointOptionsShort, Strings.DuplicatiBackend.EndpointOptionsLong), + new CommandLineArgument(AUTH_TIMEOUT_OPTION, CommandLineArgument.ArgumentType.Timespan, Strings.DuplicatiBackend.AuthTimeoutOptionsShort, Strings.DuplicatiBackend.AuthTimeoutOptionsLong, DEFAULT_AUTH_TIMEOUT), .. TimeoutOptionsHelper.GetOptions() ]; diff --git a/Duplicati/Library/Backend/Duplicati/Strings.cs b/Duplicati/Library/Backend/Duplicati/Strings.cs index 6b9cbe157..7a67d7caa 100644 --- a/Duplicati/Library/Backend/Duplicati/Strings.cs +++ b/Duplicati/Library/Backend/Duplicati/Strings.cs @@ -36,6 +36,8 @@ internal static class DuplicatiBackend public static string BackupIdOptionsLong { get { return LC.L(@"Each backupID identifies a separate backup set on the Duplicati storage server."); } } public static string EndpointOptionsShort { get { return LC.L(@"The URL of the Duplicati storage server."); } } public static string EndpointOptionsLong { get { return LC.L(@"Specifies the URL of the Duplicati storage server."); } } + public static string AuthTimeoutOptionsShort { get { return LC.L(@"The timeout for authentication requests."); } } + public static string AuthTimeoutOptionsLong { get { return LC.L(@"Specifies the timeout for authentication requests."); } } public static string ErrorMissingBackupId { get { return LC.L(@"A unique backup id must be specified"); } } }