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

📄 dxftpbaseserver.pas

📁 Well known and usefull component for delphi 7
💻 PAS
📖 第 1 页 / 共 4 页
字号:
   DoLog( ClientThread, 'DELE' , Filename , fullfname );
   // here is where you need to check security too.
   if SysUtils.DeleteFile(fullFName) then
        ClientThread.Socket.WriteLn( ErrorText(250))
   else
        ClientThread.Socket.WriteLn( ErrorText(450));
end;
{-----------------------------------------------------------------------------}
procedure TDXFTPBaseServer.DoCommandRNTO(ClientThread: TDXClientThread; Parm: String);
begin
   if not CheckAuthorized( ClientThread, 'RNTO' ) then exit;

   DoLog( ClientThread, 'RNTO' , Parm);

   If RenameFile(PUserSession(ClientThread.fpSessionData)^.RNFO,Parm) then
      ClientThread.Socket.Writeln(ErrorText(250))
   Else
      ClientThread.Socket.Writeln(ErrorText(550));
   PUserSession(ClientThread.fpSessionData)^.RNFO:='';
end;
{-----------------------------------------------------------------------------}
procedure TDXFTPBaseServer.DoCommandRNFR(ClientThread: TDXClientThread; Parm: String);
begin
   if not CheckAuthorized( ClientThread, 'RNFR' ) then exit;

   DoLog( ClientThread, 'RNFR' , Parm);

   If FileExists(Parm) then Begin
      PUserSession(ClientThread.fpSessionData)^.RNFO:=Parm;
      ClientThread.Socket.Writeln(ErrorText(350));
   End
   Else ClientThread.Socket.Writeln(ErrorText(550));
end;
{-----------------------------------------------------------------------------}
procedure TDXFTPBaseServer.DoCommandABOR( ClientThread: TDXClientThread);
begin
   DoLog( ClientThread, 'ABOR', '');

   PUserSession(ClientThread.fpSessionData)^.Abort := True ;
   ClientThread.Socket.Writeln('250 ABOR command successful.');


   // You will have to set an abort variable in the fpSessionData record
   // and if you are doing something abort it! Simple enough.
//   ## Need example on how to abort a transfer
end;
{-----------------------------------------------------------------------------}
procedure TDXFTPBaseServer.DoCommandAPPE(ClientThread: TDXClientThread; FileName: String);
begin
   if not CheckAuthorized( ClientThread, 'APPE' ) then exit;
   DoLog( ClientThread, 'APPE',FileName );

   StoreFile( ClientThread , FileName , TRUE ) ;
end;
{
// Merged into StoreFile
var
   FileToRetr:String;
   FileHandle:Integer;
   Tries:Integer;

begin
   with PUserSession(ClientThread.fpSessionData)^ do Begin
      FileToRetr:=CurrentDir+Parm;
      NewConnect.ipAddress:=PeerIPAddress;
      If PASV or DataSocket.Connect(NewConnect) then Begin
         if not FileExists(FileToRetr) then
            ClientThread.Socket.WriteLn(ErrorText(502))
         Else Begin
            FileHandle:=FileOpen(FileToRetr,fmOpenWrite);
            FileSeek(FileHandle, 0, 2);
            ClientThread.Socket.Writeln(ErrorText(150)+#32+
               Parm+' to '+PeerIPAddress+'.');
            RestPos:=0;
            Tries:=0;
            DataSocket.RestartCharactersPerSecondTimer;
            While DataSocket.Connected do Begin
               If Tries>100 then Begin
                  Break;
               End;
               If DataSocket.Readable then Begin
                  If DataSocket.CharactersToRead=0 then begin
                     Break; // dropped connection
                  end;
                  DataSocket.SaveTo(Filehandle,500);
                  Tries:=0;
               End
               Else Begin
                  DoSleepEx(10);
                  ProcessWindowsMessageQueue;
                  Inc(Tries);
               End;
            End;

         DoLog( ClientThread, FileToRetr+' @ '+DXString.SizeStamp(DataSocket.CharactersPerSecondReceived));

            FileClose(FileHandle);
            DataSocket.Disconnect;
            ClientThread.Socket.Writeln(ErrorText(226));
         End;
      End
      Else ClientThread.Socket.Writeln(ErrorText(450));
   end;
end;
}
{-----------------------------------------------------------------------------}
procedure TDXFTPBaseServer.DoCommandPASV(ClientThread: TDXClientThread);
Var
   WS:String;
   NewListen :PNewListen;
   tries : integer ;
   PasvBound : Boolean ;
