2012-07-27 4 views
6

Ich verwende die Net :: FTP Ruby-Bibliothek, um eine Verbindung zu einem FTP-Server herzustellen und Dateien herunterzuladen. Alles funktioniert gut, aber jetzt muss ich einen Outbound-Proxy verwenden, da ihre Firewall IP-Adressen auf die weiße Liste setzt und ich Heroku verwende, um die Site zu hosten. Ich probiere das neue Proximo-Add-On aus, das vielversprechend aussieht, aber ich kann Net :: FTP nicht dazu bringen, es zu benutzen.Wie Proxy-Server mit Ruby Net :: FTP verwenden?

Ich sehe die folgenden in der Net::FTP docs:

connect (host, port = FTP_PORT)

Baut eine FTP-Verbindung, gegebenenfalls das Überschreiben der Standard-Port-Host. Wenn die Umgebungsvariable SOCKS_SERVER gesetzt ist, wird die Verbindung über einen SOCKS-Proxy aufgebaut. Löst eine Ausnahme aus (normalerweise Errno :: ECONNREFUSED), wenn die Verbindung nicht hergestellt werden kann.

Der Versuch, diese Umgebungsvariable zu setzen, oder die Einstellung ENV['SOCKS_SERVER'] = proximo_url funktioniert jedoch auch nicht. Weiß jemand, wie man das richtig macht? Es muss kein SOCKS-Proxy sein, ein HTTP-Proxy reicht aus, aber ich bin nicht sicher, ob die Net :: FTP-Bibliothek dies unterstützt.

... nach einigen Recherchen ...

fand ich, dass Net :: FTP für eine Klasse SOCKSSocket, für die ich these docs gefunden genannt aussieht. Aber ich kann es nicht aufnehmen. include 'socket' gibt false zurück, was ziemlich sicher bedeutet, dass es bereits geladen ist.

+0

Haben Sie das jemals herausgefunden? –

+0

@JohnWright leider nicht :( –

Antwort

1

Sie können die Edelstein wie in Kombination mit z. Quotaguard. Stellen Sie jedoch sicher, dass Sie eine der bereitgestellten statischen IPs (und nicht den DNS-Hostnamen) als Proxy-Server verwenden, da FTP und Loadbalancing Probleme verursachen können.

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

Dies ist meine Sicht auf das Problem. Das Kesselblech:

# 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 

Jetzt in Ihrer tatsächlichen Anwendung können Sie einfach tun:

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 

Dank tvgriek für in der richtigen Richtung.