tags:

views:

8918

answers:

9

Is there a way to upload a file to a FTP server when behind an HTTP proxy ?

It seems that uploading a file is not supported behind an HTTP Proxy using .Net Webclient. (http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.proxy.aspx).

If there is no workaround ? If not, do you know a good and free FTP library I can use ?

Edit: Unfortunately, I don't have any FTP proxy to connect to.

A: 

Id don't really see the connection between a http proxy and uploading to an ftp server. If you use the http proxy class thats for accessing http resources trough a http proxy. ftp is another protocol and the ftp proxies use a different protocol.

Vasil
Don't forget the CONNECT method of HTTP proxies. The method facilitates the tunneling of arbitrary outbound TCP connections. For example, that's how HTTPS works via an HTTP proxy.
Alexander
+2  A: 

In active FTP mode, the server initiates a data connection to the client. If the client is behind an HTTP proxy, this obviously won't work. In passive FTP mode it is the client who initiates both the initial and the data connections. Since HTTP proxies can tunnel arbitrary outgoing TCP connections (using the CONNECT method), it should be possible to access an FTP server in passive mode via an HTTP proxy.

The FtpWebRequest seems to support passive mode. However, I don't understand why file download and directory listings are supported, whereas file upload, which also uses the same data connection, is not.

Have you confirmed that FtpWebRequest configured for passive mode does not work via an HTTP proxy through which directory listings/file download work just fine?

Alexander
This shortcoming is documented: "If the specified proxy is an HTTP proxy, only the DownloadFile, ListDirectory, and ListDirectoryDetails commands are supported. " - http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.proxy.aspx
Jonas Elfström
+2  A: 

most FTP proxies do their thing on the connection, so if you had NO proxy, you do this:

  • server: myftpserver.com
  • user: me
  • password: pwd

using an FTP proxy, you do:

and it just works it out from there. I'm using this RIGHT THIS SECOND (trying to debug something) thru a squid proxy.

... but as you dont have an FTP proxy....

Do you have a SOCKS proxy? That might work, but I dont know if .NET can do it. Otherwise, to be honest, I think you are stuck! FTP is an "odd" protocol, when compared to HTTP, as it has a control channel (port 21) and a data channel (or more than one, on a random port), so going via proxies is.... fun to say the least!

Nic Wise
He doesn't have an FTP proxy.
VVS
bugger, missed that bit. Editing
Nic Wise
+1  A: 

If there's a way for you to upload a file via FTP without C# then it should also be possible in C#. Does uploading via browser or an FTP client work?

The one FTP library I like the most is .NET FTP Client library.

VVS
Alexander
I guess, if the above FTP client works fine in passive mode, then you could easily modify its source code to tunnel TCP connections (it's about 20 lines of code in Java).
Alexander
@Alexander: I have to admit that I only used it with an FTP proxy which can be used like a normal FTP server.
VVS
No signs of proxy support in the source.
Jonas Elfström
+1  A: 

As Alexander says, HTTP proxies can proxy arbitrary traffic. What you need is an FTP Client that has support for using a HTTP Proxy. Alexander is also correct that this would only work in passive mode.

My employer sells such an FTP client, but it is a enterprise level tool that only comes as part of a very large system.

I'm certain that there are others available that would better fit your needs.

Darron
A: 

One solution is to try Mono's implementation of FtpWebRequest. I had a look at its source code and it appears it'll be easy to modify so that all connections (control and data) are tunneled via an HTTP proxy.

You establish a TCP connection to your HTTP proxy instead of the actual FTP server. Then you send CONNECT myserver:21 HTTP/1.0 followed by two CRLFs (CRLF = \r\n). If the proxy needs authentication, you need to use HTTP/1.1 and also send a proxy authentication header with the credentials. Then you need to read the first line of the response. If it starts with "HTTP/1.0 200 " or "HTTP/1.1 200 ", then you (the rest of the code) can continue using the connection as though it's connected directly to the FTP server.

Alexander
+1  A: 

Our Rebex FTP/SSL can use HTTP proxy. It's not free, though...

// initialize FTP client 
Ftp client = new Ftp();

// setup proxy details  
client.Proxy.ProxyType = FtpProxyType.HttpConnect;
client.Proxy.Host = proxyHostname;
client.Proxy.Port = proxyPort;

// add proxy username and password when needed 
client.Proxy.UserName = proxyUsername;
client.Proxy.Password = proxyPassword;

// connect, login 
client.Connect(hostname, port);
client.Login(username, password);

// do some work 
// ... 

// disconnect 
client.Disconnect();
Martin Vobr
I have several experience with Rebex FTP/FTPS library and it solved all my problems. I hichly recommend this library, because it saves me a lot of time => money.
TcKs
A: 

It's not free ($149), but edtFTPnet/Express supports FTP via HTTP proxies.

Bruce Blackshaw
Bruce, could you please disclose your affiliation in each post where you mention your own products? I know you're not trying anything shady, this is just the policy that moderators are asking everyone to adhere to. Please see the FAQ for the official policy statement. Thanks. http://stackoverflow.com/faq
Martin Vobr
A: 

I've just had the same problem.

My primary goal was to upload a file to an ftp. And I didn't care if my traffic would go through proxy or not.

So I've just set FTPWebRequest.Proxy property to null right after FTPWebRequest.Create(uri).

And it worked. Yes, I know this solution is not the greatest one. And more of that, I don't get why did it work. But the goal is complete, anyway.

los-t
`And I didn't care if my traffic would go through proxy or not.` - but do you have to connect through your proxy to connect to the internet or was it just optional?
Jonas Elfström