a2171e643d
- FTP - Gomba - Icoel - MultiCcn - OSAI - SqlDB
530 lines
18 KiB
C#
530 lines
18 KiB
C#
using FluentFTP;
|
|
using NLog;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Security;
|
|
|
|
namespace EgwProxy.Ftp
|
|
{
|
|
/// <summary>
|
|
/// Client per operazioni FTP, basato su FluentFTP: https://github.com/robinrodricks/FluentFTP https://github.com/robinrodricks/FluentFTP/wiki/Quick-Start-Example
|
|
/// </summary>
|
|
public class Manager
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Inizializzazione di oggetto per comunicazione FTP
|
|
/// </summary>
|
|
/// <param name="server"></param>
|
|
/// <param name="userName"></param>
|
|
/// <param name="passwd"></param>
|
|
/// <param name="rawCert"></param>
|
|
/// <param name="skipCert"></param>
|
|
public Manager(string server, string userName, string passwd, string rawCert, bool skipCert)
|
|
{
|
|
_server = server;
|
|
_userName = userName;
|
|
_passwd = passwd;
|
|
_skipCert = skipCert;
|
|
_rawCert = rawCert;
|
|
if (!string.IsNullOrEmpty(server))
|
|
{
|
|
// se ho user/pwd è autenticato...
|
|
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(passwd))
|
|
{
|
|
client = new FtpClient(server, userName, passwd);
|
|
}
|
|
//.. altrimenti anonimo...
|
|
else
|
|
{
|
|
client = new FtpClient(server);
|
|
}
|
|
client.Config.RetryAttempts = 3;
|
|
IsConfigured = true;
|
|
}
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Properties
|
|
|
|
public bool IsConfigured { get; set; } = false;
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Creazione directory remota
|
|
/// </summary>
|
|
/// <param name="remoteDir">Nome directory remota da creare (ad es: @"/public_html/videos")</param>
|
|
public bool CreateDir(string remoteDir)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
// upload della folder + files, cancellazione extra files = mirroring
|
|
answ = client.CreateDirectory(remoteDir);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in CreateDir{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eliminazionedirectory remota
|
|
/// </summary>
|
|
/// <param name="remoteDir">Nome directory remota da eliminare</param>
|
|
public bool DeleteDir(string remoteDir)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
// Elimina folder
|
|
client.DeleteDirectory(remoteDir);
|
|
answ = true;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in DeleteDir{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eliminazione file remoto
|
|
/// </summary>
|
|
/// <param name="remoteFile">Nome file remoto da eliminare</param>
|
|
public bool DeleteFile(string remoteFile)
|
|
{
|
|
bool answ = false;
|
|
tryConnect();
|
|
try
|
|
{
|
|
// Elimina folder
|
|
client.DeleteFile(remoteFile);
|
|
answ = true;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in DeleteFile{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Eliminazione lista di files remoti
|
|
/// </summary>
|
|
/// <param name="remFileList">Lista file remoti da eliminare</param>
|
|
public int DeleteFileList(List<string> remFileList)
|
|
{
|
|
int numDone = 0;
|
|
tryConnect();
|
|
try
|
|
{
|
|
foreach (var remoteFile in remFileList)
|
|
{
|
|
// Elimina folder
|
|
client.DeleteFile(remoteFile);
|
|
// verifico se sia presente...
|
|
bool fExist = client.FileExists(remoteFile);
|
|
if (!fExist)
|
|
{
|
|
numDone++;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in DeleteFileList{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return numDone;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica esistenza directory su server FTP remoto
|
|
/// </summary>
|
|
/// <param name="remotePath">Percorso remoto da testare (ad es "/htdocs/extras/")</param>
|
|
/// <returns></returns>
|
|
public bool DirExists(string remotePath)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
answ = client.DirectoryExists(remotePath);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in DirExists{Environment.NewLine}{exc}");
|
|
}
|
|
// c chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica esistenza file su server FTP remoto
|
|
/// </summary>
|
|
/// <param name="remotePath">Percorso remoto da testare (ad es "/htdocs/big2.txt")</param>
|
|
/// <returns></returns>
|
|
public bool FileExists(string remotePath)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
answ = client.FileExists(remotePath);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in FileExists{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scaricamento intera directory, modalità MIRROR
|
|
/// </summary>
|
|
/// <param name="localDir">Path directory da inviare (ad es:@"C:\website\videos\")</param>
|
|
/// <param name="remoteDir">Nome remoto file per caricamento (ad es: @"/public_html/videos")</param>
|
|
/// <param name="syncMode">Modalità di sync (default = mirror)</param>
|
|
public bool GetDir(string localDir, string remoteDir, FtpFolderSyncMode syncMode = FtpFolderSyncMode.Mirror)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
// download della folder secondo modalità sync
|
|
var result = client.DownloadDirectory(localDir, remoteDir, syncMode);
|
|
//answ = (result != null && result.Count > 0);
|
|
answ = result != null && result.Where(x => !x.IsSuccess).Count() == 0;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in GetDir{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Download singolo file
|
|
/// </summary>
|
|
/// <param name="fileName">Path locale del file da inviare (ad es: @"C:\MyVideo.mp4")</param>
|
|
/// <param name="remoteName">NOme remoto file per caricamento (ad es: "/htdocs/MyVideo.mp4")</param>
|
|
public bool GetFile(string fileName, string remoteName)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
// effettuo caricamento puntuale
|
|
var result = client.DownloadFile(fileName, remoteName);
|
|
answ = result == FtpStatus.Success;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in GetFile{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Mostra contenuto directory remota
|
|
/// </summary>
|
|
/// <param name="remoteDir">Nome directory remota da leggere con (ad es: @"/public_html/videos")</param>
|
|
/// <param name="recurse">Indica se fare search ricorsivo</param>
|
|
public List<FtpListItem> GetRemoteList(string remoteDir, bool recurse)
|
|
{
|
|
List<FtpListItem> answ = new List<FtpListItem>();
|
|
try
|
|
{
|
|
tryConnect();
|
|
// recupero listing remoto directory
|
|
FtpListItem[] dirContent;
|
|
if (recurse)
|
|
{
|
|
dirContent = client.GetListing(remoteDir, FtpListOption.Recursive);
|
|
}
|
|
else
|
|
{
|
|
dirContent = client.GetListing(remoteDir);
|
|
}
|
|
answ = dirContent.ToList();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in GetRemoteList{Environment.NewLine}{exc}");
|
|
}
|
|
client.Disconnect();
|
|
// chiudo!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Mostra contenuto directory remota
|
|
/// </summary>
|
|
/// <param name="remoteDir">Nome directory remota da leggere (ad es: @"/public_html/videos")</param>
|
|
/// <param name="recurse">Indica se fare search ricorsivo</param>
|
|
public List<string> ListDir(string remoteDir, bool recurse)
|
|
{
|
|
List<string> answ = new List<string>();
|
|
try
|
|
{
|
|
tryConnect();
|
|
// upload della folder + files, cancellazione extra files = mirroring
|
|
FtpListItem[] dirContent;
|
|
if (recurse)
|
|
{
|
|
dirContent = client.GetListing(remoteDir, FtpListOption.Recursive);
|
|
}
|
|
else
|
|
{
|
|
dirContent = client.GetListing(remoteDir);
|
|
}
|
|
answ = dirContent.Select(x => $"{x.Type} - {x.Name}").ToList();
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in ListDir{Environment.NewLine}{exc}");
|
|
}
|
|
client.Disconnect();
|
|
// chiudo!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Caricamento intera directory, modalità MIRROR
|
|
/// </summary>
|
|
/// <param name="localDir">Path directory da inviare (ad es:@"C:\website\videos\")</param>
|
|
/// <param name="remoteDir">Nome remoto file per caricamento (ad es: @"/public_html/videos")</param>
|
|
/// <param name="syncMode">Modalità di sync (default = mirror)</param>
|
|
public List<FtpResult> MirrorLocalDir(string localDir, string remoteDir, FtpFolderSyncMode syncMode = FtpFolderSyncMode.Mirror)
|
|
{
|
|
List<FtpResult> jobResult = new List<FtpResult>();
|
|
try
|
|
{
|
|
tryConnect();
|
|
jobResult = client.UploadDirectory(localDir, remoteDir, syncMode);
|
|
//answ = (result != null && result.Count > 0);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in MirrorLocalDir{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return jobResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scaricamento intera directory, modalità MIRROR, con restituzione elenco esiti
|
|
/// </summary>
|
|
/// <param name="localDir">Path directory da inviare (ad es:@"C:\website\videos\")</param>
|
|
/// <param name="remoteDir">Nome remoto file per caricamento (ad es: @"/public_html/videos")</param>
|
|
/// <param name="syncMode">Modalità di sync (default = mirror)</param>
|
|
public List<FtpResult> MirrorRemoteDir(string localDir, string remoteDir, FtpFolderSyncMode syncMode = FtpFolderSyncMode.Mirror)
|
|
{
|
|
List<FtpResult> jobResult = new List<FtpResult>();
|
|
try
|
|
{
|
|
tryConnect();
|
|
jobResult = client.DownloadDirectory(localDir, remoteDir, syncMode);
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in mirrorRemoteDir{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return jobResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Caricamento intera directory, modalità MIRROR
|
|
/// </summary>
|
|
/// <param name="localDir">Path directory da inviare (ad es:@"C:\website\videos\")</param>
|
|
/// <param name="remoteDir">Nome remoto file per caricamento (ad es: @"/public_html/videos")</param>
|
|
/// <param name="syncMode">Modalità di sync (default = mirror)</param>
|
|
public bool SendDir(string localDir, string remoteDir, FtpFolderSyncMode syncMode = FtpFolderSyncMode.Mirror)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
//var result = client.UploadDirectory(localDir, remoteDir, FtpFolderSyncMode.Mirror, FtpRemoteExists.OverwriteInPlace, FtpVerify.Retry);
|
|
// upload della folder + files, cancellazione extra files = mirroring
|
|
var result = client.UploadDirectory(localDir, remoteDir, syncMode);
|
|
//answ = (result != null && result.Count > 0);
|
|
answ = result != null && result.Where(x => !x.IsSuccess).Count() == 0;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in SendDir{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Caricamento singolo file
|
|
/// </summary>
|
|
/// <param name="fileName">Path locale del file da inviare (ad es: @"C:\MyVideo.mp4")</param>
|
|
/// <param name="remoteName">NOme remoto file per caricamento (ad es: "/htdocs/MyVideo.mp4")</param>
|
|
public bool SendFile(string fileName, string remoteName)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
tryConnect();
|
|
// effettuo caricamento puntuale
|
|
var result = client.UploadFile(fileName, remoteName);
|
|
answ = result == FtpStatus.Success;
|
|
// se insuccesso --> controllo se ci sia file...
|
|
if (!answ)
|
|
{
|
|
answ = FileExists(remoteName);
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in SendFile{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica connessione con server FTP remoto
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool ServerOk()
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
tryConnect();
|
|
answ = client.IsConnected;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in ServerOk{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce tipo server remoto
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string ServerType()
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
tryConnect();
|
|
FtpServer srvType = client.ServerType;
|
|
answ = $"{srvType}";
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in ServerType{Environment.NewLine}{exc}");
|
|
}
|
|
// chiudo!
|
|
client.Disconnect();
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
protected bool _skipCert = false;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Properties
|
|
|
|
protected string _passwd { get; set; } = "";
|
|
protected string _rawCert { get; set; } = "";
|
|
protected string _server { get; set; } = "";
|
|
protected string _userName { get; set; } = "";
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Private Fields
|
|
|
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Properties
|
|
|
|
private FtpClient client { get; set; } = new FtpClient();
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Private Methods
|
|
|
|
private void Client_ValidateCertificate(FluentFTP.Client.BaseClient.BaseFtpClient control, FtpSslValidationEventArgs e)
|
|
{
|
|
if (e.PolicyErrors == SslPolicyErrors.None || _skipCert || e.Certificate.GetRawCertDataString() == _rawCert)
|
|
{
|
|
e.Accept = true;
|
|
}
|
|
else
|
|
{
|
|
Log.Error($"{e.PolicyErrors}");
|
|
Log.Error($"Cert:{Environment.NewLine}{e.Certificate}");
|
|
Log.Error($"RawString:{Environment.NewLine}{e.Certificate.GetRawCertDataString()}");
|
|
throw new Exception($"{e.PolicyErrors}{Environment.NewLine}{e.Certificate.GetRawCertDataString()}");
|
|
}
|
|
}
|
|
|
|
private void tryConnect()
|
|
{
|
|
// connect to the server and automatically detect working FTP settings
|
|
if (!client.IsConnected)
|
|
{
|
|
var profiles = client.AutoDetect(true, true);
|
|
#if false
|
|
// if any profiles are found, print the code to the console
|
|
if (profiles.Count > 0)
|
|
{
|
|
var code = profiles[0].ToCode();
|
|
Console.WriteLine(code);
|
|
}
|
|
#endif
|
|
client.ValidateCertificate += Client_ValidateCertificate;
|
|
client.AutoConnect();
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |