代码之家  ›  专栏  ›  技术社区  ›  Nico

使用HTTP代理上传FTP文件

  •  20
  • Nico  · 技术社区  · 17 年前

    似乎在使用.Net Webclient的HTTP代理后面不支持上载文件。( http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.proxy.aspx

    如果没有解决办法?如果没有,你知道一个好的免费FTP库我可以使用吗?

    编辑

    13 回复  |  直到 15 年前
        1
  •  9
  •   Alexander    17 年前

    这个 FtpWebRequest 似乎支持被动模式。但是,我不明白为什么支持文件下载和目录列表,而同样使用相同数据连接的文件上载则不支持。

    你确认了吗 为被动模式配置的不通过HTTP代理工作,通过哪个目录列表/文件下载工作正常?

        2
  •  5
  •   Nic Wise    17 年前

    大多数FTP代理在连接上执行它们的操作,因此如果没有代理,则执行以下操作:

    • 服务器:myftpserver.com网站
    • 密码:pwd

    • 用户:me@myftpserver.com
    • 密码:pwd

    从那开始就行了。我在这一秒通过squid代理使用这个(试着调试一些东西)。

    你有袜子代理吗?这可能管用,但我不知道.NET是否能做到。否则,老实说,我觉得你被卡住了!与HTTP相比,FTP是一种“奇怪”的协议,因为它有一个控制通道(端口21)和一个数据通道(或多个随机端口),所以通过代理是。。。。至少说起来很有趣!

        3
  •  5
  •   Martin Vobr    15 年前

    Rebex FTP/SSL

    // 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();
    
        4
  •  4
  •   Martin Prikryl    6 年前

    从.NETFramework4.8开始 FtpWebRequest 仍然 cannot upload files over HTTP proxy

    可能永远不会 FtpWebRequest公司


    例如 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");
    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();
    }
    

    对于tje的选项 SessionOptions.AddRawSettings raw settings .

    generate C# FTP code template

    (我是WinSCP的作者)

        5
  •  3
  •   Alexander    17 年前

    一种解决方案是尝试Mono的FtpWebRequest实现。我看了一下它的源代码,它看起来很容易修改,这样所有的连接(控件和数据)都可以通过HTTP代理进行隧道连接。

    建立到HTTP代理的TCP连接,而不是实际的FTP服务器。然后你派 CONNECT myserver:21 HTTP/1.0 HTTP/1.0 200 “或” HTTP/1.1 200 ,则您(代码的其余部分)可以继续使用该连接,就像它直接连接到FTP服务器一样。

        6
  •  2
  •   VVS    17 年前

    没有 那么也应该有可能在C。通过浏览器或FTP客户端上传是否有效?

    我最喜欢的一个FTP库是 .NET FTP Client library .

        7
  •  2
  •   Darron    17 年前

    我的雇主出售这样一个FTP客户端,但它是一个企业级工具,只作为一个非常大的系统的一部分提供。

        8
  •  2
  •   Henrik Nordström    14 年前

    通过HTTP代理将内容上传到ftp://URL的标准方法是使用HTTP PUT请求。当处理FTP://url时,HTTP代理充当HTTP<->FTP网关,向请求的客户端发送HTTP,向请求的FTP服务器发送FTP。

    至少Squid HTTP代理支持PUT to ftp://url,不确定其他代理做什么。

    更常见的方法是通过滥用CONNECT方法在代理上搜索隧道。但这通常是不允许的,因为允许代理上的双向隧道会带来安全隐患。

        9
  •  2
  •   miconico    13 年前

    FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
    
    System.Net.WebProxy proxy = System.Net.WebProxy.GetDefaultProxy();
    proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
    
    // set the ftpWebRequest proxy
    reqFTP.Proxy = proxy;
    

    这为我解决了这个问题。

        10
  •  0
  •   A. 'Eradicator' Polyakov    12 年前

    该死的这些不自由的应用程序和组件!!! 这是我的开源C代码,可以通过HTTP代理将文件上传到FTP。

            public bool UploadFile(string localFilePath, string remoteDirectory)
        {
            var fileName = Path.GetFileName(localFilePath);
            string content;
            using (var reader = new StreamReader(localFilePath))
                content = reader.ReadToEnd();
    
            var proxyAuthB64Str = Convert.ToBase64String(Encoding.ASCII.GetBytes(_proxyUserName + ":" + _proxyPassword));
            var sendStr = "PUT ftp://" + _ftpLogin + ":" + _ftpPassword
                + "@" + _ftpHost + remoteDirectory + fileName + " HTTP/1.1\n"
                + "Host: " + _ftpHost + "\n"
                + "User-Agent: Mozilla/4.0 (compatible; Eradicator; dotNetClient)\n" + "Proxy-Authorization: Basic " + proxyAuthB64Str + "\n"
                + "Content-Type: application/octet-stream\n"
                + "Content-Length: " + content.Length + "\n"
                + "Connection: close\n\n" + content;
    
            var sendBytes = Encoding.ASCII.GetBytes(sendStr);
    
            using (var proxySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                proxySocket.Connect(_proxyHost, _proxyPort);
                if (!proxySocket.Connected)
                    throw new SocketException();
                proxySocket.Send(sendBytes);
    
                const int recvSize = 65536;
                var recvBytes = new byte[recvSize];
                proxySocket.Receive(recvBytes, recvSize, SocketFlags.Partial);
    
                var responseFirstLine = new string(Encoding.ASCII.GetChars(recvBytes)).Split("\n".ToCharArray()).Take(1).ElementAt(0);
                var httpResponseCode = Regex.Replace(responseFirstLine, @"HTTP/1\.\d (\d+) (\w+)", "$1");
                var httpResponseDescription = Regex.Replace(responseFirstLine, @"HTTP/1\.\d (\d+) (\w+)", "$2");
                return httpResponseCode.StartsWith("2");
            }
            return false;
        }
    
        11
  •  -1
  •   dvn    16 年前

    我也有同样的问题。

    所以我已经准备好了FTPWebRequest.Proxy属性在后面为空FTPWebRequest.Create(uri)。

    而且成功了。是的,我知道这个解决方案不是最好的。更重要的是,我不明白为什么会这样。但无论如何,目标是完全的。

        12
  •  -1
  •   Elephantik    12 年前

    ftp://user:pass@your.server.com/path

    不幸的是,要创建HttpWebRequest的实例,您应该使用WebRequest.Create创建. 如果这样做,就不能为ftp://schema创建HTTP请求。

    所以我使用了一点反射来调用一个非公共构造函数,它可以:

    var ctor = typeof(HttpWebRequest).GetConstructor(
        BindingFlags.NonPublic | BindingFlags.Instance, 
        null, 
        new Type[] { typeof(Uri), typeof(ServicePoint) }, 
        null);
    var req = (WebRequest)ctor.Invoke(new object[] { new Uri("ftp://user:pass@host/test.txt"), null });
    req.Proxy = new WebProxy("myproxy", 8080);
    req.Method = WebRequestMethods.Http.Put;
    
    using (var inStream = req.GetRequestStream())
    {
        var buffer = Encoding.ASCII.GetBytes("test upload");
        inStream.Write(buffer, 0, buffer.Length);
    }
    
    using (req.GetResponse())
    {
    }
    

    您还可以对其他任务使用“DELETE”等其他方法。

        13
  •  -5
  •   Vasil    17 年前

    Id没有真正看到http代理和上传到ftp服务器之间的连接。如果您使用http代理类,该类用于通过http代理访问http资源。ftp是另一种协议,ftp代理使用不同的协议。