From 150fdb33fc99b333800bc1424b118561b28f9d74 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 10 Aug 2018 14:32:45 +0300 Subject: [PATCH] Additional dependency FluentFTP replaced by CLR's FTP client implementation --- .../NAppUpdate.Framework.csproj | 4 - src/NAppUpdate.Framework/Sources/FtpSource.cs | 84 +++++++++++++++---- src/NAppUpdate.Framework/packages.config | 4 - 3 files changed, 68 insertions(+), 24 deletions(-) delete mode 100644 src/NAppUpdate.Framework/packages.config diff --git a/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj b/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj index 32e5cf34..5c06df87 100644 --- a/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj +++ b/src/NAppUpdate.Framework/NAppUpdate.Framework.csproj @@ -68,9 +68,6 @@ v4.0 - - ..\..\..\packages\FluentFTP.19.2.2\lib\net35\FluentFTP.dll - @@ -128,7 +125,6 @@ Designer - diff --git a/src/NAppUpdate.Framework/Sources/FtpSource.cs b/src/NAppUpdate.Framework/Sources/FtpSource.cs index 312d7d5d..ff378bd4 100644 --- a/src/NAppUpdate.Framework/Sources/FtpSource.cs +++ b/src/NAppUpdate.Framework/Sources/FtpSource.cs @@ -16,7 +16,9 @@ public class FtpSource : IUpdateSource private string feedBasePath => Path.GetDirectoryName(feedPath); - private FtpClient ftpClient { get; } + private int bufferSize = 2048; + + private NetworkCredential credentials { get; } /// Url of ftp server ("ftp://somesite.com/") /// Local ftp path to feed ("/path/to/feed.xml") @@ -24,43 +26,92 @@ public class FtpSource : IUpdateSource /// Password of ftp user, if needed public FtpSource(string hostUrl, string feedPath, string login = null, string password = null) { - ftpClient = new FtpClient(hostUrl); HostUrl = hostUrl; this.feedPath = feedPath; if (login != null && password != null) { - ftpClient.Credentials = new NetworkCredential(login, password); + credentials = new NetworkCredential(login, password); } } private void TryConnectToHost() { + var ftpConnRequest = (FtpWebRequest) FtpWebRequest.Create(HostUrl); + ftpConnRequest.Method = WebRequestMethods.Ftp.ListDirectory; + ftpConnRequest.UsePassive = true; + ftpConnRequest.KeepAlive = false; + ftpConnRequest.Credentials = credentials; + try { - ftpClient.Connect(); + ftpConnRequest.GetResponse(); } - catch(Exception e) + catch (WebException e) { throw new WebException($"Failed to connect to host: {HostUrl}. Error message: {e.Message}"); } } + /// + /// Downloads remote file from ftp + /// + /// Path to file on server (example: "/path/to/file.txt") + /// Path to saved on disk file (Temp folder) + private string DownloadRemoteFile(string path, string localPath = null) + { + try + { + string pathToSave = localPath ?? Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + // Create an FTP Request + var ftpRequest = + (FtpWebRequest) FtpWebRequest.Create( + $@"{HostUrl}{(HostUrl.EndsWith("/") ? string.Empty : "/")}{path}"); + ftpRequest.Credentials = credentials; + // Set options + ftpRequest.UseBinary = true; + ftpRequest.UsePassive = true; + ftpRequest.KeepAlive = true; + // Specify the Type of FTP Request + ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; + + // Establish Return Communication with the FTP Server + using (var ftpResponse = (FtpWebResponse) ftpRequest.GetResponse()) + { + // Get the FTP Server's Response Stream + using (var ftpStream = ftpResponse.GetResponseStream()) + { + using (var localFileStream = new FileStream(pathToSave, FileMode.Create)) + { + byte[] byteBuffer = new byte[bufferSize]; + int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); + + while (bytesRead > 0) + { + localFileStream.Write(byteBuffer, 0, bytesRead); + bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); + } + } + } + } + + return pathToSave; + } + catch (Exception ex) + { + throw new WebException( + $"An error occurred when trying to download file {Path.GetFileName(path)}: {ex.Message}"); + } + } + #region IUpdateSource Members public String GetUpdatesFeed() { TryConnectToHost(); - string data = null; - - using (var fileStream = ftpClient.OpenRead(feedPath, FtpDataType.ASCII, true)) - { - using (var streamReader = new StreamReader(fileStream)) - { - data = streamReader.ReadToEnd(); - } - } + string feedFilePath = DownloadRemoteFile(feedPath); + string data = File.ReadAllText(feedFilePath); // Remove byteorder mark if necessary int indexTagOpening = data.IndexOf('<'); @@ -72,9 +123,10 @@ public String GetUpdatesFeed() return data; } - public Boolean GetData(String filePath, String basePath, Action onProgress, ref String tempLocation) + public Boolean GetData(String filePath, String basePath, Action onProgress, + ref String tempLocation) { - ftpClient.DownloadFile(tempLocation, Path.Combine(feedBasePath, filePath)); + DownloadRemoteFile(Path.Combine(feedBasePath, filePath), tempLocation); return true; } diff --git a/src/NAppUpdate.Framework/packages.config b/src/NAppUpdate.Framework/packages.config deleted file mode 100644 index 53dd6e94..00000000 --- a/src/NAppUpdate.Framework/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file