Giter VIP home page Giter VIP logo

robinrodricks / fluentftp Goto Github PK

View Code? Open in Web Editor NEW
3.0K 86.0 637.0 16.97 MB

An FTP and FTPS client for .NET & .NET Standard, optimized for speed. Provides extensive FTP commands, File uploads/downloads, SSL/TLS connections, Automatic directory listing parsing, File hashing/checksums, File permissions/CHMOD, FTP proxies, FXP support, UTF-8 support, Async/await support, Powershell support and more. Written entirely in C#.

License: MIT License

C# 94.35% Batchfile 0.17% PowerShell 0.91% Visual Basic .NET 2.75% Shell 0.61% Dockerfile 1.07% Python 0.14%
ftp ftp-client ftps ssl tls unix iis net-core net-standard net-framework

fluentftp's Introduction

fluentftp's People

Contributors

adhara3 avatar alexgubanow avatar artiomchi avatar augustoproiete avatar bgroenks96 avatar dasraschloch avatar datvm avatar elmar69 avatar fandjango avatar fire-lizard avatar hornell avatar ibsenrune avatar jblacker avatar jnyrup avatar jptrosclair avatar mjmckp avatar mortens4444 avatar n0ix avatar oliviersow avatar rharrisxtheta avatar rmja avatar robinrodricks avatar sdiaman1 avatar stengnath avatar taoyouh avatar tommysor avatar tonimontana avatar tyoshiyuki avatar wakabayashik avatar wolfspiritm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fluentftp's Issues

FtpException No Deserializer Constructor

On all Serializable Exception the Constructor

   protected Exception(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }

must be Implemented so every Serializer can DeSerialize the Exception

Concurrency issue in FtpClient

In FTP Client we are not initializing m_lock as static.
I wanted to append file using multiple thread. but since m_lock object is per FtpClient different connection are failing on concurrency.
Getting below exception:
"The process cannot access the file because it is being used by another process."
I tested by making m_lock object as static , and that seems to work.

Signed package NuGet

I've seen this part in the build_nuget.bat file :
:: Build signed DLL
rem %msbuild% /p:Configuration=Release /p:SignAssembly=true /p:AssemblyOriginatorKeyFile="%snk%" FluentFTP\FluentFTP.csproj

Is it possible to publish a NuGet package of this library signed ?

Upload of great number of files (100+) suddenly slow

Hi,
since update to last nuget 16.2.4 my batch uploads (1000 - 2000 files per directory, 5-6 such uploads) became very slow via FtpClient.UploadFile() method.

I've been able to trace the problem to the now-always-executed FileExists() method call, which is present at the beginning of every UploadFile() overload and that should fix issue #46. Since commit c484877 the FileExists() method is called before every single upload, and if the file exists it is deleted before the actual upload.

While this may be a nice workaround for the issue of uploading a file smaller than the previous, it becomes a nightmare for batch transfers: the directory is checked every time, and every successful upload produces a longer directory listing, so the check gets slower and slower! The transfer time skyrockets from seconds to hours.

I've been able to temporarily work around the problem by directly invoking the UploadFileInternal method via reflection (I was already using streams, so it's been easy), but I'm submitting this issue for a more structured and robust solution.

It could either be a way to completely ignore file existence checks (so people knowing that could just turn this check off) or a bulk transfer for a specific destination directory. In this second case the file list is checked only once, before the transfer begins, and this behavior becomes the distinguishing feature from a loop of UpdateFile() calls.

.NET Core

Are you planning to support .NET Core?

[net core] suspend while calling UploadFile or DownloadFile

For the .net core version, thread will be suspended about 5 minutes while uploading or downloading file.

client.DownloadFile("D:\\1.txt", "1.txt");
client.UploadFile("D:\\2.txt", "/2.txt");

I am not sure if it's because i am behind the Microsoft ISA Server proxy, but the code works well on .net framework 4.5 . The methods which don't use data connection work well on .net core.

I will try it again while I get home as there is no need a proxy.

How to use ValidateCertificate in VB?

Hi everybody,

somehow I cant figure out how to validate and always accept TLS certificates when connecting to a FTPS server with Explicit TLS in .NET (plain FTP works perfectly).

According to VS-Debugger "ValidateCertificate" must be handled with RaiseEvent >> but what's the correct syntax?

Private Shared Sub TestServer()
	Using cl As New FtpClient()
		cl.Host = m_host
		cl.Credentials = New NetworkCredential(m_user, m_pass)
		cl.EncryptionMode = FtpEncryptionMode.Explicit
		cl.ValidateCertificate += Function(control, e) 
                                           		e.Accept = True
                                                     End Function
		cl.connect()
	End Using
End Sub

Thx for your help!

Append to file

Hi
Do you have any example to show how to append text to existing text file.
Regards
Ajay

Async Put

I would think there would be an obvious way to:

FtpClient c = new FtpClient()
...
await c.UploadFile(localfile, remotefile);

I don't see how to do this. I tried BeginOpenWrite and attempted to use Task..FromAsync but could not get it working. Can you please provide an example.

Thank you.

