FluentFTP: GetListing silently fails and returns empty array

FTP Server OS: Linux

FTP Server Type: Unsure

Client Computer OS: Windows

FluentFTP Version: Multiple versions, including latest

Framework: .NET 4.5

Iterating through a series of directories, checking if they exist, getting a listing, and download files.

On the Nth directory in the list (always the same N), GetListing randomly returns an empty array with no exception, even though there are files in the directory.

It is 100% reproducible, and always occurs on the same directory.

It seems to be a timing issue, as changing the ordering of commands can prevent the issue.

The N+1 directory works as expected.

It looks like a reconnect is being done in the background between directory N and N+1.

I’m guessing the connection is getting dropped, and GetListing is silently failing to get any data.

Logs :

# DirectoryExists("DirectoryN")

# GetWorkingDirectory()
Command:  PWD
Response: 257 "/" is the current directory
Command:  CWD DirectoryN
Response: 250 CWD command successful
Command:  CWD /
Response: 250 CWD command successful

# GetListing("DirectoryN", Auto)
Command:  TYPE I
Response: 200 Type set to I

**# This should be returning an actual file listing**
# OpenActiveDataStream(AutoActive, "MLSD DirectoryN", 0)
Command:  EPRT |1|10.8.210.15|58752|

# DirectoryExists("DirectoryN+1")

# GetWorkingDirectory()
Status:   Disposing FtpSocketStream...

**# Looks like maybe a reconnect was needed during the last listing, but GetListing just failed silently?**
# Connect()
Status:   Connecting to HOST:21
Response: 220 FTP Server ready.
Command:  USER USER
Response: 331 Password required for USER
Command:  PASS ***
Response: 230 User USER logged in
Command:  FEAT
Response: 211 End
Response: 211-Features:
Response: MDTM
Response: MFMT
Response: TVFS
Response: MFF modify;UNIX.group;UNIX.mode;
Response: MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;
Response: REST STREAM
Response: SIZE
Status:   Text encoding: System.Text.ASCIIEncoding
Command:  SYST
Response: 215 UNIX Type: L8
Command:  PWD
Response: 257 "/" is the current directory
Command:  CWD DirectoryN+1
Response: 250 CWD command successful
Command:  CWD /
Response: 250 CWD command successful

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 25 (1 by maintainers)

Most upvoted comments

@FanDjango Can we adopt this (just a rough design, what are your thoughts?):

  1. If a disconnect occurs, we do our best to reconnect
  2. If the auto reconnect fails, throw a specific type of exception (FtpReconnectFailedException) or something that users can detect
  3. Leave it to the users to handle further cases

Thanks for looking into this.

I recreated these logs in the latest version of Fluent.

I am using the legacy logger, and didn’t capture the initial connection for some reason, but I’m assuming the reconnect in the response below has the same FEAT response.

>         DirectoryExists("DirectoryN")
Command:  PWD
Status:   Waiting for response to: PWD
Response: 257 "/" is the current directory
Command:  CWD DirectoryN
Status:   Waiting for response to: CWD DirectoryN
Response: 250 CWD command successful
Command:  CWD /
Status:   Waiting for response to: CWD /
Response: 250 CWD command successful
>         GetListing("DirectoryN", Auto)
>         OpenActiveDataStream(AutoActive, "MLSD DirectoryN", 0)
Command:  EPRT |1|HOST|61117|
Status:   Waiting for response to: EPRT |1|HOST|61117|
**### should have gotten a listing here**
>         DirectoryExists("DirectoryN+1")
Status:   Disposing FtpSocketStream(control connection)
Status:   Reconnect due to disconnected control connection
>         ReConnect()
Status:   FluentFTP 42.1.0.0
Status:   Connecting to IP #1= ***:21
Status:   Waiting for a response
Response: 220 FTP Server ready.
Command:  USER ***
Status:   Waiting for response to: USER ***
Response: 331 Password required for ***
Command:  PASS ***
Status:   Waiting for response to: PASS ***
Response: 230 User *** logged in
Command:  FEAT
Status:   Waiting for response to: FEAT
Response: 211-Features:
Response: MDTM
Response: MFMT
Response: TVFS
Response: MFF modify;UNIX.group;UNIX.mode;
Response: MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;
Response: REST STREAM
Response: SIZE
Response: 211 End
Status:   Text encoding: System.Text.ASCIIEncoding
Command:  SYST
Status:   Waiting for response to: SYST
Response: 215 UNIX Type: L8
Status:   Listing parser set to: Machine
Command:  PWD
Status:   Waiting for response to: PWD
Response: 257 "/" is the current directory
Command:  CWD DirectoryN+1
Status:   Waiting for response to: CWD DirectoryN+1
Response: 250 CWD command successful
Command:  CWD /
Status:   Waiting for response to: CWD /
Response: 250 CWD command successful
>         GetListing("DirectoryN+1", Auto)
Command:  TYPE I
Status:   Waiting for response to: TYPE I
Response: 200 Type set to I
>         OpenActiveDataStream(AutoActive, "MLSD DirectoryN+1", 0)
Command:  EPRT |1|HOST|61119|
Status:   Waiting for response to: EPRT |1|HOST|61119|
Response: 200 EPRT command successful
Command:  MLSD DirectoryN+1
Status:   Waiting for response to: MLSD DirectoryN+1
Response: 150 Opening BINARY mode data connection for MLSD
+---------------------------------------+
**### Actual works here**
-----------------------------------------
Status:   Disposing FtpSocketStream(data connection)
>         CloseDataStream()
Status:   Waiting for a response
Response: 226 Transfer complete
Status:   Disposing FtpSocketStream(data connection)