begin
   if not CheckAuthorized( ClientThread, 'PASV' ) then exit;

   If fUseNatAddr then
      Ws:=fNatAddress
   Else
      Ws:=ClientThread.Socket.LocalIPAddress;

   PUserSession(ClientThread.fpSessionData)^.PASV:=True;
   PUserSession(ClientThread.fpSessionData)^.Abort := False ;

   New(NewListen);

   with NewListen^ do begin
         Port:=NextDataPort;
         UseNAGLE:=True;
         UseBlocking:= True;
         UseUDP:=False;
         WinsockQueue:= 1;
         ConnectionLess:= False;
   end;
   PasvBound:= False ;
   tries := 100 ;
   while ( tries > 0)  do begin
     PasvBound := PUserSession(ClientThread.fpSessionData)^.DataSocket.Listen(NewListen);
     CalcNextDataPort ;
     if PasvBound then Break ;
     NewListen^.Port:=NextDataPort;
     Dec( tries );
   end;

   Ws:=StringReplace(Ws,'.',',',[rfReplaceAll])+','+inttostr( trunc(NewListen^.Port div 256) )+','+inttostr( NewListen^.Port -(trunc(NewListen^.Port div 256)*256) );

   if PasvBound then Begin
      ClientThread.Socket.Writeln(ErrorText(227)+' ('+Ws+').');
      DoLog( ClientThread, 'PASV', '('+Ws+')');
      DoSleepEx(250); // give "INTERNET" time to digest!
      tries:=16; // waits upto 8 seconds:
      while not PUserSession(ClientThread.fpSessionData)^.DataSocket.Accept(
         PUserSession(ClientThread.fpSessionData)^.DataSocket) do Begin
         dec( tries ) ;
         if tries = 0 then begin
            DoLog( ClientThread, 'PASV [no client!]','');
            ClientThread.Socket.Writeln(ErrorText(550));
            break;
         end;
         DoSleepEx(500) ;
      end;
   end
   else begin
      DoLog( ClientThread, 'PASV' , '[listen failed]');
      ClientThread.Socket.Writeln(ErrorText(550));
   End;
   Dispose(NewListen);
   If PUserSession(ClientThread.fpSessionData)^.DataSocket.Connected then Begin
      DoLog( ClientThread, 'PASV' ,  '[Client Connected OK]');
   end
   Else Begin
      PUserSession(ClientThread.fpSessionData)^.PASV:=False;
   End;
end;

{-----------------------------------------------------------------------------}
procedure TDXFTPBaseServer.DoCommandPASS(ClientThread: TDXClientThread;
  password: String; var SuccessfulLogin: Boolean);
begin
   DoLog( ClientThread, 'PASS', Password );

   // Here is where you do the user lookup
   // If not found:  331 Password required for 'USER'.
   with PUserSession(ClientThread.fpSessionData)^ do Begin
      AuthorizedState:=False;
      If User='' then Begin
         ClientThread.Socket.Writeln(ErrorText(503));
         Exit;
      End;

      if not ValidateUser(ClientThread , User , Password ) then begin
         SuccessfulLogin:=False;
         ClientThread.Socket.Writeln(ErrorText(530));
         ClientThread.Socket.Disconnect;
      end
      else begin
         Pass:=Password;
         AuthorizedState:=True;
         CurrentDir:=HomeDir;
         HomeDir:=HomeDir;
{ UNCOMMENT IF MOTD IS NOT USED IN .PROCESSSESSION() in ONNEWCONENCT
         ClientThread.Socket.Writeln('230 "'+
            PUserSession(ClientThread.fpSessionData).User+
            '" user logged in.');
}
     // Once the user lookup is done, you should set the "security level/group"
     // and root directory in the Session Data!
         SuccessfulLogin:=True; // Enabled the MOTD, if it was false
                            // you would need to write something to the socket!!
                            // If MOTD is disabled, then you would have to write
                            // something to the socket too!
         if Assigned( fAftervalidUser ) then
             SuccessfulLogin:=fAfterValidUser( ClientThread , User , Password );
         if not SuccessfulLogin then
            ClientThread.Socket.Disconnect;
      end;
   end; {with}
