简体   繁体   English

如何使用Ruby Net :: FTP代理服务器?

[英]How to use proxy server with Ruby Net::FTP?

I am using the Net::FTP ruby library to connect to an FTP server and download files. 我使用Net :: FTP ruby​​库连接到FTP服务器并下载文件。 It all works well, but now I need to use an outbound proxy since their firewall whitelists IP addresses, and I am using Heroku to host the site. 这一切都运行良好,但现在我需要使用出站代理,因为他们的防火墙白名单IP地址,我使用Heroku来托管该网站。 I'm trying out the new Proximo add-on which looks promising, but I can't get Net::FTP to use it. 我正在尝试新的Proximo附加组件看起来很有前途,但我不能让Net :: FTP使用它。

I see the following in the Net::FTP docs : 我在Net :: FTP文档中看到以下内容:

connect(host, port = FTP_PORT) connect(host,port = FTP_PORT)

Establishes an FTP connection to host, optionally overriding the default port. 建立与主机的FTP连接,可选择覆盖默认端口。 If the environment variable SOCKS_SERVER is set, sets up the connection through a SOCKS proxy. 如果设置了环境变量SOCKS_SERVER,则通过SOCKS代理设置连接。 Raises an exception (typically Errno::ECONNREFUSED) if the connection cannot be established. 如果无法建立连接,则引发异常(通常为Errno :: ECONNREFUSED)。

But trying to set this environment variable, or setting ENV['SOCKS_SERVER'] = proximo_url doesn't work either. 但是尝试设置此环境变量,或者设置ENV['SOCKS_SERVER'] = proximo_url也不起作用。 Does anyone know how to properly do this? 有谁知道如何正确地做到这一点? It doesn't have to be a SOCKS proxy, an HTTP proxy will do, but I'm not sure that the Net::FTP library supports this. 它不一定是SOCKS代理,HTTP代理也可以,但我不确定Net :: FTP库是否支持这一点。

... after some research ... ...经过一些研究......

I found that Net::FTP looks for a class called SOCKSSocket , for which I found these docs . 我发现Net :: FTP查找了一个名为SOCKSSocket的类,我找到了这些文档 But I can't include it. 但我不能包括它。 include 'socket' returns false which I'm pretty sure means it's already loaded. include 'socket'返回false,我很确定这意味着它已经加载了。

Maybe this link can be of some use to you? 也许这个链接对你有用吗?

https://github.com/plevel/ruby-ftp-proxy https://github.com/plevel/ruby-ftp-proxy

You can use the socksify gem as in combination with eg. 您可以将socksify gem与eg。结合使用。 Quotaguard. Quotaguard。 Make sure you use one of the provided static ip's though (and not the DNS hostname) as proxy server though since FTP and loadbalancing can cause troubles. 尽管FTP和负载均衡可能会导致麻烦,但请确保使用提供的静态IP之一(而不是DNS主机名)作为代理服务器。

Socksify::debug = true
proxy_uri = URI(ENV['QUOTAGUARDSTATIC_URL'])
proxy_hostname = proxy_uri.hostname
proxy_port = 1080
TCPSocket::socks_username = proxy_uri.user
TCPSocket::socks_password = proxy_uri.password
Socksify::proxy(proxy_hostname, proxy_port) do |soc| 
       Net::FTP.open(server) do |ftp|
            ftp.passive = true
            ftp.debug_mode = true 
            ftp.login user, password
            ftp.get(export, storelocation)
            ftp.close
       end
end

This is my take on the problem. 这是我对这个问题的看法。 The boiler plate: 锅炉板:

# Connects to ftp through a socks proxy
#
# TODO: testing, use ssl, capture debugging output, recovery on network failure...
#
# @param ftpHost   [String ] Domain name or ip address of the ftp server
# @param proxyHost [String ] Host name or ip address of the socks proxy
# @param proxyPort [FixNum ] Port number of the socks proxy
# @param proxyUser [String ] User name for connecting to the proxy if needed
# @param proxyPass [String ] Password  for connecting to the proxy if needed
# @param ftpPort   [FixNum ] Ftp port, defaults to 21
# @param ftpUser   [String ] Ftp username
# @param ftpPass   [String ] Ftp password
# @param debug     [Boolean] Whether to turn on debug output of both socksify and Net::FTP, will be sent to STDOUT
# @param passive   [Boolean] Whether to use passive FTP mode
#
def ftp(

        ftpHost:                      ,
        proxyHost:                    ,
        proxyPort:                    ,
        proxyUser: nil                ,
        proxyPass: nil                ,
        ftpPort:   Net::FTP::FTP_PORT ,
        ftpUser:   'anonymous'        ,
        ftpPass:   'anonymous@'       ,
        debug:     false              ,
        passive:   true

    )

    Socksify::debug           = debug
    TCPSocket::socks_username = proxyUser
    TCPSocket::socks_password = proxyPass

    Socksify::proxy( proxyHost, proxyPort ) do |_|

        begin

            # Check whether we got an ip address or a domain name.
            # If needed we'll do dns through the socket to avoid dns leaks.
            #
            Regexp.new( URI::RFC2396_Parser.new.pattern[ :IPV4ADDR ] ) =~ ftpHost  or

                ftpHost = Socksify::resolve( ftpHost )


            ftp            = Net::FTP.new
            ftp.debug_mode = debug
            ftp.passive    = passive

            ftp.connect ftpHost, ftpPort
            ftp.login   ftpUser, ftpPass

            yield ftp

        ensure

            ftp.close

        end

    end

end

Now in your actual application you can just do: 现在在您的实际应用程序中,您可以这样做:

def listRemoteFiles

    connect do |ftp|

        puts ftp.list.inspect  # or other cool functions from Net::FTP

    end

end


def connect &block

    ftp({

        debug:     true            ,
        proxyHost: your.proxy.host ,
        proxyPort: your.proxy.port ,
        ftpHost:   your.ftpHost 

    }, &block )

end

Thanks to tvgriek for pointing in the right direction. 感谢tvgriek指向正确的方向。

You can use the Proximo wrapper to forward traffic through Proximo. 您可以使用Proximo包装器通过Proximo转发流量。 Here are the official instructions: https://devcenter.heroku.com/articles/proximo#forwarding-traffic-through-proximo 以下是官方说明: https//devcenter.heroku.com/articles/proximo#forwarding-traffic-through-proximo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM