Merge branch 'master' of github.com:duplicati/duplicati
This commit is contained in:
@@ -450,6 +450,11 @@ namespace Duplicati.Library.Backend.AlternativeFTP
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
private static System.IO.Stream StringToStream(string str)
|
||||
{
|
||||
var stream = new System.IO.MemoryStream();
|
||||
|
||||
@@ -457,6 +457,12 @@ namespace Duplicati.Library.Backend.AmazonCloudDrive
|
||||
return Strings.AmzCD.Description;
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region IDisposable implementation
|
||||
public void Dispose()
|
||||
|
||||
@@ -157,8 +157,13 @@ namespace Duplicati.Library.Backend.AzureBlob
|
||||
{
|
||||
return Strings.AzureBlobBackend.Description_v2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Test()
|
||||
{
|
||||
this.TestList();
|
||||
|
||||
@@ -422,6 +422,11 @@ namespace Duplicati.Library.Backend.Backblaze
|
||||
get { return Strings.B2.Description; }
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -337,6 +337,11 @@ namespace Duplicati.Library.Backend.Box
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable implementation
|
||||
|
||||
@@ -290,6 +290,11 @@ namespace Duplicati.Library.Backend
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Get(string remotename, System.IO.Stream stream)
|
||||
{
|
||||
var req = CreateRequest("/" + remotename, "");
|
||||
|
||||
@@ -136,6 +136,11 @@ namespace Duplicati.Library.Backend
|
||||
|
||||
public string Description { get { return Strings.Dropbox.Description; } }
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Test()
|
||||
{
|
||||
this.TestList();
|
||||
|
||||
@@ -355,6 +355,11 @@ namespace Duplicati.Library.Backend
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Test()
|
||||
{
|
||||
this.TestList();
|
||||
|
||||
@@ -351,6 +351,11 @@ namespace Duplicati.Library.Backend
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Rename(string oldname, string newname)
|
||||
{
|
||||
var source = GetRemoteName(oldname);
|
||||
|
||||
@@ -260,6 +260,12 @@ namespace Duplicati.Library.Backend.GoogleCloudStorage
|
||||
{
|
||||
get { return Strings.GoogleCloudStorage.Description; }
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Put(string remotename, System.IO.Stream stream)
|
||||
|
||||
@@ -346,6 +346,12 @@ namespace Duplicati.Library.Backend.GoogleDrive
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRenameEnabledBackend implementation
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2015, The Duplicati Team
|
||||
// Copyright (C) 2015, The Duplicati Team
|
||||
// http://www.duplicati.com, info@duplicati.com
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
@@ -14,13 +14,181 @@
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
using System;
|
||||
using System;
|
||||
using Duplicati.Library.Interface;
|
||||
using Duplicati.Library;
|
||||
using Duplicati.Library.Backend.OpenStack;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Duplicati.Library.Backend.HubiC
|
||||
{
|
||||
public class HubiCBackend : IBackend, IStreamingBackend
|
||||
|
||||
namespace Duplicati.Library.Backend.HubiC
|
||||
{
|
||||
public class HubiCBackend : IBackend, IStreamingBackend
|
||||
{
|
||||
private const string AUTHID_OPTION = "authid";
|
||||
private const string HUBIC_API_URL = "https://api.hubic.com/1.0/";
|
||||
private const string HUBIC_API_CREDENTIAL_URL = HUBIC_API_URL + "account/credentials";
|
||||
|
||||
private OpenStackStorage m_openstack;
|
||||
|
||||
private class HubiCAuthResponse
|
||||
{
|
||||
public string token { get; set; }
|
||||
public string endpoint { get; set; }
|
||||
public DateTime? expires { get; set;}
|
||||
}
|
||||
|
||||
private class OpenStackHelper : OpenStackStorage
|
||||
{
|
||||
private OAuthHelper m_helper;
|
||||
private HubiCAuthResponse m_token;
|
||||
|
||||
public OpenStackHelper(string authid, string url)
|
||||
: base(url, MockOptions())
|
||||
{
|
||||
m_helper = new OAuthHelper(authid, "hubic") { AutoAuthHeader = true };
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> MockOptions()
|
||||
{
|
||||
var res = new Dictionary<string, string>();
|
||||
res["openstack-authuri"] = "invalid://dont-use";
|
||||
res["openstack-apikey"] = "invalid";
|
||||
res["auth-username"] = "invalid";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private HubiCAuthResponse AuthToken
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_token == null || (m_token.expires != null && (m_token.expires.Value - DateTime.UtcNow).TotalSeconds < 30))
|
||||
m_token = m_helper.ReadJSONResponse<HubiCAuthResponse>(HUBIC_API_CREDENTIAL_URL);
|
||||
return m_token;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string AccessToken
|
||||
{
|
||||
get { return AuthToken.token; }
|
||||
}
|
||||
|
||||
protected override string SimpleStorageEndPoint
|
||||
{
|
||||
get { return AuthToken.endpoint; }
|
||||
}
|
||||
}
|
||||
|
||||
public HubiCBackend()
|
||||
{
|
||||
}
|
||||
|
||||
public HubiCBackend(string url, Dictionary<string, string> options)
|
||||
{
|
||||
string authid = null;
|
||||
if (options.ContainsKey(AUTHID_OPTION))
|
||||
authid = options[AUTHID_OPTION];
|
||||
|
||||
m_openstack = new OpenStackHelper(authid, url);
|
||||
}
|
||||
|
||||
#region IStreamingBackend implementation
|
||||
|
||||
public void Put(string remotename, System.IO.Stream stream)
|
||||
{
|
||||
m_openstack.Put(remotename, stream);
|
||||
}
|
||||
|
||||
public void Get(string remotename, System.IO.Stream stream)
|
||||
{
|
||||
m_openstack.Get(remotename, stream);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBackend implementation
|
||||
|
||||
public IEnumerable<IFileEntry> List()
|
||||
{
|
||||
return m_openstack.List();
|
||||
}
|
||||
|
||||
public void Put(string remotename, string filename)
|
||||
{
|
||||
m_openstack.Put(remotename, filename);
|
||||
}
|
||||
|
||||
public void Get(string remotename, string filename)
|
||||
{
|
||||
m_openstack.Get(remotename, filename);
|
||||
}
|
||||
|
||||
public void Delete(string remotename)
|
||||
{
|
||||
m_openstack.Delete(remotename);
|
||||
}
|
||||
|
||||
public void Test()
|
||||
{
|
||||
m_openstack.Test();
|
||||
}
|
||||
|
||||
public void CreateFolder()
|
||||
{
|
||||
m_openstack.CreateFolder();
|
||||
}
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Strings.HubiC.DisplayName;
|
||||
}
|
||||
}
|
||||
|
||||
public string ProtocolKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return "hubic";
|
||||
}
|
||||
}
|
||||
|
||||
public System.Collections.Generic.IList<ICommandLineArgument> SupportedCommands
|
||||
{
|
||||
get {
|
||||
return new List<ICommandLineArgument>(new ICommandLineArgument[] {
|
||||
new CommandLineArgument(AUTHID_OPTION, CommandLineArgument.ArgumentType.Password, Strings.HubiC.AuthidShort, Strings.HubiC.AuthidLong(OAuthHelper.OAUTH_LOGIN_URL("hubic"))),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return Strings.HubiC.Description;
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable implementation
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_openstack != null)
|
||||
{
|
||||
m_openstack.Dispose();
|
||||
m_openstack = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,8 +316,13 @@ namespace Duplicati.Library.Backend
|
||||
public bool SupportsStreaming
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Get(string remotename, System.IO.Stream stream)
|
||||
{
|
||||
// Downloading from Jottacloud: Will only succeed if the file has a completed revision,
|
||||
|
||||
@@ -260,6 +260,11 @@ namespace Duplicati.Library.Backend.Mega
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable implementation
|
||||
|
||||
@@ -500,7 +500,12 @@ namespace Duplicati.Library.Backend
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IStreamingBackend Members
|
||||
|
||||
|
||||
@@ -422,6 +422,12 @@ namespace Duplicati.Library.Backend.OpenStack
|
||||
return Strings.OpenStack.Description;
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region IDisposable implementation
|
||||
public void Dispose()
|
||||
|
||||
@@ -282,8 +282,13 @@ namespace Duplicati.Library.Backend
|
||||
{
|
||||
return Strings.Rclone.Description;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Test()
|
||||
{
|
||||
this.TestList();
|
||||
|
||||
@@ -474,6 +474,11 @@ namespace Duplicati.Library.Backend
|
||||
get { return m_wrapper; }
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
private string GetFullKey(string name)
|
||||
{
|
||||
//AWS SDK encodes the filenames correctly
|
||||
|
||||
@@ -368,5 +368,10 @@ namespace Duplicati.Library.Backend
|
||||
return m_con;
|
||||
}
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,12 +113,17 @@ namespace Duplicati.Library.Backend
|
||||
new CommandLineArgument("chunk-size", CommandLineArgument.ArgumentType.Size, Strings.SharePoint.DescriptionChunkSizeShort, Strings.SharePoint.DescriptionChunkSizeLong, "4mb"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region [Constructors]
|
||||
|
||||
|
||||
public SharePointBackend()
|
||||
{ }
|
||||
|
||||
|
||||
@@ -438,12 +438,17 @@ namespace Duplicati.Library.Backend.Sia
|
||||
{
|
||||
return Strings.Sia.Description;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
|
||||
@@ -254,6 +254,11 @@ namespace Duplicati.Library.Backend
|
||||
get { return Strings.TahoeBackend.Description; }
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace Duplicati.Library.Backend
|
||||
private string m_reverseProtocolUrl;
|
||||
private string m_rawurl;
|
||||
private string m_rawurlPort;
|
||||
private string m_dnsName;
|
||||
private bool m_useIntegratedAuthentication = false;
|
||||
private bool m_forceDigestAuthentication = false;
|
||||
private bool m_useSSL = false;
|
||||
@@ -61,6 +62,7 @@ namespace Duplicati.Library.Backend
|
||||
{
|
||||
var u = new Utility.Uri(url);
|
||||
u.RequireHost();
|
||||
m_dnsName = u.Host;
|
||||
|
||||
if (!string.IsNullOrEmpty(u.Username))
|
||||
{
|
||||
@@ -311,6 +313,11 @@ namespace Duplicati.Library.Backend
|
||||
get { return Strings.WEBDAV.Description; }
|
||||
}
|
||||
|
||||
public string DNSName
|
||||
{
|
||||
get { return m_dnsName; }
|
||||
}
|
||||
|
||||
public void Test()
|
||||
{
|
||||
this.List();
|
||||
|
||||
@@ -81,6 +81,11 @@ namespace Duplicati.Library.Interface
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The DNS name used to resolve the IP address for this backend
|
||||
/// </summary>
|
||||
string DNSName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The purpose of this method is to test the connection to the remote backend.
|
||||
/// If any problem is encountered, this method should throw an exception.
|
||||
|
||||
@@ -519,6 +519,22 @@ namespace Duplicati.Library.Main
|
||||
throw;
|
||||
}
|
||||
|
||||
if (ex is System.Net.WebException)
|
||||
{
|
||||
// Refresh DNS name if we fail to connect in order to prevent issues with incorrect DNS entries
|
||||
if (((System.Net.WebException)ex).Status == System.Net.WebExceptionStatus.NameResolutionFailure)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(m_backend.DNSName))
|
||||
System.Net.Dns.GetHostEntry(m_backend.DNSName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_statwriter.SendEvent(item.BackendActionType, retries < m_numberofretries ? BackendEventType.Retrying : BackendEventType.Failed, item.RemoteFilename, item.Size);
|
||||
|
||||
bool recovered = false;
|
||||
|
||||
Reference in New Issue
Block a user