Proxy Implementation?

Hi,

first thanks for your hard work, really appreciated. I like your library and it works fine for me, but can you show me how to implement proxy support for a connection? I have additional data from my VPN provider I would like to user for FTP connections (Proxy username, proxy server, proxy passwort) - in the past I could insert those in FTP client like Filezilla. Now I looked at avalaible properties in FTPFluent but right now, theres's no way to use proxy authentification data?

I'm referring to this code:

public static class ConnectExample {
        public static void Connect() {
            using (FtpClient conn = new FtpClient()) {
                conn.Host = "localhost";
                conn.Credentials = new NetworkCredential("ftptest", "ftptest");
                conn.Connect();
            }
        }
}

Any chance for proxy support in future? Thanks!

Unneeded calls to GetWorkingDirectory() in GetListing(path, options)

Hi,

i just did some profiling because my app was a little bit slower than FileZilla when traversing all directories.
My app has many Calls to GetListing and i noticed GetWorkingDirectory() is called even when not needed.
My profiler said GetWorkingDirectory() uses up 12% of my total execution time.

So i changed the GetListing Function to only call GetWorkingDirectory() when needed

FtpListItem item = null;
List<FtpListItem> lst = new List<FtpListItem>();
List<string> rawlisting = new List<string>();
string listcmd = null;
string pwd = null;
string buf = null;
bool includeSelf = (options & FtpListOption.IncludeSelfAndParent) == FtpListOption.IncludeSelfAndParent;

if (path == null || path.Trim().Length == 0) {
	pwd = GetWorkingDirectory();
	if (pwd != null && pwd.Trim().Length > 0)
		path = pwd;
	else
		path = "./";
} else if (!path.StartsWith("/")) {
	pwd = GetWorkingDirectory();
	if (pwd != null && pwd.Trim().Length > 0)
	{
		if (path.StartsWith("./"))
			path = path.Remove(0, 2);
		path = string.Format("{0}/{1}", pwd, path).GetFtpPath();
	}
}

Maybe this is helpful to someone

Cheers

STOR Command not working with destination FTP

hello! I am trying to submit a plain text file from my PC to an MVS MainFrame. When attempting to put in the destination path for the openwrite, it times out on me. doing this manually through the cmd prompt, the put command works just fine and the data is transmitted. My destination path is written in MVS format EX: xxx.xxx.xxx.xxx and I have it surrounded by single quotes to take the string literally. Am I doing something wrong? Is this an issue with going to a mainframe with fluentftp? Is this an issue on their end?

image

Getting Login Errors but works fine when opening in Firefox

Hi Guys,

I'm trying to get directory listing of this : site ftp://163.25.117.117/chingter/ and I'm getting a Login Incorrect error

An exception of type 'FluentFTP.FtpCommandException' occurred in FluentFTP.dll but was not handled in user code

Additional information: Login incorrect.

This is my code
use conn = new FtpClient() conn.Host <- uri.Host; conn.Credentials <- new NetworkCredential("someuser","") conn.EncryptionMode <- FtpEncryptionMode.None; conn.SetWorkingDirectory(uri.PathAndQuery) //conn.Credentials <- new NetworkCredential("ftptest", "ftptest"); let listings = conn.GetListing()

When I open the same FTP url in firefox, it is able to display the listing. I think I'm missing something obvious. Help, please?

A call to SSPI failed, see inner exception

Hello -

I am trying to make a Explicit SSL request to my UNIX based ftpd.

                conn.EncryptionMode = FtpEncryptionMode.Explicit;
                conn.SslProtocols = SslProtocols.Tls12;

I receive the exception "A call to SSPI failed, see inner exception"

The ftp server logs give me this :

Failed TLS negotiation on control channel, disconnected. (SSL_accept(): (1) error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher)

Any insight you can provide would be greatly appreciated!

DownloadFile throws exceptions in some cases

In the document, Download method described
"Downloads a file from the server to the local file system. Returns true if succeeded, false if failed or file does not exist. ".

But "DownloadFile(localPath, remotePath)" raise error exception when the remotePath dose not exist.

Error: FluentFTP.FtpException: Error while downloading the file from the server.See InnerException for more info. ---> FluentFTP.FtpCommandException: Command not implemented
at FluentFTP.FtpClient.OpenPassiveDataStream(FtpDataConnectionType type, String command, Int64 restart)
at FluentFTP.FtpClient.OpenPassiveDataStream(FtpDataConnectionType type, String command, Int64 restart)
at FluentFTP.FtpClient.OpenDataStream(String command, Int64 restart)
at FluentFTP.FtpClient.OpenRead(String path, FtpDataType type, Int64 restart)
at FluentFTP.FtpClient.DownloadFileInternal(String remotePath, Stream outStream)

Handle edge cases of failure for RETR command

From crypto, by D. J. Bernstein

Normally the server responds with a mark using code 150. It then stops accepting new connections, attempts to send the contents of the file over the data connection, and closes the data connection. Finally it

  • accepts the RETR request with code 226 if the entire file was successfully written to the server's TCP buffers;
  • rejects the RETR request with code 425 if no TCP connection was established;
  • rejects the RETR request with code 426 if the TCP connection was established but then broken by the client or by network failure; or
  • rejects the RETR request with code 451 or 551 if the server had trouble reading the file from disk.

