FluentFTP icon indicating copy to clipboard operation
FluentFTP copied to clipboard

FileExists return false when file exists on server

Open kfrid opened this issue 7 years ago • 11 comments

FileExists is returning false on a file that exists on the server. I use relative path for this. Use the below code flow, here the exists variable is false but the Bok.xlsx-file exists on the server in the specified working directory.

var ftpClient = new FtpClient("url to server", "username", "password");
await ftpClient.ConnectAsync();
await ftpClient.SetWorkingDirectoryAsync("relative path");
var exists = await ftpClient.FileExistsAsync("Bok.xlsx");

If I change the last row in the above code example to as below, I can figure out that the file exists by code. Here the exists-variable is true.

var ftpClient = new FtpClient("url to server", "username", "password");
await ftpClient.ConnectAsync();
await ftpClient.SetWorkingDirectoryAsync("relative path");
var exists = (await ftpClient.GetListingAsync()).Any(x => x.Name == "Bok.xlsx");

kfrid avatar Aug 26 '18 18:08 kfrid

I'm also see this issue; the servers I've tested this on Windows 2008R2, Windows 2012 and public ubuntu/redhat srver

grahamehorner avatar Aug 31 '18 15:08 grahamehorner

Any news about this isuue? I put a try catch in my code to prevent any error when I copy, rename or delete in the ftp server.

LuisSerrano avatar Jan 25 '19 11:01 LuisSerrano

I had the same issue. Here is my workaround:

if(!ftpClient.Download(memStream, ftpFilePath))
   throw new FtpException($"Failed to download file ftp://{ftpHost}/{ftpFilePath}. Please make sure the file exists.");

Another option

// Verify directory
if(!ftpClient.DirectoryExists(dir))
    throw new FtpException($"FTP directory {dir} does not exist.");

// Get list of files in directory
var listing = ftpClient.GetListing(dir);

// Verify the file is in the directory
if(listing.All(x => x.FullName != ftpFilePath))
    throw new FtpException($"FTP file {ftpFilePath} does not exist.");

ghost avatar Jan 30 '19 19:01 ghost

Problem continues on last version image

andresm9 avatar Feb 14 '19 22:02 andresm9

Works over here, just took a random FTP. Maybe it is specific to particular FTP server software?

using FluentFTP;
using System;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Started!");

            FtpClient ftpClient = new FtpClient("ftp.ihe.net");

            Console.WriteLine("Connecting...");
            ftpClient.Connect();
            Console.WriteLine("Connected");

            Console.WriteLine("Get listing...");
            var files = ftpClient.GetListing("MarketingAndPresentations/Artwork_Images/");

            foreach (var file in files)
            {
                if (file.Type == FtpFileSystemObjectType.File)
                {
                    Console.WriteLine($"{file.FullName} = {ftpClient.FileExists(file.FullName)}");
                }
            }

            Console.WriteLine("Finished!");
            Console.ReadKey(intercept: true);
        }
    }
}

KoalaBear84 avatar Feb 15 '19 05:02 KoalaBear84

After the instruction GetListing the command FileExists works fine. I do not know why it can be ...

LuisSerrano avatar Feb 21 '19 08:02 LuisSerrano

Can you guys submit the FTP logs (see the FAQ on how to log stuff) so we can debug this? Especially the part pertaining to the call to FileExists.

robinrodricks avatar Jun 08 '19 09:06 robinrodricks

I am running into the same issue. I checked the output logs (attached at the bottom) and found the location in code where the problem might be. The FileExists and FileExistsAsync Methods do not cater for the 550 - "SIZE not allowed in ASCII mode" Error. But since it only checks for Error 550 (introduced with #179), it returns without attempting anything further. A pull request for a change will follow shortly that caters for the specific error message.

# ConnectAsync()
Status:   Connecting to ***:21
Response: 220 FTP Server ready.
Command:  USER ***
Response: 331 Password required for ftpserver
Command:  PASS ***
Response: 230 User ftpserver logged in
Command:  FEAT
Response: 211 End
Response: 211-Features:
Response: MFF modify;UNIX.group;UNIX.mode;
Response: REST STREAM
Response: MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;
Response: UTF8
Response: EPRT
Response: EPSV
Response: LANG zh-CN;zh-TW;bg-BG;en-US;es-ES;fr-FR;it-IT;ja-JP;ko-KR;ru-RU
Response: MDTM
Response: TVFS
Response: MFMT
Response: SIZE
Status:   Text encoding: System.Text.UTF8Encoding+UTF8EncodingSealed
Command:  OPTS UTF8 ON
Response: 200 UTF8 set to on
Command:  SYST
Response: 215 UNIX Type: L8

# FileExistsAsync("/somefolder/288120b8_transferfile.txt")
Command:  SIZE /somefolder/288120b8_transferfile.txt
Response: 550 SIZE not allowed in ASCII mode

# Dispose()
Status:   Disposing FtpClient object...
Command:  QUIT
Response: 221 Goodbye.
Status:   Disposing FtpSocketStream...
Status:   Disposing FtpSocketStream...

Dragonsangel avatar Aug 05 '19 09:08 Dragonsangel

@Dragonsangel Does this solve your issue? I applied a variation of your fix.

https://www.nuget.org/packages/FluentFTP/27.0.2

robinrodricks avatar Aug 06 '19 11:08 robinrodricks

@robinrodricks the fix worked in my scenario. Thanks for cleaning up the fix, was wondering about the double "Get Filesize" implementation.

Dragonsangel avatar Aug 06 '19 12:08 Dragonsangel

Great to hear that. Thanks for the PR btw and sorry again to reject it.

robinrodricks avatar Aug 06 '19 12:08 robinrodricks

Now when FileExists is implemented by SIZE, I'm getting false positives (file does not exist, but server returns positive result and I'm getting true).

