Skip to content
Permalink
Browse files

Update AlternativeFtp Backend for async Put

Removed System.Net.FtpClient and added the FluentFTP Nuget package which
is the new name of System.Net.FtpClient.
  • Loading branch information...
seantempleton committed Feb 17, 2019
1 parent 0c122ff commit 662627a98a908a8f7f7ec3ad6db2d845728c69be
@@ -1,7 +1,29 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup>
</configuration>
@@ -1,3 +1,28 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Large diffs are not rendered by default.

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -1,9 +1,31 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true"/>
<loadFromRemoteSources enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -52,5 +52,8 @@
<Name>Duplicati.Library.SQLiteHelper</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -1,7 +1,29 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<loadFromRemoteSources enabled="true"/>
<loadFromRemoteSources enabled="true" />
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.KeyVault.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup>
</configuration>
@@ -20,17 +20,18 @@

using Duplicati.Library.Common.IO;
using Duplicati.Library.Interface;
using FluentFTP;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.FtpClient;
using System.Net.Security;
using System.Security.Authentication;
using System.Threading;
using System.Threading.Tasks;
using CoreUtility = Duplicati.Library.Utility.Utility;
using Uri = System.Uri;

using Uri = System.Uri;

namespace Duplicati.Library.Backend.AlternativeFTP
{
// ReSharper disable once RedundantExtendsListEntry
@@ -306,7 +307,7 @@ private IEnumerable<IFileEntry> List(string filename, bool stripFile)
return list;
}

public Task Put(string remotename, System.IO.Stream input, CancellationToken cancelToken)
public async Task Put(string remotename, Stream input, CancellationToken cancelToken)
{
string remotePath = remotename;
long streamLen = -1;
@@ -320,10 +321,7 @@ public Task Put(string remotename, System.IO.Stream input, CancellationToken can
streamLen = input.Length;
}
// ReSharper disable once EmptyGeneralCatchClause
catch
{

}
catch { }

// Get the remote path
remotePath = "";
@@ -334,19 +332,12 @@ public Task Put(string remotename, System.IO.Stream input, CancellationToken can
remotePath += remotename;
}

using (var outputStream = ftpClient.OpenWrite(remotePath))
var success = await ftpClient.UploadAsync(input, remotePath, FtpExists.Overwrite, createRemoteDir: false, token: cancelToken, progress: null).ConfigureAwait(false);
if (!success)
{
try
{
CoreUtility.CopyStream(input, outputStream, true, _copybuffer);
}
finally
{
outputStream.Close();
}
throw new UserInformationException(string.Format(Strings.ErrorWriteFile, remotename), "AftpPutFailure");
}


if (_listVerify)
{
var fileEntries = List(remotename, true);
@@ -357,7 +348,7 @@ public Task Put(string remotename, System.IO.Stream input, CancellationToken can
{
if (fileEntry.Size < 0 || streamLen < 0 || fileEntry.Size == streamLen)
{
return Task.FromResult(true);
return;
}

throw new UserInformationException(Strings.ListVerifySizeFailure(remotename, fileEntry.Size, streamLen), "AftpListVerifySizeFailure");
@@ -376,19 +367,17 @@ public Task Put(string remotename, System.IO.Stream input, CancellationToken can

throw;
}

return Task.FromResult(true);
}

public Task Put(string remotename, string localname, CancellationToken cancelToken)
{
using (System.IO.FileStream fs = System.IO.File.Open(localname, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
using (FileStream fs = File.Open(localname, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Put(remotename, fs, cancelToken);
}
}

public void Get(string remotename, System.IO.Stream output)
public void Get(string remotename, Stream output)
{
var ftpClient = CreateClient();

@@ -417,7 +406,7 @@ public void Get(string remotename, System.IO.Stream output)

public void Get(string remotename, string localname)
{
using (System.IO.FileStream fs = System.IO.File.Open(localname, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
using (FileStream fs = File.Open(localname, FileMode.Create, FileAccess.Write, FileShare.None))
{
Get(remotename, fs);
}
@@ -456,10 +445,10 @@ public string[] DNSName
get { return new string[] { new Uri(_url).Host }; }
}

private static System.IO.Stream StringToStream(string str)
private static Stream StringToStream(string str)
{
var stream = new System.IO.MemoryStream();
var writer = new System.IO.StreamWriter(stream) { AutoFlush = true };
var stream = new MemoryStream();
var writer = new StreamWriter(stream) { AutoFlush = true };
writer.Write(str);
return stream;
}
@@ -498,7 +487,7 @@ public void Test()
}

// Test read permissions
using (var stream = new System.IO.MemoryStream())
using (var stream = new MemoryStream())
{
try
{
@@ -546,9 +535,7 @@ public void Dispose()

private FtpClient CreateClient()
{
var url = _url;

var uri = new Uri(url);
var uri = new Uri(_url);

if (this.Client == null) // Create connection if it doesn't exist yet
{
@@ -34,17 +34,18 @@
<AssemblyOriginatorKeyFile>Duplicati.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentFTP, Version=21.0.0.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL">
<HintPath>..\..\..\..\packages\FluentFTP.21.0.0\lib\net45\FluentFTP.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="System.Net.FtpClient">
<HintPath>..\..\..\..\thirdparty\System.Net.FtpClient\System.Net.FtpClient.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AlternativeFTPBackend.cs" />
@@ -54,6 +55,7 @@
<ItemGroup>
<None Include="app.config" />
<None Include="Duplicati.snk" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Interface\Duplicati.Library.Interface.csproj">
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentFTP" version="21.0.0" targetFramework="net45" />
</packages>

1 comment on commit 662627a

@duplicatibot

This comment has been minimized.

Copy link

commented on 662627a Jul 3, 2019

This commit has been mentioned on Duplicati. There might be relevant details there:

https://forum.duplicati.com/t/problems-after-upgrade-to-2-0-4-21/7469/3

Please sign in to comment.
You can’t perform that action at this time.