我正在使用Net::FTP ruby库连接到FTP服务器并下载文件。这一切都很好,但现在我需要使用出站代理,因为他们的防火墙白名单IP地址,我正在使用Heroku来托管网站。我正在尝试新的Proximo插件,它看起来很有前景,但我无法使用Net::FTP。
我在网上看到以下内容::FTP文档:
连接(主机,端口=FTP_port)
建立到主机的FTP连接,可选择覆盖默认端口。如果设置了环境变量SOCKS_SERVER,则通过SOCKS代理设置连接。如果无法建立连接,则引发异常(通常为Errno::ECONNREFUSED)。
但是尝试设置这个环境变量或设置ENV['SOCKS_SERVER'] = proximo_url
也不起作用。有人知道如何正确地做到这一点吗?它不一定是SOCKS代理,HTTP代理就可以了,但我不确定Net::FTP库是否支持这一点。
经过一些研究。。。
我发现Net::FTP查找一个名为SOCKSSocket
的类,我为它找到了这些文档。但我不能包含它。include 'socket'
返回false,我很确定这意味着它已经加载了。
您可以将socksfy gem与例如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
这是我对这个问题的看法。锅炉板:
# 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
现在,在您的实际应用程序中,您只需执行以下操作:
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指出了正确的方向。
您可以使用Proximo包装器通过Proximo转发流量。以下是官方说明:https://devcenter.heroku.com/articles/proximo#forwarding-通过proxymo 的流量