Connect to ftps:// URL

user2676140 picture user2676140 · May 6, 2015 · Viewed 9.8k times · Source

I am trying to use this code to upload a file to an FTP, the problem I have is that when the syntax hits the serverURI.Scheme != Uri.UriSchemeFtp it returns false. Does that mean I have my URI address set-up incorrectly? I know it is a valid address, I have used ftptest.net to verify the site is up and running. What is incorrect in my syntax?

private void button1_Click(object sender, EventArgs e)
{
  Uri serverUri = new Uri("ftps://afjafaj.org");
  string userName = "Ricard";
  string password = "";
  string filename = "C:\\Book1.xlsx";
  ServicePointManager.ServerCertificateValidationCallback = AcceptAllCertificatePolicy;
  UploadFile(serverUri, userName, password, filename);
}

public bool AcceptAllCertificatePolicy(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
  return true;
}

public bool UploadFile(Uri serverUri, string userName, string password, string fileName)
{
  if (serverUri.Scheme != Uri.UriSchemeFtp)
    return false;

  try
  {
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
    request.EnableSsl = true;
    request.Credentials = new NetworkCredential(userName, password);
    request.Method = WebRequestMethods.Ftp.UploadFile;
    StreamReader sourceStream = new StreamReader(fileName);
    byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
    sourceStream.Close();
    request.ContentLength = fileContents.Length;
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(fileContents, 0, fileContents.Length);
    requestStream.Close();

    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Console.WriteLine("Response status: {0}", response.StatusDescription);
  }
  catch (Exception exc)
  {
    throw exc;
  }
  return true;
}

Answer

Martin Prikryl picture Martin Prikryl · May 7, 2015

The ftps:// prefix is not a standard IANA URI scheme. There's only ftp:// scheme, as defined by RFC 1738.

Anyway, the ftps:// is still recognized by some software to refer to an FTP over TLS/SSL protocol (secure FTP). This mimics https:// scheme, which is an HTTP over TLS/SSL (https:// is a standard scheme).

Though the ftps:// is NOT recognized by the .NET framework.

To connect to the explicit mode FTP over TLS/SSL, change your URI to ftp://, and set FtpWebRequest.EnableSsl to true (what you are doing already).


Note that the ftps:// prefix commonly refers to an implicit mode FTP over TLS/SSL. The .NET framework supports only an explicit mode. Though even if your URI is indeed referring to the implicit mode, most servers would support the explicit mode too anyway. So this won't be a problem typically. For the explicit mode, ftpes:// is sometimes used. See my article to understand the difference between FTP over TLS/SSL implicit and explicit modes.