The server is obliged to close the data connection in each of these cases. The client is not expected to look for a response from the server until the client sees that the data connection is closed.

The server may reject the RETR request without first responding with a mark. In this case the server does not touch the data connection. RFC 959 allows code 550 for file-does-not-exist, permission-denied, etc., and code 450 for out-of-memory, disk-failure, etc.

The client needs to be prepared for many different ways that RETR can fail:

  • After sending the RETR request, the client reads one response from the server. If this response is anything but a mark (for example, the server can't find the file, or doesn't have permission to open it, or is temporarily out of memory, or the server crashes and the connection is closed without a response, or the server is overloaded and the client times out before receiving a response), the client stops and reports temporary failure.
  • After sending the RETR request and reading a mark, the client reads data from the data connection until FIN (end of file), or a TCP error (for example, TCP reset or network unreachable), or timeout. The client saves the data, remembers whether there was a FIN, and closes the data connection.
  • After sending the RETR request, reading a mark, reading data from the data connection, and closing the data connection, the client reads another response from the server. If this response is acceptance and the data connection ended with FIN, the client knows that it has received the entire file from the server. Otherwise the client reports temporary failure; the file has (probably) been truncated.

Note that code 226 from the server does not guarantee that the client has received, or will receive, the entire file. The client must check for TCP errors on the data connection.

Some clients do not close the data connection until they receive the 226 response from the server. This behavior is permitted by RFC 959. However, I recommend that clients close the data connection immediately after seeing the end of data.

Resume uploading of files if server disconnects midway

DownloadFile() and UploadFile() should resume uploading of files if server disconnects midway, since occasional connection resets are valid.

public static void Download(this FtpClient ftp, string remoteFilePath, string localFilePath) {
	using (var fs = new FileStream(filePath: localFilePath, fileMode: FileMode.Create, fileAccess: FileAccess.Write, fileShare: FileShare.None)) {
		// istream.Position is incremented accordingly to the reads you perform
		// istream.Length == file size if the server supports getting the file size
		// also note that file size for the same file can vary between ASCII and Binary
		// modes and some servers won't even give a file size for ASCII files! It is
		// recommended that you stick with Binary and worry about character encodings
		// on your end of the connection.
		var buffer = new byte[8192];
		var offset = 0;
		var remoteStream = ftp.OpenRead(remoteFilePath);
		try {
			while (offset < remoteStream.Length) {
				try {
					int len;
					while ((len = remoteStream.Read(buffer, 0, buffer.Length)) > 0) {
						fs.Write(buffer, 0, len);
						offset += len;
					}
				}
				catch (IOException ex) {
					if (ex.InnerException != null) {
						var iex = ex.InnerException as System.Net.Sockets.SocketException;
						if (iex != null && iex.ErrorCode == 10054) {
							remoteStream.Close();
							remoteStream = ftp.OpenRead(remoteFilePath, restart: offset);
						}
						else throw;
					}
					else throw;
				}
			}
		}
		finally {
			remoteStream.Close();
		}
	}
}

public static void Upload(this FtpClient ftp, string localFilePath, string remoteFilePath) {
	using (var fs = new FileStream(filePath: localFilePath, fileMode: FileMode.Open, fileAccess: FileAccess.Read, fileShare: FileShare.Read)) {
		Upload(ftp: ftp, stream: fs, remoteFilePath: remoteFilePath);
	}
}

public static void Upload(this FtpClient ftp, Stream stream, string remoteFilePath) {
	var buffer = new byte[8192];
	var offset = 0;
	var remoteStream = ftp.OpenWrite(remoteFilePath);
	try {
		while (offset < stream.Length) {
			try {
				int len;
				while ((len = stream.Read(buffer, 0, buffer.Length)) > 0) {
					remoteStream.Write(buffer, 0, len);
					offset += len;
				}
			}
			catch (IOException ex) {
				if (ex.InnerException != null) {
					var iex = ex.InnerException as System.Net.Sockets.SocketException;
					if (iex != null && iex.ErrorCode == 10054) {
						remoteStream.Close();
						remoteStream = ftp.OpenAppend(remoteFilePath);
						remoteStream.Position = offset;
					}
					else throw;
				}
				else throw;
			}
		}
	}
	finally {
		remoteStream.Close();
	}
}

OpenRead always retuns size 0

When I try to download a file using FluentFTP the OpenRead always returns a stream with size 0
What could be the cause for this ? The files are there and I can download them with filezilla or total commander so there is no security problem or anything

