📚 Référence API

Documentation complète de l'API CLI et des services web

🖥️ API CLI (Ligne de Commande)

L'outil en ligne de commande utilise System.CommandLine pour le parsing des arguments.

CLI Commande Principale

Syntaxe

sftp-copy-tool [options]

Options Obligatoires

Option Type Description
--host string Adresse du serveur SFTP
--username string Nom d'utilisateur SFTP
--password string Mot de passe SFTP
--remote-path string Chemin du fichier/dossier distant
--local-path string Répertoire de destination local

Options Facultatives

Option Type Défaut Description
--port int 22 Port du serveur SFTP
--recursive flag false Active la copie récursive
--log-level enum Information Niveau de journalisation (Verbose, Debug, Information, Warning, Error, Fatal)

Exemple

sftp-copy-tool \
  --host sftp.example.com \
  --port 22 \
  --username admin \
  --password "secret123" \
  --remote-path /data/backup \
  --local-path /mnt/nas/backup \
  --recursive \
  --log-level Debug

Code de Retour

Code Signification
0 Succès
1 Erreur générale ou exception

🌐 Services Web

L'application Blazor expose plusieurs services pour gérer les opérations SFTP et l'interface utilisateur.

SftpExecutionService

Service principal pour exécuter les opérations SFTP avec suivi de progression.

ExecuteAsync

Description: Exécute une opération SFTP (fichier unique ou récursif)

Signature

public async Task ExecuteAsync(
    string host,
    int port,
    string username,
    string password,
    string remotePath,
    string localPath,
    bool recursive,
    IProgressReporter progressReporter,
    CancellationToken cancellationToken
)

Paramètres

Paramètre Type Description
host string Adresse du serveur SFTP
port int Port SFTP (généralement 22)
username string Nom d'utilisateur
password string Mot de passe
remotePath string Chemin distant (absolu)
localPath string Chemin local de destination
recursive bool True pour copie récursive
progressReporter IProgressReporter Interface de rapport de progression
cancellationToken CancellationToken Token d'annulation

Exceptions

  • ArgumentException: Paramètres invalides
  • InvalidOperationException: Tentative de copie d'un dossier sans --recursive
  • IOException: Erreur d'E/S (lecture/écriture)
  • UnauthorizedAccessException: Permissions insuffisantes

📡 SftpService

Service bas niveau pour les opérations SFTP utilisant la bibliothèque Tmds.Ssh.

CopyFileAsync

Description: Copie un fichier unique depuis le serveur SFTP

public async Task CopyFileAsync(
    string host,
    int port,
    string username,
    string password,
    string remotePath,
    string localPath,
    IProgress<ProgressInfo>? progress = null
)

ProgressInfo Structure

public class ProgressInfo
{
    public long BytesTransferred { get; set; }
    public long TotalBytes { get; set; }
    public double Percentage { get; set; }
    public double SpeedBytesPerSecond { get; set; }
    public TimeSpan Elapsed { get; set; }
    public TimeSpan? EstimatedRemaining { get; set; }
    public string CurrentFile { get; set; }
}

CopyDirectoryRecursiveAsync

Description: Copie récursivement un répertoire complet

public async Task CopyDirectoryRecursiveAsync(
    string host,
    int port,
    string username,
    string password,
    string remotePath,
    string localPath,
    IProgress<ProgressInfo>? progress = null
)
ℹ️ Comportement: Cette méthode parcourt récursivement tous les sous-dossiers et fichiers, maintenant la structure de répertoires. Les entrées spéciales (. et ..) sont ignorées.

TestConnectionAsync

Description: Teste la connexion SFTP sans effectuer de transfert

public async Task<bool> TestConnectionAsync(
    string host,
    int port,
    string username,
    string password
)

Retour

  • true: Connexion réussie
  • false: Échec de connexion (exception levée)

📊 Suivi de Progression

IProgressReporter Interface

public interface IProgressReporter
{
    void Report(ProgressInfo info);
    void AddLog(string message);
    IReadOnlyList<string> GetRecentLogs();
}

ProgressReporter (Implémentation)

Propriétés Publiques

Propriété Type Description
CurrentProgress ProgressInfo Informations de progression actuelles
OnProgressChanged Action<ProgressInfo> Callback appelé lors des mises à jour

Méthodes

Méthode Description
Report(ProgressInfo info) Met à jour la progression et déclenche le callback
AddLog(string message) Ajoute un message au journal (max 50 entrées)
GetRecentLogs() Récupère les 50 derniers logs
Clear() Réinitialise la progression et les logs

Exemple d'Utilisation

var progressReporter = new ProgressReporter();
progressReporter.OnProgressChanged = (info) =>
{
    Console.WriteLine($"Progression: {info.Percentage:F1}%");
    Console.WriteLine($"Vitesse: {info.SpeedBytesPerSecond / 1024:F2} KB/s");
};

await sftpService.CopyFileAsync(
    "sftp.example.com", 22, "user", "pass",
    "/remote/file.zip", "/local/dest/",
    new Progress<ProgressInfo>(progressReporter.Report)
);

📁 Explorateur de Fichiers

FileExplorerService

ListRemoteDirectoryAsync

Description: Liste les fichiers et dossiers d'un répertoire distant SFTP

