2012-07-27 77 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爲指向正確的方向。

相關問題