tags:

views:

1469

answers:

5

I'm using the code below (needs to be .Net 2.0) to connect on a UAT server to a customer FTP server to up/down load files. I need to connect over port 990, using a self signed certificate supplied by them. I've got the firewall rules amended to allow connection to the URI on port 990 from our UAT server.

However (! :) ) I get a timeout on the line

 Stream requestStream = request.GetRequestStream();

If I increase the timeout time it makes no difference.

I've had a look around on the web but found nothing obvious that is missing in the code.

If I use CuteFTP to connect on the UAT server then, naturally, it connect fine and I can manually do the file transfers. If I use WireShark to look at the network traffic it gets a responce from the FTP server but never does the handshake for the userid and pwd (for the code), but via CuteFTP all the network traffic is fine.

I force the return of True where it checks the certificate.


private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                string completeFTPPath = ConfigurationManager.AppSettings["FTPPath"];
                // get the object used to communicate with the server.
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(completeFTPPath);
                request.EnableSsl = true;
                request.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["FtpUserName"], ConfigurationManager.AppSettings["FtpPassword"]);
                request.Method = WebRequestMethods.Ftp.UploadFile;                

                ServicePointManager.ServerCertificateValidationCallback = AcceptAllCertifications;

                // read file into byte array
                StreamReader sourceStream = new StreamReader(ConfigurationManager.AppSettings["LocalFilePath"]);
                byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
                sourceStream.Close();
                request.ContentLength = fileContents.Length;

                // send bytes to server
                MessageBox.Show("GetRequestStream() start");
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(fileContents, 0, fileContents.Length);
                requestStream.Close();
                MessageBox.Show("GetRequestStream() end");

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
                MessageBox.Show("Response status: " + response.StatusDescription);
            }
            catch (WebException we)
            {
                MessageBox.Show(we.Message);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }

        }

  public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
        { return true; }

e.g. FTPPath - ftp://111.222.333.444%3A990/UAT/testFile.zip; FtpUserName - userID; FtpPassword = userPwd; LocalFilePath - c:\temp\testFile.zip

Anyone any ideas? As some people seem to have the above code working. TIA.

A: 

Turn on tracing in .Net and repro the issue then post up the resulting log and I'll tell you what's going wrong. There are a few known issues in FtpWebRequest in .Net 2.0 so you could be hitting one of them also but it's impossible to say just with the code you're showing. Instructions for turning on tracing can be found here: http://blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx

Jeff Tucker
A: 

Hi Jeff, I did have a look at this originally also, but it didn't shed much light to me.

I've run the trace again just now, and used the SSL system.diagnostics settings in Durgaprasad's post.

System.Net Verbose: 0 : [7016] WebRequest::Create(ftp://www.companyname.com:990/UAT/testFile.zip)
System.Net Information: 0 : [7016] FtpWebRequest#48285313::.ctor(ftp://www.companyname.com:990/UAT/testFile.zip)
System.Net Verbose: 0 : [7016] Exiting WebRequest::Create()     -> FtpWebRequest#48285313
System.Net Verbose: 0 : [7016] FtpWebRequest#48285313::GetRequestStream()
System.Net Information: 0 : [7016] FtpWebRequest#48285313::GetRequestStream(Method=STOR.)
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Socket() 
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Connect(131:990#-2083582714)
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Connect() 
System.Net Information: 0 : [7016] Associating FtpWebRequest#48285313 with FtpControlStream#18796293
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Receive()
System.Net.Sockets Error: 0 : [7016] Exception in the Socket#31914638::Receive - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Receive()   -> 0#0
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Dispose()
System.Net Information: 0 : [7016] FtpWebRequest#48285313::(Releasing FTP connection#18796293.)
System.Net Error: 0 : [7016] Exception in the FtpWebRequest#48285313::GetRequestStream - The operation has timed out.
System.Net Error: 0 : [7016]    at System.Net.FtpWebRequest.GetRequestStream()
System.Net Verbose: 0 : [7016] Exiting FtpWebRequest#48285313::GetRequestStream() 

Also, (at the previous time of running this) I got the network team to run Netmon and they implied from the below, that it was code related :


  TCP    kulccstgweb02:2673     companyname.com:microsoft -ds  ESTABLISHED
  TCP    kulccstgweb02:2678     companyname IP:ftps    ESTABLISHED
  TCP    kulccstgweb02:sms-chat  companyname IP:ftps    ESTABLISHED

BTW, the FTPPath - "ftp://111.222.333.444:990/UAT/testFile.zip" is actaully "ftp://www.companyname.com:990/UAT/testFile.zip" and is then resolved to the IP. But I don't see how that could make a difference.

Neil Carey
If the host name "111.222.333.444" isn't the name "www.company.com", then certificate name matching will fail. Might this be your issue?
Steve Gilham
A: 

Being on port 990, the server is most likely supporting implicit FTPS, not the more standard explicit FTPS. It may be that implicit FTPS is not supported in FtpWebRequest (I don't know).

If so, take a look at edtFTPnet/PRO , which supports both implicit and explicit FTPS, as well as SFTP.

Bruce Blackshaw
+1  A: 

Try the EnterpriseDT library.

tsilb
A: 

When uploading a file with FTP I usually create the FtpWebRequest object like this:

string address = "ftp://www.companyname.com/UAT/"
string fileName = "testFile.zip"
UriBuilder uriBuilder = new UriBuilder(address);
FtpWebRequest  request = (FtpWebRequest)WebRequest.Create(uriBuilder.ToString() + fileName);

Give this a try and see what happens, I know this works with explicit SSL and port 990.

Crackerjack