procedure TIdFTP.InternalPut(
const ACommand:
string; ASource: TIdStream; AFromBeginning: Boolean = true);
var
LIP:
string;
LPort: Integer;
LPasvCl : TIdTCPClient;
LPortSv : TIdSimpleServer;
begin
FAbortFlag.Value := False;
//for SSL FXP, we have to do it here because there is no command were a client
//submits data through a data port where the SSCN setting is ignored.
ClearSSCN;
DoStatus(ftpTransfer, [RSFTPStatusStartTransfer]);
try
if FPassive
then begin
SendPret(ACommand);
if FUsingExtDataPort
then begin
SendEPassive(LIP, LPort);
end else begin
SendPassive(LIP, LPort);
end;
IOHandler.WriteLn(ACommand);
FDataChannel := TIdTCPClient.Create(
nil);
LPasvCl := TIdTCPClient(FDataChannel);
try
InitDataChannel;
LPasvCl.Host := LIP;
LPasvCl.Port := LPort;
if Assigned(FOnDataChannelCreate)
then begin
OnDataChannelCreate(self,FDataChannel);
end;
LPasvCl.Connect;
try
Self.GetResponse([110, 125, 150]);
try
if FUsingSFTP
and (FDataPortProtection = ftpdpsPrivate)
then begin
TIdSSLIOHandlerSocketBase(FDataChannel.IOHandler).Passthrough := False;
end;
if FCurrentTransferMode<>dmDeflate
then begin
if AFromBeginning
then begin
FDataChannel.IOHandler.
Write(ASource,0, false);
// from beginning
end else begin
FDataChannel.IOHandler.
Write(ASource,-1, false);
// from current position
end;
end else begin
FCompressor.CompressFTPToIO(ASource,FDataChannel.IOHandler,FZLibCompressionLevel,FZLibWindowBits,FZLibMemLevel, FZLibStratagy);
end;
except
on E: EIdSocketError
do
begin
// If 10038 - abort was called. Server will return 225
if E.LastError <> 10038
then begin
raise;
end;
end;
end;
finally
LPasvCl.Disconnect;
end;
finally
FinalizeDataOperation;
end;
end else begin
FDataChannel := TIdSimpleServer.Create(
nil);
LPortSv := TIdSimpleServer(FDataChannel);
try
InitDataChannel;
LPortSv.BoundIP := (Self.IOHandler
as TIdIOHandlerSocket).Binding.IP;
LPortSv.BoundPort := FDataPort;
LPortSv.BoundPortMin := FDataPortMin;
LPortSv.BoundPortMax := FDataPortMax;
if Assigned(FOnDataChannelCreate)
then begin
OnDataChannelCreate(Self, FDataChannel);
end;
LPortSv.BeginListen;
if FUsingExtDataPort
then begin
SendEPort(LPortSv.Binding);
end else begin
SendPort(LPortSv.Binding);
end;
Self.SendCmd(ACommand, [125, 150]);
LPortSv.Listen;
if FUsingSFTP
and (FDataPortProtection = ftpdpsPrivate)
then begin
TIdSSLIOHandlerSocketBase(FDataChannel.IOHandler).PassThrough := False;
end;
if FCurrentTransferMode<>dmDeflate
then begin
if AFromBeginning
then begin
FDataChannel.IOHandler.
Write(ASource,0, false);
// from beginning
end else begin
FDataChannel.IOHandler.
Write(ASource,-1, false);
// from current position
end;
end else begin
FCompressor.CompressFTPToIO(ASource,FDataChannel.IOHandler,FZLibCompressionLevel,FZLibWindowBits,FZLibMemLevel, FZLibStratagy);
end;
finally
FinalizeDataOperation;
end;
end;
except
//Note that you are likely to get an exception you abort a transfer
//hopefully, this will make things work better.
on E: EIdConnClosedGracefully
do
begin
if not (E
is EIdConnClosedGracefully)
then
begin
raise;
end;
end;
end;
{ commented out because we might need to revert back to this
if new code fails.
if (LResponse = 426) or (LResponse = 450) then
begin
// some servers respond with 226 on ABOR
GetResponse([226, 225]);
DoStatus(ftpAborted, [RSFTPStatusAbortTransfer]);
end;
}
end;