【问题标题】:Establish FtpWebRequest through a HTTP proxy using the CONNECT method使用 CONNECT 方法通过 HTTP 代理建立 FtpWebRequest
【发布时间】:2024-09-29 14:30:01
【问题描述】:

我尝试使用FtpWebRequest 建立一个FTP 连接。我需要通过squid代理服务器建立连接,这需要我先发送CONNECT命令。

我已经尝试了下面的代码,但这会导致向代理服务器发出 GET 请求,但它拒绝了。

FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" +server);
request.Credentials = new NetworkCredential(user, pwd);
var webproxy = new WebProxy(new Uri("http://" + proxy+ ":" + proxyPort));
webproxy.UseDefaultCredentials = true;
request.Proxy = webproxy;
request.UsePassive = true;
request.Method = WebRequestMethods.Ftp.ListDirectory;

FtpWebResponse response = (FtpWebResponse)request.GetResponse();

有什么方法可以使用FtpWebRequest 通过代理建立连接?

如果没有,您是否知道我可以使用的一个好用且希望免费的 .NET FTP 客户端? 非常感谢您的帮助。

【问题讨论】:

    标签: c# .net proxy ftp ftpwebrequest


    【解决方案1】:

    FtpWebRequest 是一个“无会话”客户端,因此它不允许您在连接时与远程端进行交互。我检查了 FtpWebRequest.cs 的代码,但不知道如何让它发送“CONNECT”命令。

    “CONNECT”命令似乎不是标准 FTP 命令集的一部分,所以我无法理解这如何适合 FTP 库应该做的事情。

    我使用的一个很好的面向会话的免费 FTP 客户端是http://sshnet.codeplex.com/ 的“SSH.NET 库”,但我相信它只支持 sftp。 FtpWebRequest 支持 ftps 和 ftp。查明您的 FTP 服务器是否支持 sftp 并且您可能能够使用 SSH.NET。如果您唯一的选择是 ftps,我可以报告我花了很长时间寻找免费的 .net ftps 客户端,然后我使用 FtpWebRequest。

    【讨论】:

    • FileZilla 支持先发送 Connect 语句。它是在属性中设置通用代理服务器时可以选择的选项之一。这让我假设使用 CONNECT 方法是通过代理服务器进行连接的一些标准方式。但是,通过与我们的基础设施部门进行一些交谈,我的问题得到了解决。他们允许我豁免代理服务器,这样我就可以直接连接到 FTP 服务器而无需通过代理。
    【解决方案2】:

    FtpWebRequest 支持 HTTP 代理(CONNECT 命令是该支持的必要部分)。你的代码是正确的。

    虽然 HTTP 代理不支持上传(它适用于所有其他操作)。所以也许你的实际问题是上传,而你没有提到它。

    对于通过 HTTP 代理的 FTP 上传,您必须使用第 3 方 FTP 客户端。


    例如WinSCP .NET assembly,你可以使用:

    // Setup session options
    SessionOptions sessionOptions = new SessionOptions
    {
        Protocol = Protocol.Ftp,
        HostName = "example.com",
        UserName = "user",
        Password = "mypassword",
    };
    
    // Configure proxy
    sessionOptions.AddRawSettings("ProxyMethod", "3"); // HTTP proxy
    sessionOptions.AddRawSettings("ProxyHost", "proxy");
    
    using (Session session = new Session())
    {
        // Connect
        session.Open(sessionOptions);
    
        // Upload file
        string localFilePath = @"C:\path\file.txt";
        string pathUpload = "/file.txt";
        session.PutFiles(localFilePath, pathUpload).Check();
    }
    

    有关SessionOptions.AddRawSettings 的选项,请参阅raw settings

    为您提供 WinSCP GUI generate C# FTP code template 更简单。

    请注意,WinSCP .NET 程序集不是本机 .NET 库。它是控制台应用程序上的一个精简的 .NET 包装器。

    (我是 WinSCP 的作者)

    【讨论】:

    • 几年前我写了这个问题。我们同时把它修好了。如果我没记错的话,我们在防火墙中遇到了一个异常,因此我们可以直接连接到客户端 FTP 服务器而无需代理。