⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idftp.pas

📁 photo.163.com 相册下载器 多线程下载
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        end;
        FDataChannel.IOHandler.Free;
        FreeAndNil(FDataChannel);
      end;
    end
    else
    begin
      // PORT or EPRT
      FDataChannel := TIdSimpleServer.Create(nil);
      LPortSv := FDataChannel as TIdSimpleServer;
      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;
        if AResume then begin
          SendCmd('REST ' + IntToStr(ADest.VCLStream.Position), [350]);  {do not localize}
        end;
        SendCmd(ACommand, [125, 150, 154]); //APR: Ericsson Switch FTP);

        LPortSv.Listen;
        if FUsingSFTP and (FDataPortProtection = ftpdpsPrivate) then begin
          TIdSSLIOHandlerSocketBase(FDataChannel.IOHandler).PassThrough := False;
        end;

        if FCurrentTransferMode = dmStream then begin
          FDataChannel.IOHandler.ReadStream(ADest, -1, True);
        end else begin
          FCompressor.DecompressFTPFromIO( FDataChannel.IOHandler, FZLibWindowBits, ADest.VCLStream);
 //         ReadCompressedData(FCompressor, ADest, FDataChannel.IOHandler, FZLibWindowBits);
        end;
      finally
        if Assigned(FOnDataChannelDestroy) then begin
          OnDataChannelDestroy(Self, FDataChannel);
        end;
        FDataChannel.IOHandler.Free;
        FDataChannel.IOHandler := nil;
        FreeAndNil(FDataChannel);
      end;
    end;
  finally
    DoStatus(ftpReady, [RSFTPStatusDoneTransfer]);
  end;
  // ToDo: Change that to properly handle response code (not just success or except)
  // 226 = download successful, 225 = Abort successful}
  LResponse := GetResponse([225, 226, 250, 426, 450]);
  if (LResponse = 426) or (LResponse = 450) then begin
    GetResponse([226, 225]);
    DoStatus(ftpAborted, [RSFTPStatusAbortTransfer]);
  end;
end;

procedure TIdFTP.Quit;
begin
  if Connected then begin
    IOHandler.WriteLn('QUIT');      {do not localize}
  end;
  Disconnect;
end;

procedure TIdFTP.KillDataChannel;
begin
  // Had kill the data channel ()
  if Assigned(FDataChannel) then begin
    FDataChannel.Disconnect;//FDataChannel.IOHandler.DisconnectSocket;  {//BGO}
  end;
end;

procedure TIdFTP.Abort;
begin
  // only send the abort command. The Data channel is supposed to disconnect
  if Connected then begin
    IOHandler.WriteLn('ABOR');                   {do not localize}
  end;
  // Kill the data channel: usually, the server doesn't close it by itself
  KillDataChannel;
end;

procedure TIdFTP.SendPort(AHandle: TIdSocketHandle);
begin
  if FExternalIP <> '' then
  begin
    SendPort(FExternalIP,AHandle.Port);
  end
  else
  begin
    SendPort(AHandle.IP, AHandle.Port);
  end;
end;

procedure TIdFTP.SendPort(const AIP: String; const APort: Integer);
begin
  SendDataSettings;
  SendCmd('PORT ' + StringReplace(AIP, '.', ',', [rfReplaceAll])   {do not localize}
   + ',' + IntToStr(APort div 256) + ',' + IntToStr(APort mod 256), [200]); {do not localize}
end;

procedure TIdFTP.InternalPut(const ACommand: string; ASource: TIdStreamVCL; AFromBeginning: Boolean = true);
var
  LIP: string;
  LPort: Integer;
  LResponse: Integer;
  LPasvCl : TIdTCPClient;
  LPortSv : TIdSimpleServer;
  LIO : TIdIOHandler;


begin
  //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 := FDataChannel as TIdTCPClient;
      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.VCLStream,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
        if Assigned(FOnDataChannelDestroy) then begin
          OnDataChannelDestroy(self,FDataChannel);
        end;
        LIO := FDataChannel.IOHandler;
        FDataChannel.IOHandler := nil;
        FreeAndNil(LIO);
        FreeAndNil(FDataChannel);
      end;
    end else begin
      FDataChannel := TIdSimpleServer.Create(nil);
      LPortSv := FDataChannel as TIdSimpleServer;
      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.VCLStream,FDataChannel.IOHandler,FZLibCompressionLevel,FZLibWindowBits,FZLibMemLevel, FZLibStratagy);
        end;
      finally
        if Assigned(FOnDataChannelDestroy) then begin
          OnDataChannelDestroy(Self, FDataChannel);
        end;
        FDataChannel.IOHandler.Free;
        FDataChannel.IOHandler := nil;
        FreeAndNil(FDataChannel);
      end;
    end;
  finally
    DoStatus(ftpReady, [RSFTPStatusDoneTransfer]);
  end;
  // 226 = download successful, 225 = Abort successful}
  LResponse := GetResponse([225, 226, 250, 426, 450]);
  if (LResponse = 426) or (LResponse = 450) then
  begin
    // some servers respond with 226 on ABOR
    GetResponse([226, 225]);
    DoStatus(ftpAborted, [RSFTPStatusAbortTransfer]);
  end;
end;

procedure TIdFTP.InitDataChannel;
var LSSL : TIdSSLIOHandlerSocketBase;
begin
  if (FDataPortProtection = ftpdpsPrivate) then
  begin
    LSSL := TIdSSLIOHandlerSocketBase(Self.IOHandler);
    FDataChannel.IOHandler := LSSL.Clone;
    //we have to delay the actual negotiation until we get the reply and
    //and just before the readString
    TIdSSLIOHandlerSocketBase(FDataChannel.IOHandler).Passthrough := True;
  end else begin
    FDataChannel.IOHandler := TIdIOHandler.MakeDefaultIOHandler(Self);
  end;
  if FDataChannel is TIdTCPClient then
  begin
	  //Now SocksInfo are multi-thread safe
	  FDataChannel.IOHandler.ConnectTimeout := Self.IOHandler.ConnectTimeout;
  end;
  if (FDataChannel.IOHandler is TIdIOHandlerSocket) and (Self.IOHandler is TIdIOHandlerSocket) then
	begin
    TIdIOHandlerSocket(FDataChannel.IOHandler).TransparentProxy := TIdIOHandlerSocket(Self.IOHandler).TransparentProxy;
    TIdIOHandlerSocket(FDataChannel.IOHandler).IPVersion := TIdIOHandlerSocket(Self.IOHandler).IPVersion;
	end;
  FDataChannel.IOHandler.ReadTimeout := FTransferTimeout;
  FDataChannel.IOHandler.SendBufferSize := IOHandler.SendBufferSize;
  FDataChannel.IOHandler.RecvBufferSize := IOHandler.RecvBufferSize;
  FDataChannel.OnWork := OnWork;
  FDataChannel.OnWorkBegin := OnWorkBegin;
  FDataChannel.OnWorkEnd := OnWorkEnd;
end;

procedure TIdFTP.Put(const ASource: TIdStreamVCL; const ADestFile: string;
 const AAppend: boolean = false);
begin
  if ADestFile = '' then
  begin
    raise EIdFTPUploadFileNameCanNotBeEmpty.Create(RSFTPFileNameCanNotBeEmpty);
  end
  else
  begin
    DoBeforePut(ASource.VCLStream ); //APR);
    if AAppend then
    begin
      InternalPut('APPE ' + ADestFile, ASource, false);  {Do not localize}
    end
    else
    begin
      InternalPut('STOR ' + ADestFile, ASource);  {Do not localize}
    end;
    DoAfterPut;
  end;
end;

procedure TIdFTP.Put(const ASource: TStream; const ADestFile: string;
 const AAppend: boolean = false);
var LStream : TIdStreamVCL;
begin
  LStream := TIdStreamVCL.Create(ASource);
  try
    Put(LStream,ADestFile,AAppend);
  finally
    FreeAndNil(LStream);
  end;
end;

procedure TIdFTP.Put(const ASourceFile: string; const ADestFile: string='';
 const AAppend: boolean = false);
var
  LSourceStream: TFileStream;
  LDestFileName : String;
begin
  LDestFileName := ADestFile;
  if LDestFileName = '' then
  begin
   LDestFileName := ExtractFileName(ASourceFile);
  end;
  LSourceStream := TFileStream.Create(ASourceFile, fmOpenRead or fmShareDenyNone); try
    Put(LSourceStream, LDestFileName, AAppend);
  finally FreeAndNil(LSourceStream); end;
end;

procedure TIdFTP.StoreUnique(const ASource: TIdStreamVCL);
begin
    InternalPut('STOU', ASource);  {Do not localize}
end;

procedure TIdFTP.StoreUnique(const ASource: TStream);
var LStream : TIdStreamVCL;
begin
  LStream := TIdStreamVCL.Create(ASource);
  try
    StoreUnique(LStream);
  finally
    FreeAndNil(LStream);
  end;

end;

procedure TIdFTP.StoreUnique(const ASourceFile: string);
var
  LSourceStream: TFileStream;
begin
  LSourceStream := TFileStream.Create(ASourceFile, fmOpenRead or fmShareDenyNone); try
    StoreUnique(LSourceStream);
  finally FreeAndNil(LSourceStream); end;
end;

procedure TIdFTP.SendInternalPassive(const ACmd: String; var VIP: string;
  var VPort: integer);
var
  i,bLeft,bRight: integer;
  s: string;
begin
  SendDataSettings;
  SendCmd(ACmd, 227);      {do not localize}
  s := Trim(LastCmdResult.Text[0]);
  // Case 1 (Normal)
  // 227 Entering passive mode(100,1,1,1,23,45)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -