arxone / ftp Goto Github PK
View Code? Open in Web Editor NEWSimple FTP client
License: MIT License
Simple FTP client
License: MIT License
I'm trying to open a path on a FileZilla server that has spaces in it, but keep getting 550 error.
Example ftpClient.ListEntries("/Test Folder") will be handled as "/Test\ Folder" on the server.
Is ArxOne.FTP changing the space character to "\ " or is FileZilla server doing that?
Thanks.
In the first line, it's not NetworkCredentials... the correct is NetworkCredential
Hello -
I am experiencing an issue when trying to connect to a client via the FtpProtocol.FtpES protocol.
I believe it has something to do with the SSL certificate signing.
Can you point me in the right direction to try and fix this?
I will be happy to commit my fix, once its completed.
Exception Message:
A call to SSPI failed, see inner exception.
Here is the stack trace:
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception) 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 ArxOne.Ftp.FtpSession.UpgradeToSsl(Stream stream) at ArxOne.Ftp.FtpSession.EnterSslProtocol() at ArxOne.Ftp.FtpSession.InitializeProtocol() at ArxOne.Ftp.FtpSession.ProcessConnect(TimeSpan connectTimeout, TimeSpan readWriteTimeout) at ArxOne.Ftp.FtpSession.<>c__DisplayClass15_0.b__0() at ArxOne.Ftp.FtpSession.Process[TResult](Func1 func, String commandDescription, String requestCommand, String[] requestParameters) at ArxOne.Ftp.FtpSession.Connect(TimeSpan connectTimeout, TimeSpan readWriteTimeout) at ArxOne.Ftp.FtpSession.get_ProtocolStream() at ArxOne.Ftp.FtpClient.<>c__DisplayClass123_0.b__0(FtpSession session) at ArxOne.Ftp.FtpClient.Process[TResult](Func
2 action, FtpSession session) at ArxOne.Ftp.FtpClient.SendSingleCommand(String command, String[] parameters).
Hi,
I've find out that the format used to parse the Modify field of Mlsd is wrong. It doesn't parse dates with hours greater than 12.
The current formats are: "yyyyMMddhhmmss", "yyyyMMddhhmmss.fff"
They should be: "yyyyMMddHHmmss", "yyyyMMddHHmmss.fff" to correctly handle 00-23
Hello,
I'm trying to connect to an ftp server using ftpes. I checked with filezilla and the server does require explicit TLS ftp. When connecting I get an CheckCertificate and the valid property equals true. After that any command returns 501 ('Server cannot accept argument.'). Is there an easy way to see which command is causing this? At this moment I only have stack trace which is not very informative. It happens as soon as I hit HasFeature in code below.
The ftp server is the built in microft ftp server and output from FEAT is
Response: 211-Extended features supported:
Response: LANG EN*
Response: UTF8
Response: AUTH TLS;TLS-C;SSL;TLS-P;
Response: PBSZ
Response: PROT C;P;
Response: CCC
Response: HOST
Response: SIZE
Response: MDTM
Response: REST STREAM
Response: 211 END
Stacktrace:
at ArxOne.Ftp.FtpSession.ThrowException(FtpReply reply)
at ArxOne.Ftp.FtpSession.Expect(FtpReply reply, Int32[] codes)
at ArxOne.Ftp.FtpSession.OpenActiveDataStream(TimeSpan connectTimeout, TimeSpan readWriteTimeout)
at ArxOne.Ftp.FtpSession.OpenDataStream(Boolean passive, TimeSpan connectTimeout, TimeSpan readWriteTimeout, FtpTransferMode transferMode, Nullable1 streamMode) at ArxOne.Ftp.FtpClientUtility.OpenDataStream(FtpSession session, FtpTransferMode transferMode, FtpStreamMode streamMode) at ArxOne.Ftp.FtpClientUtility.ProcessList(FtpSession session, FtpPath path) at ArxOne.Ftp.FtpClient.Process[TResult](Func
2 action, FtpSession session)
at ArxOne.Ftp.FtpClientUtility.ListEntries(FtpClient ftpClient, FtpPath path)
at NugetHelper.Program.Main(String[] args) in \Program.cs:line 36
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
using (var ftpClient = new FtpClient(new Uri("ftpes://ftp.*****"), new NetworkCredential("****", "******"), new FtpClientParameters() { Passive = false, })) { ftpClient.CheckCertificate += FtpClient_CheckCertificate; if (ftpClient.ServerFeatures.HasFeature("MLSD")) { var temp = ftpClient.MlsdEntries("/"); //.Mlsd(new FtpPath("/")); } }
Hi,
i try to use your FTP Library, but i don't get it managed to Download a File. Maybe you can provide me a simple Example or you may have a tip whats wrong with my Code?
Here is my Code
Dim _settings As New Settings
Dim _download_path As String
'IO Stream Variablen
Const Length As Integer = 256
Dim buffer As [Byte]()
Dim bytesRead As Integer = 0
Dim bytestotalread As Integer = 0
Dim _starttime As DateTime = DateTime.Now
Dim _percent_downloaded As Integer = 0
Dim _current As Long = 0
Dim _ctime As TimeSpan
Dim elapsed As TimeSpan
Dim bytesPerSec As Integer = 0
_settings = Application.Current.Resources("Settings")
Try
_download_path = IO.Path.Combine(_settings.DownloadDirectory, _item.FileName) 'ToDo: Einstellungen beachten (Subfolder etc)
'ToDO: Check Download Path is exceeding 255 Chars
'ToDO: Check FRee Disk Space
Using _ftp_read_stream As ArxOne.Ftp.IO.FtpStream = ArxOne.Ftp.FtpClientUtility.Retr(_ftp_client, New ArxOne.Ftp.FtpPath(_item.FullPath), ArxOne.Ftp.FtpTransferMode.Binary)
'ToDO: Set Filemode to append or create
buffer = New Byte(8192) {}
bytesRead = _ftp_read_stream.Read(buffer, 0, buffer.Length)
Using _local_write_stream As New IO.FileStream(_download_path, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None, 8192, False)
While bytesRead > 0 'ToDo: CHeck if Download is stopped
Dim _tmp_percent_downloaded As Double = 0
Dim _new_perc As Integer = 0
Dim _download_speed As String = String.Empty
' If _ftp_read_stream.Length > 0 Then
_local_write_stream.Write(buffer, 0, bytesRead)
bytesRead = _ftp_read_stream.Read(buffer, 0, Length)
bytestotalread += bytesRead
elapsed = DateTime.Now.Subtract(_starttime)
_tmp_percent_downloaded = CDbl(_local_write_stream.Position) / CDbl(_ftp_read_stream.Length)
_new_perc = CInt(_tmp_percent_downloaded * 100)
bytesPerSec = CInt(If(elapsed.TotalSeconds < 1, bytestotalread, bytestotalread / elapsed.TotalSeconds))
' End If
If _new_perc <> _percent_downloaded Then 'Nicht jedesmal Updaten
Dim _tmp_speed As Double
_percent_downloaded = _new_perc
_current = _ftp_read_stream.Position
_ctime = DateTime.Now.Subtract(_starttime)
_tmp_speed = Math.Round(bytesPerSec / 1024, 2)
If _tmp_speed >= 1024 Then
_download_speed = Math.Round(_tmp_speed / 1024, 2) & " MB/s"
Else
_download_speed = _tmp_speed & " KB/s"
End If
'_ftp_thread_info.FileItem.SizeDownloaded = _local_write_stream.Position
_item.DownloadSpeed = _download_speed
_item.DownloadProgress = _percent_downloaded
' UpdateItemProgress(_ftp_thread_info.FileItem, _ftp_thread_info.SFDLSession.SFDLSessionName, _download_speed, _percent_downloaded)
End If
'ThrottleByteTransfer(_max_bytes_per_second, bytestotalread, _ctime, bytesPerSec)
End While
End Using
End Using
Catch ex As Exception
End Try
Thanks in andvance.
The latest version is 1.41.2, however the version before was 1.14.1. Is it a typo?
Hi!
Could you give me an example for using proxies in your framework. I found a Delegte ConectProxy wich can be set in FtpClientParameter Class. In a Class I would like to use the FtpClient, both proxy and ftp data are known. But i don't realy understand how can I produce a SocketObject from given EndPoint.
Thanks a lot!
Currently, it's not.
Hello there,
I'm "toying" with a tiny utility to parse Cobol "layouts" (copy files) and while looking for an alternative to FtpWebRequest I found your nice ftp client.
However, just like most FTP clients, it adds a slash to paths to make them absolute. Which is fine on z/Os too, unless one is trying to access "traditional" mainframe files, in which case it's a bane! (and obviously this is my case....!)
I made a few tiny modifications to FtpPath (and since I was there, I also added an MVS platform) - would you be interested in adding them to your code? Should I make a pull request?? (I'm sorry, I'm a noob in this field - my main business is on mainframes.... )
Hello, i'm having trouble with a FTPS server with TLS certificate.
I traced the code and it always fails when it try to set the TransferMode in SetTransferMode method, you send a command with "TYPE", but I always get this reply:
{"IO Exception while connecting to FTP server"}
futhermore, you always _transferMode as the value that you get from method
private void SetTransferMode(FtpTransferMode value)
{
if (value != _transferMode)
{
Expect(SendCommand("TYPE", value.ToString()), 200);
_transferMode = value;
}
}
Is that correct?
[TestMethod]
[TestCategory("Ftp")]
[TestCategory("RequireHost")]
public void FtpListNoDirectory()
{
var ftpTestHost = GetTestHost("ftp");
using (var ftpClient = new FtpClient(ftpTestHost.Uri, ftpTestHost.Credential))
{
var list = ftpClient.ListEntries("/DirectoryNotFound/");
}
}
After replied 550, the server would not give the second one, then FtpStream.Release(true) will be blocking.
protected void Release(bool expectEndReply)
{
var session = Session;
Session = null;
if (session != null)
{
try
{
if (expectEndReply)
{
Process(() => session.Expect(
226, // default ack
150 // if the stream was opened but nothing was sent, then we still shall exit gracefully
));
}
}
// on long transfers, the command socket may be closed
// however we need to signal it to client
finally
{
session.Release();
}
}
}
My FTP server refuses active data channel because IP address differs (and shouldn't)
It would be nice if the library targets .NET Standard. I use it in .NET Core for Linux and want to be on the safe side 😄
Any plans for it?
Hi, when i try to retrive an .odt file, the getBinaryReader() return null, in same location of the .odt file, i've got an .doc file, and when i retrive the doc it's work.
Why with .odt does not work?
Specifications here: http://tools.ietf.org/html/draft-ietf-ftpext-mlst-16#section-7
If you set ChannelProtection
to contain FtpProtection.DataChannel
the library never explicitly informs the server of this.
Some servers do not by default use SSL on the data channel even if it is being used on the command channel.
This can result in the server sending unencrypted data which is picked up by System.Net.Security.SslStream.AuthenticateAsClient
and causes the exception seen above as the data is not a valid SSL handshake.
FtpSession.CheckProtection
should, if State["PROT"]
does not equal the desired protection level, issue a PROT
command and fail on a non 2xx response code. State["PROT"]
should not initially be set on a new connection.
I'm currently using the below as a temporary fix:
if (client.SendSingleCommand("PROT", "P").Code.Code != 200)
throw new Exception("Could not enable data channel encryption.");
It appears the library also doesn't issue a PBSZ
command which is apparently required by https://tools.ietf.org/html/rfc2228.
Other libraries seem to use PBSZ 0
successfully.
Unrelated to #32, as it turns out.
Move from Stream
to Socket
(and EndPoint
)
When I attempt to connect to azure and use List the library waits returning nothing. The end result is the host closes the connection. Is this a bug or am I missing a setup step to use secure connections?
using (var client = new FtpClient(new Uri(_address), new NetworkCredential(_userName, _password), new FtpClientParameters {SslProtocols = SslProtocols.Tls}))
{
var pro = client.Protocol;
return client.List(new FtpPath(BaseDirectory));
}
Hello,
I'm having a problem where I have to download several files from an external ftp server (of which I have little knowledge or control). Using filezilla everything works using the same settings.
But when I use this library and the code below, I can only download the first three files and then it stops with authentication errors. After that filezilla also won't work, but it gives an more specific error. Something like "maximum number of logins reached". I contacted the server owner and they increased the max connection limit. But that only helps so far.
What I really want to know is why filezilla is not having a problem (when starting with no outstanding sessions) and this library does (for the same number of files, both passive connections). Other projects I used it on work fine, so I guess it's something to do with the specific server I am connecting to.
Is there something in the code below that I can change to better "close" the connection or something after a download? Maybe I'm just missing something. Any help appreciated.
`using (var ftpClient = new FtpClient(new Uri("ftps://123.123.123.123"), credential, new FtpClientParameters()
{
ConnectTimeout = new TimeSpan(0, 0, 10),
Passive = true
}))
{
if (ftpClient.ServerFeatures.HasFeature("MLSD"))
{
entries = ftpClient.MlsdEntries(myPath);
}
else
{
entries = ftpClient.ListEntries(myPath);
}
foreach (FtpEntry entry in entries)
{
ftpClient.Retr(entry.Path, FtpTransferMode.Binary);
}
}`
The errors that appear as as follows (first few lines are normal output, but then errors appear once the message was sent by the server):
......
16
16
16
16
16
16
Expected other reply than 214 ('test2')
Expected other reply than 214 ('test2')
File error. Code=150 ('Opening ASCII mode data connection for /bin/ls (998 bytes).')
File error. Code=150 ('Opening ASCII mode data connection for /bin/ls (998 bytes).')
Connection error. Code=226 ('Transfer complete (20.792 KB/s).')
Connection error. Code=226 ('Transfer complete (21.234 KB/s).')
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
Socket error to localhost
.....
I need to be able to determine if a file exists and if it does delete it so i can then rename the uploaded file (which was uploaded with a temporary filename).
I would suggest using MLST if its supported for speed as the folder i have to upload to has 30k files in it and is therefore very slow.
I suppose I could just 'delete' the file and ignore the response?
Hello,
I was trying out the library and noted the following:
When connecting to speedtest.tele2.net I could do a listing no problems. However this server does not support mlsd. So I tried ftp.cs.brown.edu. I verified connection and mlsd support using filezilla. But when I connect using this library I get a ftpprotocolexception: "Expected other reply than 230 ('Anonymous user logged in')" on normal and mlsd listing.
This problem might just be related to brown.edu ftp software and I am just using it as a test server. But I thought to write this down here, as it might affect others to and could be as simple fix.
My test code
using (var ftpClient = new FtpClient(new Uri("ftp://speedtest.tele2.net"), null, new FtpClientParameters()
//using (var ftpClient = new FtpClient(new Uri("ftp://ftp.cs.brown.edu"), null, new FtpClientParameters()
{
Passive = false,
}))
{
var temp = ftpClient.ListEntries(""); //.MlsdEntries(""); //.Mlsd(new FtpPath("/"));
}
It's missing a ) in the first line and it's not session is ftpSession on the second using.
Don't worry i'm testing your library 👍
Tests should be a matrix with parameters:
TestCategoryAttribute
)The quoting of spaces seems incosistent: on MKD spaces are not quoted but on STAT they're quoted
on out server, this command return ok
"MKD /ConadSicilia/3P/PV1595 - ITA"
so the directory is created without problem; but checking if directory exists, using GetEntry, returns an error.
I found that is because STAT is called with quoted spaces:
"STAT /ConadSicilia/3P/PV1595\\ -\\ ITA"
In my case, FtpPlatform GetFtpPlatform(FtpServerType serverType, string system)
is called with serverType Unix, and system "UNIX Type: L8" so the UnixFtpPlatform.EscapePath is then called.
That function indicates that space has to be quoted; I found that the decision to quote space has been changed back and forth in April 2016 (0cb32a8 and 48563cb)
Just for my server I edited to exclude space from quoting and it solved the issue but I found no definitive information about which behavior is correct or if is it implementation dependent, so I'm reluctant to submit a PR to remove space character from quoting.
Failing since Feb 28, 2021
Uploading artifacts...
[1/2] ArxOne.Ftp.1.41.4.nupkg (81,182 bytes)...100%
[2/2] ArxOne.Ftp.1.41.4.symbols.nupkg (100,347 bytes)...100%
Deploying using NuGet provider
Publishing ArxOne.Ftp.1.41.4.nupkg to https://www.nuget.org/api/v2/package...
Error publishing package. NuGet server returned 403: The specified API key is invalid, has expired, or does not have permission to access the specified package.
Sorry i got it working - My Fault :-)
Pls Delete
In ProcessGetEntry there is a status code check which doesn't seem to align with my FTP server...
private static FtpEntry ProcessGetEntry(FtpSession session, FtpPath path) { session.CheckProtection(FtpProtection.ControlChannel); var reply = session.SendCommand("STAT", session.Connection.Client.GetPlatform(session).EscapePath(path.ToString())); if (reply.Code != 213 || reply.Lines.Length <= 2) return null; // now get the type: the first entry is "." for folders or file itself for files/links var entry = EnumerateEntries(session.Connection.Client, path, reply.Lines.Skip(1), ignoreSpecialEntries: false).First(); // actually, it's always good here return new FtpEntry(path, entry.Size, entry.Type, entry.Date, entry.Target); }
My FTP server seems to return status code 211 instead of 213 as the code expects. Everything else in the response is fine, I get full details of the remote file I queried.
I run the unit tests in TestCategory with IIS Ftp Server, all passed except FileExistsTest,
because there is no key word "FtpEntryType.Link" in WindowsFtpPlatform.ParseLine method.
In fact, the response lines by STAT command have no symlink identifier.
By vsftpd in linux, FileExistsTest passed if symlink to file, but failed to directory,
because the response line by FtpClient.GetEntry for a folder is always start with 'd', even if the foder is symlink.
So the last Assert statement in FileExistsTest failed.
Currently, active transfer is not supported.
If someone care, just add a comment here 😄
(I don't see any way to ask a question, so I am putting this into an issue, but it's really a request for info.)
What is the advantage for using a session? The documentation on the main page shows me how to make a session, but does not explain what is useful about it.
In case you are curious how I am using your library, please see https://github.com/ontytoom/AntonFtpClient
Without escaping, ParenthesisNameTest, BracketsNameTest and SpaceNameTest also work well.
And that if escaping, these tests will fail by Fillzilla on Windows and vsftpd in LIST command,
and when exception throw, the test code will be blocking by filezilla but vsftpd won't.
Besides, above three tests also fail since Fillzilla Server on Windows unsupported STAT command.
Juste in case someone would care.
Hi,
I am using Cerberus FTP server on Azure VM. When I user Filezilla client to connect to server over FTPS its working fine.
When I use the below code it is throwing the error mentioned in the subject line
using (var ftpClient = new FtpClient(FtpProtocol.FtpS,"xx.xx.xxx.xx",990, new NetworkCredential("tenantuser1","tenantuser1")))
{
IEnumerable files = ftpClient.ListEntries("/");
}
Here is the stack trace
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
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 ArxOne.Ftp.FtpSession.UpgradeToSsl(Stream stream)
at ArxOne.Ftp.FtpSession.CreateDataStream(Socket socket)
at ArxOne.Ftp.IO.FtpPassiveStream.SetSocket(Socket socket)
at ArxOne.Ftp.IO.FtpPassiveStream..ctor(Socket socket, FtpSession session)
at ArxOne.Ftp.FtpSession.OpenDirectPassiveDataStream(String host, Int32 port, TimeSpan connectTimeout, TimeSpan readWriteTimeout)
at ArxOne.Ftp.FtpSession.OpenPassiveDataStream(TimeSpan connectTimeout, TimeSpan readWriteTimeout)
at ArxOne.Ftp.FtpSession.OpenDataStream(Boolean passive, TimeSpan connectTimeout, TimeSpan readWriteTimeout, FtpTransferMode mode)
at ArxOne.Ftp.FtpClientUtility.OpenDataStream(FtpSession session, FtpTransferMode mode)
at ArxOne.Ftp.FtpClientUtility.ProcessList(FtpSession session, FtpPath path)
at ArxOne.Ftp.FtpClientUtility.<>c__DisplayClass1_0.b__0(FtpSession handle)
at ArxOne.Ftp.FtpClient.Process[TResult](Func`2 action, FtpSession session)
at ArxOne.Ftp.FtpClientUtility.List(FtpClient ftpClient, FtpPath path)
at ArxOne.Ftp.FtpClientUtility.ListEntries(FtpClient ftpClient, FtpPath path)
at FTPTestAppConsole.Program.DownloadDirectory(FtpClient client, String source, String destination) in c:\Users\kkanikanti\Documents\Visual Studio 2013\Projects\FTPTestApp\FTPTestAppConsole\Program.cs:line 29
at FTPTestAppConsole.Program.Main(String[] args) in c:\Users\kkanikanti\Documents\Visual Studio 2013\Projects\FTPTestApp\FTPTestAppConsole\Program.cs:line 23
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Let me know if I have to specify any certificate for FTPS.
Thanks,
Krishna Priya
Hi, I have a server which I can connect to from FileZilla using "Require explicit FTP over TLS" mode only. The following code fails...
var ftpClient = new FtpClient(FtpProtocol.FtpES, ftpHost, 21, new NetworkCredential(ftpUser, ftpPassword), new FtpClientParameters { SslProtocols = System.Security.Authentication.SslProtocols.Tls }); var list = ftpClient.ListEntries("/");
Is there anything more with needs to be done to make the client work around certificates or something?
The error is...
IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Picrap,
I noticed the command for GetEntry is using the "STAT" command.
I am unable to use GetEntry with FileZilla because it does not know what the STAT command is.
Also, if I use LIST on a directory that does not exist, it throws an error.
Basically I'm trying to check if a directory exists before renaming a file/folder to that directory.
Any other options than GetEntry or LIST?
Thanks,
Darrell
We have a (filezilla) server that emulates unix - directory names would not need to be escaped in this case (though it is marked as unix emulated). In the current form the code is very nicely encapsulated - but it is very hard to extend.
Maybe you could change the methods to virtual ones and private ones to protected. And/or include some strategy pattern to handle unix/windows specific logic (which could then be overridden or implemented as a new strategy for custom servers).
I'm getting the next error: ArxOne.Ftp.Exceptions.FtpFileException: File error. Code=550
But only trying to upload the file Views/ABM/Usuarios.cshtml
Please, See my log:
"Subiendo" = "Uploading"
Subiendo...
Subiendo C:\Jenkins.jenkins\jobs\HalleyV3 - Trunk\workspace\HalleyV3.WebSite\Views\Web.config...
OK
Carpeta: Views
Path: Views//Web.config
Subiendo C:\Jenkins.jenkins\jobs\HalleyV3 - Trunk\workspace\HalleyV3.WebSite\Views_ViewStart.cshtml...
OK
Carpeta: Views
Path: Views//_ViewStart.cshtml
Subiendo C:\Jenkins.jenkins\jobs\HalleyV3 - Trunk\workspace\HalleyV3.WebSite\Views\ABM\Usuarios.cshtml...
OK
Carpeta: Views
Path: Views//ABM/Usuarios.cshtml
ArxOne.Ftp.Exceptions.FtpFileException: File error. Code=550 ('Filename invalid')
en ArxOne.Ftp.FtpSession.ThrowException(FtpReply reply)
en ArxOne.Ftp.FtpClientUtility.ProcessStor(FtpSession session, FtpPath path, FtpTransferMode mode)
en ArxOne.Ftp.FtpClientUtility.<>c__DisplayClass9_0.b__0(FtpSession handle)
en ArxOne.Ftp.FtpClient.Process[TResult](Func2 action, FtpSession session) en ArxOne.Ftp.FtpClientUtility.Stor(FtpClient ftpClient, FtpPath path, FtpTransferMode mode) en HalleyVersionPublisher.Publicador.CargarGenerico(String carpetaFtp, String directorio, Boolean recursive, String filtro, String filtroRegex, Boolean eliminarViejos, IEnumerable
1 extensionesValidas) en c:\Jenkins.jenkins\jobs\Halley V2\workspace\HVP\Publicador.cs:l¡nea 286
en HVP.Parametros.Procesar(String[] args) en c:\Jenkins.jenkins\jobs\Halley V2\workspace\HVP\Parametros.cs:l¡nea 109
i unable to figure out why am not able to open this style of folder name or any folder with space in it
/\Fun/Films/Bla Bla Vol. 1 et 2 (2003-2004) MULTi-Work [WORK] XCOM-FunFor
Server is unix
Hello!
Thank you for this FTP library. It seems well written and easy to use.
I have a c# program that occasionally retrieves a number of small files from another device using ftp. The program works, but an exception is thrown every time and does not get caught in my try catch block.
"Exception thrown: 'System.Threading.ThreadInterruptedException' in mscorlib.dll"
The exception does not cause the program to crash but i wonder why it is happening. Perhaps you can help?
Here is my code:
private bool FTPGetLogfilesFromPLC()
{
// Initiate ftp variables and file paths
Uri plcFtpUri = new Uri("ftp://" + PLC_IPAddress);
NetworkCredential plcFtpCred = new NetworkCredential("user", "pass");
FtpPath plcLogPath = new FtpPath("MEMCARD1");
// Get the list of .csv files already present in the PC harddrive
FileInfo[] localFiles = new DirectoryInfo(LocalLogPath).GetFiles("*.csv");
FtpClientParameters par = new FtpClientParameters();
par.ConnectTimeout = TimeSpan.FromMinutes(1);
try
{
using (var ftpClient = new FtpClient(plcFtpUri, plcFtpCred, par))
{
// Using FTP, get the list of files existing on the PLC side
IEnumerable<FtpEntry> plcFiles = ftpClient.MlsdEntries(plcLogPath);
foreach (FtpEntry plcFile in plcFiles)
{
int localFileIndex = -1;
bool download = false;
// Step through all .csv files on the plc side, download if the size differs or if they dont exist locally.
if (plcFile.Size != null && plcFile.Name.Contains(".csv"))
{
//Console.WriteLine("File found in PLC: " + plcFile.Name);
localFileIndex = Array.FindIndex(localFiles, localFile => localFile.Name.Equals(plcFile.Name));
if (localFileIndex != -1)
{
//Console.WriteLine("The file exists locally.");
if (localFiles[localFileIndex].Length != plcFile.Size)
{
Console.WriteLine("File: " + plcFile.Name + " has unseen data. Downloading.");
download = true;
}
else
download = false;
}
else
{
Console.WriteLine("File: " + plcFile.Name + " does not exist locally. Downloading.");
download = true;
}
if (download)
using (FileStream newLocalFile = File.Create(LocalLogPath + @"\" + plcFile.Name))
{
using (Stream ftpDLstream = ftpClient.Retr(plcFile.Path, FtpTransferMode.Binary))
ftpDLstream.CopyTo(newLocalFile);
}
}
}
}
Console.WriteLine("Exiting FTP function.");
return true;
}
catch (Exception ex)
{
AddToEventLog("An exception occured. See log file for details.");
Util.AppendToErrorLog(LogFiles.App, "Could not FTP to PLC:\n" + ex.ToString());
return false;
}
}
And here is the output of the program:
File: 2016-12-20.csv does not exist locally. Downloading.
File: 2016-12-21.csv does not exist locally. Downloading.
File: 2016-12-22.csv does not exist locally. Downloading.
Exception thrown: 'System.Threading.ThreadInterruptedException' in mscorlib.dll
The thread 0x3920 has exited with code 0 (0x0).
Exiting FTP function.
As you can see, the exception is thrown while inside my ftp function but seemingly on an other thread as it is not caught in my try-catch block. All files are succesfully downloaded and my function returns "true".
It would be really nice to have asynchronous API since this library provide an interface for network I/O. The best possible solution will be to target .NET >= 4.5 and use async/await pattern, but if it's not possible we can at least implement it using older patterns, as IAsyncResult.
I use multiple threads those include sometimes uploading a image.
But sometimes it works, and sometimes not, they call that random ;)
The error I get is this: IO Exception while connection to FTP server
Its a fact the the target FTP directory contains many pictures, and need some time to open that directory.
the code and structure I use is like this:
while (SELECT image,.* FROM something){
thread start (
doheavymanythings()
)
}
void doheavymanythings(){
// many things here
// including image upload
UploadImage()
}
bool UploadImage()
{
try
{
using (var ftpClient = new FtpClient(new Uri(uploadOptions.FTPHost),
new NetworkCredential(uploadOptions.FTPUser, uploadOptions.FTPPass),
new FtpClientParameters
{
Passive = true,
ChannelProtection = FtpProtection.ControlChannel
}))
{
using (var s = ftpClient.Stor(uploadOptions.FTPPath + imgFileName))
{
msg("FTP start upload", 0, false);
byte[] fileData = null;
try
{
fileData = File.ReadAllBytes(Uploader.Properties.Resources.imageTempPath + imgFileName);
}
catch (Exception e)
{
// NO ERROR
error("FTP error2 :" + e.Message);
}
if (fileData != null)
{
for (int i = 0; i < fileData.Length; i++)
{
s.WriteByte(fileData[i]);
msg("FTP upload [" + (i + 1) * 100 / fileData.Length + " %]", (i + 1) * 100 / fileData.Length);
}
}
return true;
}
}
}
catch (Exception e)
{
// HERE I GET THE ERROR
// IO Exception while connection to FTP server
error("FTP error :" + e.Message);
}
finally
{
msg();
}
return false;
}
In order to avoid disorder...
Make path management standard (for both Windows and Linux)
I have a file when I check with FileZilla it says modified 12:57:00 AM, but in ArxOne FTP file.Date property says 12:57:00 PM. Ordering the file list by date returns wrong files as more recent, even though there are newer files since then.
I have noticed that sometimes I get an error connecting to a certain server: ftp.ch.freebsd.org
Out of 2000 tests, it failed only 8 times..... so, strangely enough, it only happens sometimes.
It reports an error:
Impossible to parse line: drwxr-xr-x 1 10000 10000 34 Aug 12
When I look at the server listing for / I see that the only matching line is:
drwxr-xr-x 1 10000 10000 34 Aug 12 00:10 funport
The server claims to be vsFTPd 3.0.2
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.