Indy
OrgaMon verwendet den HTTP-Server und FTP-Client des Indy Projektes. Dieses Projekt enthält in Delphi geschriebene TCP Protokolle. Im Moment (Stand 2009) benötigen einige Units-Patches aus unterschiedlichen Gründen ...
Wirksamkeit der folgenden Patches
Im Tools->Optionen->Bibliothekspfad müssen die 3 Pfade ...
$(BDS)\source\Indy\Indy10\System
$(BDS)\source\Indy\Indy10\Core
$(BDS)\source\Indy\Indy10\Protocols
... hinzugefügt werden, sonst ist der Patch wirkungslos, da die Quelltexte sonst nicht gesehen werden.
Zeitzonen-Bug
- \System\IdSysVCL.pas
class function TIdSysVCL.OffsetFromUTC: TIdDateTimeBase; var TimeZ : TTimeZoneInformation; OffsetInMinutes: integer; begin // get Offset in Minutes from System if (GetTimeZoneInformation(TimeZ)=2) then OffsetInMinutes := - (TimeZ.Bias + TimeZ.DayLightBias) else OffsetInMinutes := - (TimeZ.Bias + TimeZ.StandardBias); // Build the TDateTime, ensure positive Values Result := EncodeTime(abs(OffsetInMinutes) DIV 60,abs(OffsetInMinutes) MOD 60,0,0); // Ensure Old Sign if (OffsetInMinutes<0) then Result := - Result; end;
FTP_Client kann keine REST(art)
- \Protocols\IdFTP.pas
// Im "public" Bereich der TIDFTP-Klasse // am besten unter die anderen Put - Routinen procedure PutRestart(const ASourceFile,ADestFile: string; const StartPosition: Int64);
// hier die Implementierung weiter unten
//
procedure TIdFTP.PutRestart(const ASourceFile, ADestFile: string; const StartPosition: int64);
var
LSourceStream: TIdStream;
LDestFileName : String;
begin
LDestFileName := ADestFile;
if LDestFileName = then
begin
LDestFileName := Sys.ExtractFileName(ASourceFile);
end;
LSourceStream := TReadFileNonExclusiveStream.Create(ASourceFile);
try
EIdFTPUploadFileNameCanNotBeEmpty.IfTrue(ADestFile = , RSFTPFileNameCanNotBeEmpty);
LSourceStream.Position := StartPosition;
DoBeforePut(LSourceStream);
SendCmd('REST ' + Sys.IntToStr(StartPosition), [350]); {Do not localize}
InternalPut('STOR ' + ADestFile, LSourceStream, false); {Do not localize}
DoAfterPut;
finally
Sys.FreeAndNil(LSourceStream);
end;
end;
// eine typische Anwendung eines FTP Restart sieht so aus ...
function TFormDatensicherung.doUpload(ResultFName: string):boolean;
var
FtpDestFName: string;
rSize: int64;
lSize: int64;
begin
//
result := false;
lSize := FSize(ResultFName);
SolidInit(IdFTP1);
with IdFTP1 do
begin
Host := cFTP_Host;
UserName := cFTP_UserName;
password := cFTP_Password;
try
FtpStartTime := 0;
if connected then
Quit;
connect;
// atomic.begin
FtpDestFName := ExtractFileName(ResultFName);
repeat
rSize := Size(FtpDestFName + '.$$$');
if rSize=lSize then
break;
if rSize>lSize then
raise Exception.create('FTP: remote Datei ist '+inttostr(rSize-lSize)+' Bytes grösser als die lokale');
if (rSize<1) then
begin
FTP_StartOffset := 0;
Put(ResultFName, FtpDestFName + '.$$$');
end else
begin
FTP_StartOffset := rSize;
PutRestart(ResultFName, FtpDestFName + '.$$$',rSize);
end;
until true;
rSize := Size(FtpDestFName + '.$$$');
if (lSize=rSize) then
begin
if (Size(FtpDestFName) >= 0) then
Delete(FtpDestFName);
Rename(FtpDestFName + '.$$$', FtpDestFName);
result := true;
end else
begin
if (rSize>lSize) then
raise Exception.create('FTP: remote Datei ist '+inttostr(rSize-lSize)+' Bytes grösser als die lokale')
else
raise Exception.create('FTP: remote Datei ist '+inttostr(lSize-rSize)+' Bytes kleiner als die lokale');
end;
// atomic.end
Quit;
except
on E: Exception do
begin
Log('ERROR: Ftp Upload Error: ' + e.message);
end;
end;
end;
end;