Our Delphi application is trying to connect to our website via IdFTP on a client machine using a proxy server, and I always get a 'read timed out' message. I don't know how to fix it.
My code:
IdFTP1.Host :=Website_address;
IdFTP1.Username :=Website_user;
IdFTP1.Password :=Website_password;
IdFTP1.TransferType:=ftBinary;
IdFTP1.ProxySettings.ProxyType:=fpcmNone;
IdFTP1.ProxySettings.Host :=Proxy_server;
IdFTP1.ProxySettings.Port :=Proxy_port;
IdFTP1.ProxySettings.Username :=Proxy_username;
IdFTP1.ProxySettings.Password :=Proxy_password;
IdFTP1.Connect;
...which returns a 'read timed out' exception.
Having looked on the web for possible solutions, I have tried various combinations of the following with no joy (although there might be a combination that might work, I just don't really know what I'm doing):
IdFTP1.IOHandler :=TIdSSLIOHandlerSocketOpenSSL.Create
(IdFTP1);
IdFTP1.UseTLS :=utUseExplicitTLS;
IdFTP1.NATKeepAlive.UseKeepAlive:=True;
IdFTP1.NATKeepAlive.IdleTimeMS :=100000;
IdFTP1.DataPortProtection :=ftpdpsPrivate;
The frustrating thing is I can't test it on my machine, I have to compile a new version of the application, copy it to their machine, and then see if it works.
There is nothing complex about the installation on the client side as far as I can tell. They have given me the proxy host address, and the proxy username and password are blank.
Other bits of the application connect to the same website via HTTP and the proxy server, and this works perfectly. So my logic is that it can't be firewalls or anything like that.
IdHTTP1.HandleRedirects :=True;
IdHTTP1.ProxyParams.BasicAuthentication:=True;
IdHTTP1.ProxyParams.ProxyServer :=Proxy_server;
IdHTTP1.ProxyParams.ProxyPort :=Proxy_port;
IdHTTP1.ProxyParams.ProxyUsername :=Proxy_username;
IdHTTP1.ProxyParams.ProxyPassword :=Proxy_password;
I am using Delphi XE8.
They have created a virtual server for our testing, it runs Windows 7 64 bit.
Update
Remy, is this the right idea? One problem I am having is the TIdConnectThroughHttpProxy component, what must be in the uses clause for this? Delphi is not recognizing it.
var
TempIO : TIdIOHandlerStack;
TempProxy : TIdConnectThroughHttpProxy;
......
TempIO :=TIdIOHandlerStack.Create;
TempProxy :=TIdConnectThroughHttpProxy.Create;
TempProxy.Host :=Proxy_host;
TempIO.TransparentProxy:=TempProxy;
IdFTP1.IOHandler :=TempIO;
IdFTP1.Connect;
Update 2
A point of clarity: the HTTP request that is successfully reaching the web server through the proxy server goes to a different web address than the FTP request. In other words, they both go through the same proxy server, but the destination addresses are different. Just in case this is of use.
I have now tried using Fiddler to find the problem, not sure if this is a great idea? My understanding is is that Fiddler acts as a proxy server, so I thought I would see if I encountered the same problem. Sure enough, can't connect.
To be clear about my steps:
Run Fiddler, and check the box that says 'Capture FTP requests'.
Update my IdHTTP component:
IdHTTP1.ProxyParams.ProxyServer:='127.0.0.1';
IdHTTP1.ProxyParams.ProxyPort :=Fiddler port;
Update my IdFTP component:
IdFTP1.ProxySettings.Host:='127.0.0.1';
IdFTP1.ProxySettings.Port:=Fiddler port;
So now I have removed the client setup completely, I am mirroring the problem from my local machine using Fiddler as far as I can tell. If I don't use Fiddler, everything works great. If I use Fiddler as described above, then the HTTP request works correctly, but the FTP request can't connect.
Any ideas as to what I can do to try and solve this? I'm sure it is something really stupid that I'm doing wrong.
IdFTP1.ProxySettings.ProxyType:=fpcmNone
This tells TIdFTP
not to communicate with an FTP-aware proxy. If you want to use the TIdFTP.ProxySettings
properties, you need to set the ProxyType
so TIdFTP.Connect()
will connect to the ProxySettings.Host
and TIdFTP.Login()
will know what kind of commands it needs to send to login to the proxy and request a connection to the next host.
Note that TIdFTP.ProxySettings
only works with FTP proxies. If you need to connect to a different type of proxy, before you call TIdFTP.Connect()
you will have to assign a TIdIOHandler
-derived component to the TIdFTP.IOHandler
property, and then assign a TIdCustomTransparentProxy
-derived component to the TIdIOHandler.TransparentProxy
property. To connect to an HTTP proxy (which it sounds like you need, since that is what TIdHTTP.ProxyParams
works with), use TIdConnectThroughHttpProxy
. To connect to a SOCKS proxy, use TIdSocksInfo
.