end;
{-----------------------------------------------------------------------------}
{
procedure TDXFTPBaseServer.DoCommandSIZE(ClientThread: TDXClientThread;Parm: String);
//Var
//   MySRec: PSRec;
var
siz : int64 ;
begin
   if not CheckAuthorized( ClientThread, 'SIZE' ) then exit;
   DoLog( ClientThread, 'SIZE',PARM );
   FileSize()

   MySRec:=DXFileAllocationTable1.FileInformation(PUserSession(ClientThread.fpSessionData)^.CurrentDir+Parm);
   ## FileSize
   If MySRec<>Nil then Begin
      ClientThread.Socket.Writeln(ErrorText(213)+#32+IntToStr(MySRec^.FileSize))
   End
   Else
      ClientThread.Socket.Writeln(ErrorText(550));
end;
}
{-----------------------------------------------------------------------------}
function TDXFTPBaseServer.ValidateUser(ClientThread: TDXClientThread;
  Username, Password: string): boolean;
begin
  if Assigned( fValidateUser ) then
    result:= fValidateUser(ClientThread, Username, Password)
  else
    result := true;
end;
{-----------------------------------------------------------------------------}


{-----------------------------------------------------------------------------}

procedure TDXFTPBaseServer.DoDataSocketOnRead(xClientThread: TThread;
  BytesToRead, Readbytes: integer; var AbortXfer: boolean);
begin
//
   if Assigned( xClientThread ) then begin

      Inc(PUserSession(TDXClientThread(xClientThread).fpSessionData)^.BytesRcv , ReadBytes );
      CalcSpeed( TDXClientThread(xClientThread) , ReadBytes );
      if Assigned( feDataSocketOnRead )  then
        FeDaTaSocketOnRead( TDXClientThread(xClientThread) , -1 , BytesToRead , ReadBytes , AbortXfer);
   end;
end;

procedure TDXFTPBaseServer.DoDataSocketOnWrite(xClientThread: TThread;
  TotalBytes, BytesLeft, BytesSent: integer; var AbortXfer: boolean);
begin
   if Assigned( xClientThread ) then begin
      Inc( PUserSession(TDXClientThread(xClientThread).fpSessionData)^.BytesSnd, BytesSent );

      
      CalcSpeed( TDXClientThread(xClientThread) , BytesSent );

      if Assigned( feDataSocketOnWrite ) then
        FeDaTaSocketOnWrite( TDXClientThread(xClientThread) ,
            TotalBytes ,
             ABs(TotalBytes-Bytesleft),BytesSent, AbortXfer);
   end;
end;

procedure TDXFTPBaseServer.CalcSpeed(ClientThread: TDXClientThread;
  BytesXfer : integer);
var
  anow : TDateTime ;
  diff : int64 ;
begin
   anow:= Now ;
   with PUserSession(ClientThread.fpSessionData)^ do begin
      if SpeedStartTS = 0 then begin
          SpeedStartTs  := aNow ;
          CurrSpeed     := 0  ;
          SpeedBytesXfer := 0 ;
      end;

      Inc( SpeedBytesXfer  , BytesXfer );
      diff := MilliSecondsBetween(aNow, SpeedStartTS) ;
//      diff :=aNow -  SpeedStartTS ;

      if ( diff > 3000) then begin // reset every 3 seconds
          if ( diff > 10000 ) then begin //Restart data from last transfer
             SpeedStartTs  := aNow ;
             CurrSpeed     := 0 ;
             SpeedBytesXfer := BytesXfer;
          end
          else begin
             SpeedStartTs := aNow ;
             CurrSpeed    := SpeedBytesXfer div Max((diff div 1000),1) ;
             SpeedBytesXfer := BytesXfer;
          end;
{      end
      else if (diff < 100) and ( diff > 0 ) then begin
       // Don磘 do anything
      end
      else begin // Calc speed
//          CurrSpeed    := SpeedBytesXfer div Max((diff div 1000),1) ;
}      end;
   end;
end;

end.

⌨️ 快捷键说明

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