Log:

Command:  CWD /private/Test2/Docs/Teensy
Waiting for response to: CWD /private/Test2/Docs/Teensy
Response: 250 CWD command successful [29ms]
Command:  PWD
Waiting for response to: PWD
Response: 257 "/private/Test2/Docs/Teensy" is the current directory [33ms]
>         OpenWrite("Teensy32_1.pdf", Binary)
>         GetFileSize("Teensy32_1.pdf")
Command:  SIZE Teensy32_1.pdf
Waiting for response to: SIZE Teensy32_1.pdf
Response: 550 Teensy32_1.pdf: No such file or directory [40ms]

Here it tells correctly, that file does not exist, and then

>         OpenDataStream("STOR Teensy32_1.pdf", 0)
>         OpenPassiveDataStream(PASV, "STOR Teensy32_1.pdf", 0)
Command:  PASV
Waiting for response to: PASV
Response: 227 Entering Passive Mode (195,78,67,12,138,204). [28ms]
Connecting to IP #1= ***:35532
Command:  STOR Teensy32_1.pdf
Waiting for response to: STOR Teensy32_1.pdf
Response: 150 Opening BINARY mode data connection for Teensy32_1.pdf [36ms]
SSL Buffering force disabled, is .NET 5.0 and later
FTPS authentication successful, lib = .NET SslStream, cipher suite = Tls12 (Aes128, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 44550, 255) [72ms]
Closing/Disposing FtpSocketStream(data connection)
>         DirectoryExists("/private/Test2/Docs/Teensy/Teensy32_2.pdf")
Command:  CWD /private/Test2/Docs/Teensy/Teensy32_2.pdf
Waiting for response to: CWD /private/Test2/Docs/Teensy/Teensy32_2.pdf
Response: 550 /private/Test2/Docs/Teensy/Teensy32_2.pdf: No such file or directory [64ms]
>         FileExists("/private/Test2/Docs/Teensy/Teensy32_2.pdf")
Command:  SIZE /private/Test2/Docs/Teensy/Teensy32_2.pdf
Waiting for response to: SIZE /private/Test2/Docs/Teensy/Teensy32_2.pdf
Response: 226 Transfer complete [1,6s]

However, file Teensy32_2.pdf DOES NOT exist in that location.

Listing

wojciechsura avatar Mar 24 '23 14:03 wojciechsura

This may shed some more light on the case:

Waiting for response to: PWD
Response: 226 Transfer complete [3ms]
Failed to parse working directory from: Transfer complete
>         GetListing(null, Auto)
>         OpenDataStream("MLSD /", 0)
>         OpenPassiveDataStream(PASV, "MLSD /", 0)
Command:  PASV
Waiting for response to: PASV
Response: 257 "/private/Test2/Docs/Teensy" is the current directory [27ms]
Zgłoszony wyjątek: „FluentFTP.Exceptions.FtpException” w FluentFTP.dll
Malformed PASV response: "/private/Test2/Docs/Teensy" is the current directory

wojciechsura avatar Mar 24 '23 14:03 wojciechsura

Tell the FluentFTP version you are showing these logs for

FanDjango avatar Mar 24 '23 14:03 FanDjango

That would be 46.0.2.

I have read some documentation related to FTP codes and it looks like that server may respond with 226 to inform, that it have successfully closed the connection after file upload. The issue happens only after uploading files to the server.

wojciechsura avatar Mar 24 '23 14:03 wojciechsura

Ok, please make a new issue for this. I can see a problem that needs debugging.

FanDjango avatar Mar 24 '23 14:03 FanDjango

It has nothing to do with FileExists return false when file exists on server,

it is:

Command:  STOR Teensy32_1.pdf
Waiting for response to: STOR Teensy32_1.pdf
Response: 150 Opening BINARY mode data connection for Teensy32_1.pdf [36ms]
SSL Buffering force disabled, is .NET 5.0 and later
FTPS authentication successful, lib = .NET SslStream, cipher suite = Tls12 (Aes128, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 44550, 255) [72ms]
Closing/Disposing FtpSocketStream(data connection)

and then the code just continues... although the transfer is still running.... Pls transfer this to a new issue.

FanDjango avatar Mar 24 '23 14:03 FanDjango