2012-07-27 37 views
6

我使用Net :: FTP ruby​​库连接到FTP服务器并下载文件。它一切正常,但现在我需要使用出站代理,因为它们的防火墙将IP地址列入白名单,并且我使用Heroku来托管该站点。我正在尝试新的Proximo插件,它看起来很有前途,但我无法使用Net :: FTP来使用它。如何在Ruby Net :: FTP中使用代理服务器?

我看到Net::FTP docs以下:

连接(主机,端口= FTP_PORT)

建立FTP连接到主机,任选覆盖默认端口。如果设置了环境变量SOCKS_SERVER,则通过SOCKS代理设置连接。如果无法建立连接,则引发异常(通常为Errno :: ECONNREFUSED)。

但试图设置此环境变量,或设置ENV['SOCKS_SERVER'] = proximo_url也不起作用。有谁知道如何正确地做到这一点?它不一定是SOCKS代理,HTTP代理也可以,但我不确定Net :: FTP库是否支持这一点。

......经过一番研究...

我发现的Net :: FTP查找一个名为SOCKSSocket类,为此,我发现these docs。但我不能包括它。 include 'socket'返回false,我很确定这意味着它已经被加载。

+0

你有没有想过这个? – 2013-06-26 15:20:48

+0

@JohnWright不幸的是:( – 2013-07-02 19:08:14

回答

1

您可以使用宝石与例如。 Quotaguard。确保你使用提供的静态IP的一个(虽然不是DNS主机名)作为代理服务器,但是由于FTP和负载平衡会导致麻烦。

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 
0

这是我对这个问题的看法。锅炉板:

# 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: '[email protected]'  , 
     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 

现在,在实际的应用程序,你可以这样做:

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 

感谢tvgriek为指向正确的方向。

相关问题