Repository navigation
Description
FTP OS: irrelevant
FTP Server: irrelevant
FTP Proxy: CCProxy 8.0 (and likely others)
Computer OS: Windows 10 20H2
FluentFTP Version: 34.0
There appear to be two general issues with the UserAtHost proxy.
CCProxy and probably other proxies provide a status 220 banner on connect. With the current UserAtHost proxy implementation it is impossible to connect in such a case, because the Execute("USER " + userName); during Authenticate will run into the StaleDataCheck, which closes the stream, causing another failing Connect() attempt and the whole thing continues failing recursively.
Inserting a GetReply() during the proxy handshake solves the issue (as in the custom Blue Coat solution for #246), but I think calling base.Handshake() should be the preferred way for FTP proxies to override that method anyway, no? I am not sure though whether all FTP proxies provide a banner, or if a direct or indirect call to GetReply() during the handshake might actually lead to a potential hang if they do not.
The second issue is that the current method of replacing Credentials.UserName with User@Host information is not guarded, which leads to User@Host@Host@Host... if Handshake is called repeatedly as in the scenario above.
I'm happy to provide a PR for these issues, if there is some consensus on how to approach the first issue. If proxies exist with or without banner, perhaps a check of whether the stream has data before calling GetReply() is an option, or a version of that function that times out instead of blocking when no data is available?
Logs :
# Connect()
# Connect()
Status: Connecting to 192.168.40.9:2121
Status: Connecting to 192.168.40.9:2121
Status: There is stale data on the socket, maybe our connection timed out or you did not call GetReply(). Re-connecting...
Status: There is stale data on the socket, maybe our connection timed out or you did not call GetReply(). Re-connecting...
Status: The stale data was: 220-CCProxy FTP Service(Unregistered)
220-you need to input userid@site as login name.
220 Example: user anonymous@ftp.netscape.com
Status: The stale data was: 220-CCProxy FTP Service(Unregistered)
220-you need to input userid@site as login name.
220 Example: user anonymous@ftp.netscape.com
Status: Disposing FtpSocketStream...
Status: Disposing FtpSocketStream...
# Connect()
# Connect()
Status: Connecting to 192.168.40.9:2121
Status: Connecting to 192.168.40.9:2121
Status: There is stale data on the socket, maybe our connection timed out or you did not call GetReply(). Re-connecting...
Status: There is stale data on the socket, maybe our connection timed out or you did not call GetReply(). Re-connecting...
Status: The stale data was: 220-CCProxy FTP Service(Unregistered)
220-you need to input userid@site as login name.
220 Example: user anonymous@ftp.netscape.com
Status: The stale data was: 220-CCProxy FTP Service(Unregistered)
220-you need to input userid@site as login name.
220 Example: user anonymous@ftp.netscape.com
Status: Disposing FtpSocketStream...
Status: Disposing FtpSocketStream...
[continues ad infinitum]
Activity
robinrodricks commentedon May 26, 2021
Hi, thanks for this detailed issue/PR. The first option is probably better
check of whether the stream has data before calling GetReply().robinrodricks commentedon May 26, 2021
If this is specific to CCProxy, then it would be better to create a custom proxy class like for BlueHost, if you are not sure, then also create a custom proxy class.
FamiPun commentedon Jun 2, 2022
I encountered a similar problem when using UserAtHost proxy, but it was solved by creating a custom proxy class like BlueHost.
robinrodricks commentedon Sep 19, 2022
Added to the bucket list. We will pick this up as and when we have free time. Comment on this issue if you want us to prioritize it. Thanks!