here is my code

            FtpClient client = new FtpClient();
            client.Host = drv["Host"].ToString();
            client.Port = (int)drv["Port"];
            client.Credentials = new NetworkCredential(drv["UserName"].ToString(), drv["PassWord"].ToString());
            client.EnableThreadSafeDataConnections = false; // the ftp server only allows one connection per username
            client.Connect();

            client.SetWorkingDirectory(remoteDir); // GetListing with a folder does not works

                using (Stream stream = client.OpenRead(remoteFile))
                {
                     SaveStreamToFile(localFile, stream);
                }

    private void SaveStreamToFile(string fileFullPath, Stream stream)
    {
        if (stream.Length == 0) 
              return; // I always get here. Why ????????

        // Create a FileStream object to write a stream to a file
        using (FileStream fileStream = System.IO.File.Create(fileFullPath, (int)stream.Length))
        {
            // Fill the bytes[] array with the stream data
            byte[] bytesInStream = new byte[stream.Length];
            stream.Read(bytesInStream, 0, (int)bytesInStream.Length);

            // Use FileStream object to write to the specified file
            fileStream.Write(bytesInStream, 0, bytesInStream.Length);
        }
    }

Invalid HTTP version when using a proxy

I am trying to fit an FTP server from behind a firewall. Initially I specified the proxy address as "http://" and port as 3128, however I was then getting an exception from System.Net "No such host" and it appeared that the proxy wasn't being used. Checking the proxy tests, I realised it was my bad and I removed the http://.

However, now I'm getting

Can't connect ftp.bom.gov.au via proxy <ip address. Message : FluentFTP.FtpReply.

Checking the squid cache.log (v2.7, running on windows) I'm seeing:

2016/12/16 10:41:14| clientTryParseRequest: FD 19 (:) Invalid Request
2016/12/16 10:51:08| parseHttpRequest: Invalid HTTP version

Any tips on how this can be resolved?

Thanks for any help you're able to provide.

Cannot install FluentFTP into a PCL project

Hi,

I'm trying to use FluentFTP in my PCL project with .net 4.5 and profile 111.

I got this error:

PM> Install-Package FluentFTP
Attempting to gather dependency information for package 'FluentFTP.16.2.1'
with respect to project 'ABCD', targeting '.NETPortable,Version=v4.5
,Profile=Profile111'
Attempting to resolve dependencies for package 'FluentFTP.16.2.1' with
DependencyBehavior 'Lowest'
Resolving actions to install package 'FluentFTP.16.2.1'
Resolved actions to install package 'FluentFTP.16.2.1'
GET https://api.nuget.org/packages/fluentftp.16.2.1.nupkg
OK https://api.nuget.org/packages/fluentftp.16.2.1.nupkg 145ms
Installing FluentFTP 16.2.1.
Adding package 'FluentFTP.16.2.1' to folder 'D:\abcd\packages'
Added package 'FluentFTP.16.2.1' to folder 'D:\abcd\packages'
Install failed. Rolling back...
Package 'FluentFTP.16.2.1' does not exist in project 'ABCD'
Removing package 'FluentFTP.16.2.1' from folder 'D:\abcd\packages'
Removed package 'FluentFTP.16.2.1' from folder 'D:\abcd\packages'
Install-Package : Failed to add reference to 'System.Web'. Please make sure
that it is in the Global Assembly Cache.
At line:1 char:1

  • Install-Package FluentFTP
  •  + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
     + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.
    

PackageManagement.PowerShellCmdlets.InstallPackageCommand

The reason it failed to add reference to 'System.Web' is because System.Web cannot be added into a PCL project.

I'm not sure if this is an issue or not, do we have a workaround?

Error 421

Hello,
I tried your DLL successfull with an external 1und1 ftp-server and an fritz.box server without problems. But when it comes to any external goneo ftp-server I always get an "to many connections error". Iยดve tested it with the DownloadFile and OpenRead methods. I tried a Thread.Sleep after any single download, an explicit passive mode, EnableThreadSafeDataConnections = false and only small files. But all in vain.

using(FTPClientManager fcm = new FTPClientManager("any goneo ftp-server", "", "")) {
    fcm.TraceListening = TraceListenerType.Default;
    //fcm.Client.SocketKeepAlive = true;
   //fcm.Client.StaleDataCheck = true;
				
   fcm.Connect();
   fcm.Client.DataConnectionType = FtpDataConnectionType.PASV;
  //fcm.SaveMode = true;
  //fcm.Client.SocketPollInterval = 0;
  if(fcm.SetWorkingDirectory(remotePath)) {
      List<FtpListItem> lst = fcm.GetFileList(remotePath);
      fcm.Disconnect();
      foreach (FtpListItem item in lst) {
           fcm.DownloadFile(l, r1, true)
          Thread.Sleep(100);
      }
     fcm.Disconnect();
}

Greets Peter

Here the traceoutput

220 goneo FTP-Server ready
USER xxx
331 Please specify the password.
PASS <omitted>
230 Login successful.
FEAT
211-Features:
 EPRT
 EPSV
 MDTM
 PASV
 REST STREAM
 SIZE
 TVFS
 UTF8
211 End
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 Always in UTF8 mode.
220 goneo FTP-Server ready
USER xxx
331 Please specify the password.
PASS <omitted>
230 Login successful.
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 Always in UTF8 mode.
PWD
257 "/" is the current directory
CWD /
250 Directory successfully changed.
TYPE I
200 Switching to Binary mode.
SIZE /htdocs/Buecher.zip
213 72123810
PASV
227 Entering Passive Mode (82,100,220,51,195,208).
RETR /htdocs/Buecher.zip
150 Opening BINARY mode data connection for /htdocs/Buecher.zip (72123810 bytes).
220 goneo FTP-Server ready
USER xxx
331 Please specify the password.
PASS <omitted>
230 Login successful.
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 Always in UTF8 mode.
PWD
257 "/" is the current directory
CWD /
250 Directory successfully changed.
TYPE I
200 Switching to Binary mode.
SIZE /htdocs/LuvLeeNV.zip
213 81693056
PASV
227 Entering Passive Mode (82,100,220,51,195,236).
RETR /htdocs/LuvLeeNV.zip
150 Opening BINARY mode data connection for /htdocs/LuvLeeNV.zip (81693056 bytes).
Disposing FtpSocketStream...
Disposing FtpClient object...
Testing connectivity using Socket.Poll()...
Testing connectivity using Socket.Poll()...
There is stale data on the socket, maybe our connection timed out. Re-connecting.
Testing connectivity using Socket.Poll()...
The data was: 226 Transfer complete.
Not sending QUIT because the connection has already been closed.
Disposing FtpSocketStream...
220 goneo FTP-Server ready
USER xxx
331 Please specify the password.
PASS <omitted>
230 Login successful.
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 Always in UTF8 mode.
PWD
257 "/" is the current directory
CWD /
250 Directory successfully changed.
TYPE I
200 Switching to Binary mode.
SIZE /htdocs/LuvLeeV2.zip
213 1242270
PASV
227 Entering Passive Mode (82,100,220,51,195,172).
RETR /htdocs/LuvLeeV2.zip
150 Opening BINARY mode data connection for /htdocs/LuvLeeV2.zip (1242270 bytes).
220 goneo FTP-Server ready
USER xxx
331 Please specify the password.
PASS <omitted>
230 Login successful.
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 Always in UTF8 mode.
PWD
257 "/" is the current directory
CWD /
250 Directory successfully changed.
TYPE I
200 Switching to Binary mode.
SIZE /htdocs/index.html
213 3735
PASV
227 Entering Passive Mode (82,100,220,51,195,153).
RETR /htdocs/index.html
150 Opening BINARY mode data connection for /htdocs/index.html (3735 bytes).
220 goneo FTP-Server ready
USER xxx
331 Please specify the password.
PASS <omitted>
230 Login successful.
Text encoding: System.Text.UTF8Encoding
OPTS UTF8 ON
200 Always in UTF8 mode.
PWD
257 "/" is the current directory
CWD /
250 Directory successfully changed.
TYPE I
200 Switching to Binary mode.
SIZE /htdocs/kammermusik.html
213 1429
PASV
227 Entering Passive Mode (82,100,220,51,197,188).
RETR /htdocs/kammermusik.html
150 Opening BINARY mode data connection for /htdocs/kammermusik.html (1429 bytes).
421 There are too many connections from your internet address.

Minimize round-trips!

Without going deeper and assessing the whole code I have noticed at least one place where the unnecessary round-trips to the server are performed.
Look at FtpClient.GetListing method and the GetListing example. In the example you suggest passing the current path by calling GetWorkingDirectory method (RT1). But when one looks in the code sees that there is a string pwd = GetWorkingDirectory(); declaration in line 1904, that is making a second round-trip (RT2) regardless of the path parameter, which is still evaluated three lines below and GetWorkingDirectory method is either called if necessary.

Implement FtpDataType in DownloadFile Method

Hello,

Would you consider implement a DownloadFile method with a "FtpDataType" as a parameter ?
Like this for example : DownloadFile(string localPath, string remotePath, FtpDataType type, bool overwrite = true);
Let me Explain : the method .OpenRead(...) is deprecated and we should use .DownloadFile(..) but, at the moment, we can't download files with 0 lenght with the method .DownloadFile(..).

Thank you for your response and your work,
Regards,

Race-condition when renaming a file after upload

I'm not sure if this is a issue in FluentFTP or the FTP-server i'm using.

I'm uploading a file to a temporary filename to rename the file after the upload is complete.
This is because the folder i'm uploading to is periodically scanned by 3rd party software for certain files, and i need to prevent the 3rd party software to read partially completed uploads.

The following code causes the server to return error "Internal error renaming the file".
I'm guessing the issue is that the client wants to rename the uploaded file before the server thinks it's complete.

// Open a stream to write on the FTP server
using (var ftpStream = ftpClient.OpenWrite("/file.tmp"))
{
    var bytes = encoding.GetBytes(fileContents);
    ftpStream.Write(bytes, 0, bytes.Length);
}

// Move file from temporary upload path to final.
ftpClient.Rename("/file.tmp", "/file.txt");

server log:

(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> STOR file.tmp
(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> 150 Opening data channel for file upload to server of "/file.tmp"
(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> SSL connection for data connection established
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> RNFR /file.tmp
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> 350 File exists, ready for destination name.
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> RNTO /file.txt
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> 450 Internal error renaming the file
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> QUIT
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> 221 Goodbye
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> disconnected.
(000141)2016-11-04 09:37:20 - ****** (a.b.c.d)> disconnected.
(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> 226 Successfully transferred "/file.tmp"
(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> QUIT
(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> 221 Goodbye
(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> disconnected.
(000142)2016-11-04 09:37:20 - ****** (a.b.c.d)> disconnected.

I can work around the problem by manually closing the control-connection for the file transfer.

...
    ftpStream.Write(bytes, 0, bytes.Length);

    // Close control-connection manually
    (ftpStream as FtpDataStream)?.Close();
...

server log:

(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> STOR file.tmp
(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> 150 Opening data channel for file upload to server of "/file.tmp"
(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> SSL connection for data connection established
(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> 226 Successfully transferred "/file.tmp"
(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> QUIT
(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> 221 Goodbye
(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> disconnected.
(000144)2016-11-04 09:47:16 - ****** (a.b.c.d)> disconnected.
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> RNFR /file.tmp
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> 350 File exists, ready for destination name.
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> RNTO /file.txt
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> 250 file renamed successfully
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> QUIT
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> 221 Goodbye
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> disconnected.
(000143)2016-11-04 09:47:16 - ****** (a.b.c.d)> disconnected.

Add high-level Copy and Move commands

Hi,

Would you consider adding Copy and Move primitives for both File and Directory? I realise these are not core FTP commands but would make great additions.

The overarching simplification being that as these are compound actions and would require a number of commands to be executed against the FTP server, if something failed half way through then the command returns FALSE and gives up.

Authentication failed because the remote party has closed the transport stream.

While downloading file from FTPS once it works but next time the exception message "Authentication failed because the remote party has closed the transport stream." appears. Please suggest me.

I'm connecting like

 private void ConnectFTPS()
        {
            try
            {
                FtpClient myFTPSClient = new FtpClient();
                myFTPSClient.Host = ftpHost; 
                myFTPSClient.Port = ftpPort;
                myFTPSClient.Credentials = new NetworkCredential(ftpUser, ftpPwd); 
                myFTPSClient.EncryptionMode = FtpEncryptionMode.Explicit;
                X509Certificate2 cert_grt = new X509Certificate2(@"ABC.pfx", "123456");
                myFTPSClient.ClientCertificates.Add(cert_grt);
                myFTPSClient.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
                myFTPSClient.Connect();
                 }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Global.AppName + ": FTP Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                OpenSettingsWindows();
            }
        }

        static void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e)
        {
            e.Accept = true;
           
        }

And the detail error message is:

Authentication failed because the remote party has closed the transport stream.
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   at FluentFTP.FtpSocketStream.ActivateEncryption(String targethost, X509CertificateCollection clientCerts, SslProtocols sslProtocols)
   at FluentFTP.FtpClient.OpenPassiveDataStream(FtpDataConnectionType type, String command, Int64 restart)
   at FluentFTP.FtpClient.OpenDataStream(String command, Int64 restart)
   at FluentFTP.FtpClient.GetListing(String path, FtpListOption options)
   at FluentFTP.FtpClient.GetListing(String path)

Thank you

FTPS client not working on vsftpd

Hello,

I've created an FTPS server on ubuntu by following this tutorial.

I've tested it on Filezilla by using explicit encryption. Everything works fine.

But when I test it with FluentFTP by using explicit encryption, I get the following error when the client is trying to connect to the remote FTPS server:

Unable to read data from the transport connection : An existing connection was forcibly closed by the remote host

Can you please help me to solve this issue?

Kind regards,

Method UploadFiles is throwing Expcetion "bad login"

Hi,
i think i found an issue. When i connect to FTP server via Total Commander, then when i connect to FTP via your FtpClient class at the same time, then when i use method UploadFile on instance of FtpClient then method is throwing Exception with InnerException "bad login". This behavior stops when i disconnect from FTP in Total Commander.

X509 certificates for SFTP

Is there a way to bundle an X509 certificate (from a file) or do I have to register it in the X509Store, and if so, which one?

Modified datetime is incorrectly parsed

Hi!

Trying to figure out the modification time of the file in the directory.
The modification time of the directory shows correctly (debug values):

Created = {01.01.0001 0:00:00}
FullName = "/73/6878398845"
Input = "drwxrwxr-x 2 ftp ftp 4096 Nov 24 12:30 6878398845"
Modified = {24.11.2016 12:30:00}

....
Next, try to know the modification time of the file in this directory (debug values):

Created = {01.01.0001 0:00:00}
Input = "-rw-rw-r-- 1 ftp ftp 392872 Nov 24 12:30 AKT VYPOLNENNYH RABOT(1).PDF"
Modified = {24.11.2016 16:30:33}

Why is not the same as the Modified time and Input params (12:30 -is real local time, 16:30 - converted to UTC. I have to convert back ) ?
At the same time, the directory everything is fine.

var items = ftp.GetListing(ftpUri.Uri.LocalPath, FtpListOption.ForceList | FtpListOption.Modify);
                foreach(var item in items)
                {
                    if (item.Type != FtpFileSystemObjectType.Directory)
                        continue;

                    var files = ftp.GetListing(item.FullName, FtpListOption.ForceList | FtpListOption.Modify);
               }

UploadFile stuck in while-loop

When using UploadFile (stream, "path"); to a filename that already exists and the uploaded file is smaller than the existing one. Then UploadFileInternal gets stuck in the empty while-loop, since upStream.Length is bigger than upStream.Position.

Transferring large files should stream straight to disk

Currently the data is accumulated in memory before writing from disk. This can be an issue with large files (>100 MB) as it will consume the same amount of memory unnecessarily. Thus the FileStream API should be used to read/write large files.

Changes required in:

  • DownloadFile() and UploadFile()

Timed out trying to read data from the socket stream!

Why this error happen on my virtual machine, but on my local it work good

Timed out trying to read data from the socket stream!

 ftpClient = new FtpClient
 {
                Host = settings.Host,
                Credentials = new NetworkCredential(settings.Login, settings.Password),
                EnableThreadSafeDataConnections = false,
                ReadTimeout = 30000,
                DataConnectionReadTimeout = 30000,
                DataConnectionType = FtpDataConnectionType.AutoActive     
 };

problem on windows server 2012 client

on windows 7 work good

Is there a Nuget release?

Hi,
is FluentFTP available on Nuget?

Looking the code it seems you have the scripts to create the nuget packaged, but I can't find it.

Thanks
.u

OpenWrite - too many connections

Hi,

if I upload multiple streams I get the error that the server can't accept more then 8 connections from the same username. I have some logic (see code) which checks if the stream is uploaded completly but I think the ftpClient doesn't close the connection. How I can close the connection/stream for OpenWrite?

_ftpClient.Connect();

        long origLength = stream.Length;

        using (var ftpStream = _ftpClient.OpenWrite(filePath, isBinary ? FtpDataType.Binary : FtpDataType.ASCII))
        {
            try
            {
                stream.CopyTo(ftpStream);
                Thread.Sleep(1000);

                //byte[] buf = new byte[8192];
                //int read = 0;

                //while ((read = stream.Read(buf, 0, buf.Length)) > 0)
                //{
                //    ftpStream.Write(buf, 0, read);
                //}
            }
            finally
            {
                ftpStream.Close();
                stream.Close();
            }

            long fileSizeOnFtp = _ftpClient.GetFileSize(filePath);
            while (fileSizeOnFtp < origLength)
            {
                if (fileSizeOnFtp > -1)
                {
                    fileSizeOnFtp = _ftpClient.GetFileSize(filePath);
                    Thread.Sleep(2000);
                }
                else
                {
                    Thread.Sleep(3000);
                }
            }

GetListing with spaces in path

GetListing("/usr/local/plexdata/Plex Media Server") returns nothing...
GetListing("/usr/local/plexdata") returns correct data

i have manually ftped to server and verified i can see the underlying directories and files
server is a freebsd box

How to use certificates for FTPS connections in C# .?

Hi HGupta,

I am using your library for making connections with FTP sites. now i am facing some problems with FTPS sites(Sites with SSL enabled). I have set my FTPS site with IIS and i am using the code in below.

FtpClient conn = new FtpClient();
conn.Host = firewallSslDetails.Address;
conn.Credentials = new NetworkCredential(firewallSslDetails.UserName, firewallSslDetails.Password);
conn.SslProtocols = System.Security.Authentication.SslProtocols.Default;

X509Certificate2 cert = new X509Certificate2(@"C:\Users\BizTalk360\Desktop\FtpSites\ServerCert.cer");
 conn.EncryptionMode = FtpEncryptionMode.Explicit;
 conn.DataConnectionType = FtpDataConnectionType.AutoActive;
 conn.DataConnectionEncryption = true;
 conn.EnableThreadSafeDataConnections = false;
 conn.ClientCertificates.Add(cert);
 conn.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
 
 conn.Connect();
 conn.ConnectTimeout = 60000;
 Console.WriteLine("Connection Established");
 if (conn.DirectoryExists("/" + firewallSslDetails.Folder))
 {
     Console.WriteLine("Directory Exists..!");
     conn.SetWorkingDirectory("/" + firewallSslDetails.Folder);
     FtpListItem[] items = conn.GetListing();
     Console.WriteLine(items.Length);
 }
 else
 {
     Console.WriteLine("Directory does not exist");
 }

I am new to programming and i can't figure out how to verify and connect to the server.

Thanks.

Proxy implementation problems

We've found a number of problems with the proxy implementations:

  1. USER@HOST sends the FTP credentials every time instead of the proxy credentials.
  2. HTTP 1.1 proxy only connects the base stream correctly. Each stream thereafter is direct to the FTP host, not via the proxy.

I've attached a patch file that addresses these issues. This has been tested on an HTTP 1.1 proxy, but not a USER@HOST proxy.
fluentftp.txt

Access is Denied when do upload with Explicit SSL

I have problem when to upload file from local to ftp server.
Below is my code to upload the files to the ftp server and an error shows 'Access is Denied'. Anybody have solutions? Thanks in advance.

capture

OpenRead and OpenWrite deprecated?

OpenRead and OpenWrite are the only two ways to open stream to the file and return it (except async versions, which, I assume, going to be deprecated also). DownloadFile and UploadFile works fine in simple cases. However, when creating bigger API, returning Stream is the way to go.
In my case, I have FileSystem, File and Directory abstracion and in all cases (local file, network share, SFTP, Dokan) returning Stream works fine. It's simple and efficient. With FluentFTP and the new DownloadFile and UploadFile API the only way to implement this is to create MemoryStream, which is impossible for big files.

Is there an important reason to obsolete OpenRead and OpenWrite or not to create versions of DownloadFile and UploadFile where Stream is returned?

Multiple upload error

Unusual problem,when i upload many files in one thread. Sometimes i have error in uploading (example Failed to get the EPSV port from: 6351, or unknown command)

but i try it again it work fine

i have a bad issue now, - if error thread.sleep(10 seconds)

 ftpClient = new FtpClient
            {
                Host = ftpClientSettings.Host,
                Credentials = new NetworkCredential(ftpClientSettings.Login, ftpClientSettings.Password),
                EnableThreadSafeDataConnections = false,
               
            };

i use the win service, that each 2 hours upload files to different servers

File truncated when uploading through proxy

I am attempting to upload a file to an external FTP server (i.e. a third party server that I don't control). When I do this on my dev machine it is not going through a proxy. However from our other environments it goes through a HTTP1.1 proxy.

I have found that when the file is uploaded through the proxy, the file is always truncated slightly. The file being uploaded is a CSV with header, and the header includes a count of total rows of data (not including header), and each row in the file includes an index field - therefore it's v easy to see that the file is truncated. The files are ~15-16MB in size. Some of the files that are being truncated indicate that there are 206,818 records in the file, however the last line of data is record 206,223 - and the line is half truncated.

Are there any known issues with file truncation through a proxy? Is there anything else I should be doing here? I'm transmitting using ASCII format, as that's what the third party specifies. I'll test using Binary, but will have to see if this will cause issues at the other end. any tips appreciated.

Multiple file uploads keep re-opening connection

Hi there,

I am trying to upload multiple files synchronously using the same FTP connection (using FluentFTP 16.1.0). I would expect to see only one connection being used on the FTP server for the whole operation, but I can see that the connection is closed and reopened after every file upload. I've replicated the problem with the following test program (using FileZilla as my FTP server):

class Program
{
	static void Main(string[] args)
	{
		FtpTrace.AddListener(new ConsoleTraceListener());

		using (FtpClient client = new FtpClient())
		{
			client.Host = "127.0.0.1";
			client.Port = 21;
			client.Credentials = new NetworkCredential("anonymous", string.Empty);
			client.EnableThreadSafeDataConnections = false;
			client.Connect();

			foreach (string file in Directory.GetFiles(@"C:\Temp"))
			{
				client.UploadFile(file, "./" + Path.GetFileName(file), true);
			}

			client.Disconnect();
		}
	}
}

In the console, I can see the following trace output (for every file):

...
STOR ./File1.txt
150 Opening data channel for file upload to server of "/File1.txt"
TYPE I
200 Type set to I
There is stale data on the socket, maybe our connection timed out. Re-connecting.
The data was: 226 Successfully transferred "/File1.txt"
...

I can see that it is closing the connection because of the StaleDataCheck failing. I can set this flag to false, but I'm not sure what other consequences this will have on our code (we use a generic client for upload, download, etc.). If you need any other information from my side, please let me know.

SFTP support?

As far as I can tell it isn't support, but issue #4 suggests that there is SFTP support?

Either way the readme should probably mention it (either that it's supported or not supported) just to clear things up

DownloadFile with restart option?

Hi there,

The OpenRead method is now obsolete and DownloadFile is recommended instead. But what about OpenRead(string path, FtpDataType type, long restart)? There is no way to use DownloadFile with restart option. The workaround is to use the static OpenRead method but that is only a workaround. Any other options / plans?

GetListing doesn't return the current directory and the parent directory (. and ..)

Hi,

GetListing() and GetListing("", FtpListOption.AllFiles) don't return the current directory and the parent directory.

However, the LIST COMMAND returns those 2 files.

TELNET 127.0.0.1 21

220 Hello, I'm freeFTPd 1.0
USER test
331 Password required for test
PASS Bonjour123
230 User test logged in
PASV
227 Entering passive mode (127,0,0,1,226,7)
LIST
150 Opening ASCII mode data connection
226 Directory send OK

TELNET 127.0.0.1 57863

drwxr-xr-x 1 root root 0 Jan 30 12:17 .
drwxr-xr-x 1 root root 0 Jan 30 12:17 ..
-rw-r--r-- 1 root root 8 Jan 30 12:17 Bonjour.txt
drwxr-xr-x 1 root root 0 Dec 22 2016 final_gabarit2015B
drwxr-xr-x 1 root root 0 Dec 22 2016 tmp2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.