В продолжении темы
Евенты, выкладываю код программы для скачивания XML файла с SFTP сервера с помощью компонент SecureBridge
Хотелось бы конструктивной критики. В силу того, что есть желание избавиться от быдлокодерских замашек,
а командной работы в проектах нет (всё один делаю), возникла необходимость поделиться (необходимость личная, так сказать "духовная")
Класс потока:
Код:
type
TXMLDonwload = class(TThread)
protected
procedure Execute; override;
procedure SSHClientServerKeyValidate(Sender: TObject; NewServerKey: TScKey;
var Accept: Boolean);
procedure SFTPClientData(Sender: TObject; const FileName: string;
const Handle, Buffer: TArray<System.Byte>; Offset, Count: Integer;
EOF: Boolean);
end;
Реализация:
Код:
procedure TXMLDonwload.Execute;
var
aSSHClient: TScSSHClient;
aKeyStorage: TScFileStorage;
aSFTPClient: TScSFTPClient;
aAttr: TScSFTPFileAttributes;
aSettings: TRegistry;
FileName: string;
FileDate: TDate;
YY, MM, DD: string;
const
SFTP_LOKAL = '/LOKAL/'; //папка, из которой качаем
COMP_LOKAL = 'X:/TOS/XML/'; //папка, куда качаем
SFTP_FILE_PREF = 'TE_000024_';// константы для построения имени файла
SFTP_FILE_TYPE = '.xml';
REGEDIT_SETTINGS = '\SYSTEM\CurrentControlSet\services\TechemService'; // место, где хранятся ключи настроек для коннекта с SFTP
begin
inherited;
try
// CoInitialize(nil);
aSSHClient := TScSSHClient.Create(nil);
try
aSettings := TRegistry.Create(KEY_READ);
try
aSettings.RootKey := HKEY_LOCAL_MACHINE;
aSettings.OpenKey(REGEDIT_SETTINGS, false);
aSSHClient.HostName := aSettings.ReadString('HostName');
aSSHClient.Port := aSettings.ReadInteger('Port');
aSSHClient.User := aSettings.ReadString('User');
aSSHClient.Password := aSettings.ReadString('Password');
finally
aSettings.Free;
end;
aKeyStorage := TScFileStorage.Create(nil);
try
aSSHClient.KeyStorage := aKeyStorage;
aSSHClient.OnServerKeyValidate := SSHClientServerKeyValidate;
aSSHClient.Connect;
if aSSHClient.Connected then
begin
aSFTPClient := TScSFTPClient.Create(nil);
try
aSFTPClient.SSHClient := aSSHClient;
aSFTPClient.OnData := SFTPClientData;
aSFTPClient.Initialize;
aSFTPClient.OpenDirectory('.');
FileDate := IncDay(Date, -1);
DD := Copy(DateToStr(FileDate), 1, 2);
MM := Copy(DateToStr(FileDate), 4, 2);
YY := Copy(DateToStr(FileDate), 7, 4);
FileName := SFTP_FILE_PREF + YY + MM + DD + SFTP_FILE_TYPE;
aAttr := TScSFTPFileAttributes.Create;
try
aSFTPClient.RetrieveAttributes(aAttr, SFTP_LOKAL + FileName);
Synchronize(
procedure
begin
Form1.cxProgressBar6.Properties.Max := aAttr.Size;
end);
finally
aAttr.Free;
end;
aSFTPClient.DownloadFile(SFTP_LOKAL + FileName,
COMP_LOKAL + FileName, true);
aSFTPClient.Disconnect;
finally
aSFTPClient.Free;
end;
end;
finally
aKeyStorage.Free;
end;
finally
aSSHClient.Free;
end;
finally
// CoUnInitialize;
end;
end;
Процедура для обновления позиции прогресс бара скачивания файла. Возникает каждый раз, когда SFTP пересылает очередной пакет размером Count
Код:
procedure TXMLDonwload.SFTPClientData(Sender: TObject; const FileName: string;
const Handle, Buffer: TArray<System.Byte>; Offset, Count: Integer;
EOF: Boolean);
begin
Synchronize(
procedure
begin
Form1.cxProgressBar6.Position := Form1.cxProgressBar6.Position + Count;
end);
end;
Процедура подтверждения приёма файла-ключа для коннекта.
Код:
procedure TXMLDonwload.SSHClientServerKeyValidate(Sender: TObject;
NewServerKey: TScKey; var Accept: Boolean);
begin
Accept := true;
end;
За область обсуждения выносим
1) "хранение пароля в открытом виде в реестре"
2) Принятие файла ключа без проверки