Niestety na googlach nie znalazłem satysfakjonującej mnie odpowiedzi i po długim czasie ślęczenia nad kodem źródłowym biblioteki znalazłem pewien sposób, który spełnia moje oczekiwania. Otóż należy przesłonić żądany komuniat za pomocą CommandHandlers komponentu INDY Server FTP, wpisać obsługiwany command dla tworzonego przesłonięcia, a następnie zareagować na jego wystąpienie poprzez zdarzenie OnCommand.
Wadą tego sposobu jest konieczność własnoręcznej implementacji całego zdarzenia od nowa, ale z drugiej strony uzyskujemy nad nim całkowitą kontrolę - najlepiej skopiować źródło domyślnej reakcji, a następnie dostosować je do własny potrzeb.
Dla przykładu umieszczam przesłonięcie komendy ftp CWD, która co prawda jest domyślnie obsługiwana przez komponent, ale niestety nie robi tego dokładnie, ponieważ nie blokuje użytkownika przy próbie przejścia do katalogu, który nie istnieje.
procedure TForm1.IdFTPServer1TIdCommandHandler1Command(ASender: TIdCommand);
var
s: string;
begin
with TIdFTPServerThread(ASender.Thread) do begin
if Authenticated then begin
if Assigned(IdFTPServer1.OnChangeDirectory) then begin
case IdFTPServer1.EmulateSystem of
ftpsDOS: s := ProcessPath(CurrentDir, ASender.UnparsedParams, '\'); {Do not Localize}
ftpsOther, ftpsUNIX, ftpsVAX: s := ProcessPath(CurrentDir, ASender.UnparsedParams);
end;
IdFTPServer1.OnChangeDirectory(TIdFTPServerThread(ASender.Thread), s);
if s<>'' then
begin
ASender.Reply.SetReply(250, Format(RSFTPCmdSuccessful, ['CWD'])); {Do not Localize}
CurrentDir := s;
end else
ASender.Reply.SetReply(550, Format('%s: No such file or directory.', ['CWD']));
end else begin
ASender.Reply.SetReply(550, Format(RSFTPCmdNotImplemented, ['CWD'])); {Do not Localize}
end;
end;
end;
end;
W tym przypadku zadrzenie OnChangeDirectory
sprawdza czy katalog istnieje, jeśli tak to następuje domyślna reakcja, jeśli nie zmienna s jest czyszczona co jest dla nas sygnałem, aby odpowiednio zareagować. (domyślnie zmienna zawiera katalog, do którego użytkownik żąda dostępu).