0

I've setup a simple FTPServer that only serves a specific purpose. Watching the code when a get is performed, I see GetFileDate and GetFileSize called twice, but I never see RetrieveFile being called. Instead, the client shows an exception of 'Connection reset by peer'.

All of the properties of IdFTPServer are default except for AllowAnonymousLogin. 100% of the FTP Server code is being shown:

I've tried changing the TerminateWaitTimeout value, but that didn't help.

__fastcall TFTPServer::TFTPServer(TComponent* Owner) : TDataModule(Owner)
{
    root = IncludeTrailingPathDelimiter(GetCurrentDir()) + "files\\";
    IdFTPServer1->Active = true;
}

// ---------------------------------------------------------------------------
void __fastcall TFTPServer::Close(void)
{
    IdFTPServer1->Active = false;
}

// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1FileExistCheck(TIdFTPServerContext *ASender, const UnicodeString APathName, bool &VExist)
{
    String file = StringReplace(APathName, "/", "", TReplaceFlags() <<     rfReplaceAll);
    TSearchRec sr;
    int done = FindFirst(root + file, 0, sr);
    VExist = (done == 0);
    FindClose(sr);
}

// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1GetFileDate(TIdFTPServerContext *ASender, const UnicodeString AFilename, TDateTime &VFileDate)
{
    String file = StringReplace(AFilename, "/", "", TReplaceFlags() << rfReplaceAll);
    TSearchRec sr;
    int done = FindFirst(root + file, 0, sr);
    if (done == 0)
    {
        VFileDate = sr.TimeStamp;
    }
    FindClose(sr);
}

// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1GetFileSize(TIdFTPServerContext *ASender, const UnicodeString AFilename, __int64 &VFileSize)
{
    String file = StringReplace(AFilename, "/", "", TReplaceFlags() << rfReplaceAll);
    TSearchRec sr;
    int done = FindFirst(root + file, 0, sr);
    if (done == 0)
    {
        VFileSize = sr.Size;
    }
    FindClose(sr);
}

// ---------------------------------------------------------------------------
void __fastcall TFTPServer::IdFTPServer1RetrieveFile(TIdFTPServerContext *ASender, const UnicodeString AFileName, TStream *&VStream)
{
    String file = StringReplace(AFileName, "/", "", TReplaceFlags() << rfReplaceAll);
    VStream = new TFileStream(root + file, fmOpenRead);
}

// ---------------------------------------------------------------------------

What am I missing?

Brian P.
  • 206
  • 3
  • 14
  • The `OnGetFileDate` event is triggered only in reply to a `MDTM` command, `OnGetFileSize` in reply only to a `SIZE` command, and `OnRetrieveFile` in reply only to a `RETR` command. If you are not getting the `OnRetrieveFile` event triggered, then either 1) you didn't assign your handler to it, or 2) the client really is not asking to retrieve a file. To verify, sniff the FTP commands using a packet sniffer like Wireshark, or an Indy `TIdLog...` component assigned to the `AContext.Connection.Intercept` property. – Remy Lebeau Jan 16 '19 at 01:07
  • Log shows: 192.168.1.1:55150 Sent 1/16/2019 9:20:07 AM: 230 Anonymous user logged in, proceed. 192.168.1.1:55150 Recv 1/16/2019 9:20:07 AM: MDTM /1FINITY-S100-02011_201709221105.PGM 192.168.1.1:55150 Sent 1/16/2019 9:20:07 AM: 550 Requested action aborted: local error in processing. 192.168.1.1:55150 Recv 1/16/2019 9:20:07 AM: QUIT 192.168.1.1:55150 Sent 1/16/2019 9:20:07 AM: 221 Goodbye. --- When I step through the debugger though, everything appears to run smoothly. – Brian P. Jan 16 '19 at 15:21
  • Strike earlier comment. Wrong file name. Actual log shows as such: 220 Indy FTP Server ready. USER anonymous 331 Anonymous login OK, send e-mail as password. PASS anonymous 230 Anonymous user logged in, proceed. MDTM /FC9543F021-I01.PGM 213 20170922110522 SIZE /FC9543F021-I01.PGM 213 263963758 TYPE I 200 Type set to I. PASV 227 Entering Passive Mode (192,168,1,200,0,20). Stat Disconnected. – Brian P. Jan 16 '19 at 15:34
  • Found the solution: The PASVBoundPortMin/PASVBoundPortMax values needed to be set. – Brian P. Jan 16 '19 at 16:41

0 Answers0