public async Task<List<FileEntry>> ListRemoteDirectoryAsync(
    string host,
    int port,
    string username,
    string password,
    string remotePath
)

FileEntry Structure

public class FileEntry
{
    public string Name { get; set; }
    public string FullPath { get; set; }
    public bool IsDirectory { get; set; }
    public long Size { get; set; }
    public DateTime? LastModified { get; set; }
}

Retour

Liste d'objets FileEntry représentant les fichiers et dossiers

ListLocalDirectoryAsync

Description: Liste les fichiers et dossiers d'un répertoire local

public async Task<List<FileEntry>> ListLocalDirectoryAsync(
    string localPath
)

⚠️ Gestion des Erreurs

Types d'Exceptions

Exception Contexte Solution
SshException Erreur de connexion SSH/SFTP Vérifier host, port, identifiants, firewall
ArgumentException Paramètres invalides Valider les entrées utilisateur
InvalidOperationException Opération invalide (ex: dossier sans --recursive) Ajouter le flag --recursive pour les dossiers
UnauthorizedAccessException Permissions insuffisantes (local) Vérifier les permissions du dossier local
IOException Erreur lecture/écriture fichier Vérifier espace disque, permissions, chemin valide
TaskCanceledException Opération annulée par l'utilisateur Normal, pas d'action requise

Messages d'Erreur Courants

"Connection refused"

Causes:
  • Serveur SFTP inaccessible ou hors ligne
  • Port incorrect (vérifier si c'est bien 22)
  • Firewall bloquant la connexion

"Authentication failed"

Causes:
  • Nom d'utilisateur ou mot de passe incorrect
  • Compte verrouillé après trop de tentatives
  • Authentification par clé requise (non supporté actuellement)

"Path not found"

Causes:
  • Le chemin distant n'existe pas
  • Permissions insuffisantes sur le serveur SFTP
  • Chemin relatif au lieu d'absolu

Gestion des Erreurs dans le Code

try
{
    await sftpService.CopyFileAsync(
        host, port, username, password,
        remotePath, localPath, progress
    );
    Console.WriteLine("✅ Transfert réussi");
}
catch (SshException ex)
{
    Console.WriteLine($"❌ Erreur SFTP: {ex.Message}");
    // Vérifier connexion réseau, identifiants
}
catch (UnauthorizedAccessException ex)
{
    Console.WriteLine($"❌ Permissions refusées: {ex.Message}");
    // Vérifier permissions du dossier local
}
catch (IOException ex)
{
    Console.WriteLine($"❌ Erreur E/S: {ex.Message}");
    // Vérifier espace disque, chemin valide
}
catch (Exception ex)
{
    Console.WriteLine($"❌ Erreur inattendue: {ex.Message}");
    // Logger pour investigation
}

📖 Exemples Complets

Exemple 1: Transfert Simple avec Progression

using SftpCopyTool;

var sftpService = new SftpService();
var progress = new Progress<ProgressInfo>(info =>
{
    Console.WriteLine($"📊 {info.Percentage:F1}% | " +
                      $"⚡ {info.SpeedBytesPerSecond / 1024:F2} KB/s | " +
                      $"📁 {info.CurrentFile}");
});

try
{
    await sftpService.CopyFileAsync(
        "sftp.example.com",
        22,
        "admin",
        "password123",
        "/remote/file.tar.gz",
        "/local/backup/",
        progress
    );
    Console.WriteLine("✅ Transfert terminé avec succès!");
}
catch (Exception ex)
{
    Console.WriteLine($"❌ Erreur: {ex.Message}");
}

Exemple 2: Interface Web - Composant Blazor

@page "/copy"
@inject SftpExecutionService SftpService

<h3>SFTP Copy Tool</h3>

<EditForm Model="@model" OnValidSubmit="@StartCopy">
    <InputText @bind-Value="model.Host" placeholder="Host" />
    <InputNumber @bind-Value="model.Port" placeholder="Port" />
    <InputText @bind-Value="model.Username" placeholder="Username" />
    <InputText type="password" @bind-Value="model.Password" placeholder="Password" />
    <InputText @bind-Value="model.RemotePath" placeholder="Remote Path" />
    <InputText @bind-Value="model.LocalPath" placeholder="Local Path" />
    <InputCheckbox @bind-Value="model.Recursive" /> Recursive

    <button type="submit">Start Copy</button>
</EditForm>

@if (progress != null)
{
    <div>
        <p>Progression: @progress.Percentage.ToString("F1")%</p>
        <p>Vitesse: @(progress.SpeedBytesPerSecond / 1024).ToString("F2") KB/s</p>
        <p>Fichier: @progress.CurrentFile</p>
    </div>
}

@code {
    private SftpModel model = new();
    private ProgressInfo? progress;
    private CancellationTokenSource? cts;

    private async Task StartCopy()
    {
        cts = new CancellationTokenSource();
        var progressReporter = new ProgressReporter();
        progressReporter.OnProgressChanged = (info) =>
        {
            progress = info;
            StateHasChanged();
        };

        try
        {
            await SftpService.ExecuteAsync(
                model.Host, model.Port, model.Username, model.Password,
                model.RemotePath, model.LocalPath, model.Recursive,
                progressReporter, cts.Token
            );
        }
        catch (Exception ex)
        {
            // Handle error
        }
    }
}