class Net::FTP
此类实现了文件传输协议。如果您使用过命令行 FTP
程序,并且熟悉这些命令,您将能够轻松使用此类。其中包含一些额外的功能,以利用 Ruby 的风格和优势。
示例¶ ↑
require 'net/ftp'
示例 1¶ ↑
ftp = Net::FTP.new('example.com') ftp.login files = ftp.chdir('pub/lang/ruby/contrib') files = ftp.list('n*') ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024) ftp.close
示例 2¶ ↑
Net::FTP.open('example.com') do |ftp| ftp.login files = ftp.chdir('pub/lang/ruby/contrib') files = ftp.list('n*') ftp.getbinaryfile('nif.rb-0.91.gz', 'nif.gz', 1024) end
主要方法¶ ↑
以下是用户最可能使用的方法
大型机用户支持¶ ↑
常量
- CASE_DEPENDENT_PARSER
- CASE_INDEPENDENT_PARSER
- DECIMAL_PARSER
- FACT_PARSERS
- OCTAL_PARSER
- TIME_PARSER
属性
当 true
时,传输以二进制模式执行。默认值:true
。
当 true
时,所有与服务器的流量都会写入 +$stdout+。默认值:false
。
设置或检索调试的输出流。仅当 debug_mode
设置为 true 时才使用输出流。默认值是 +$stdout+。
服务器的最后响应。
服务器的最后响应代码。
服务器的最后响应代码。
等待连接打开的秒数。可以使用任何数字,包括小数秒的浮点数。如果 FTP
对象无法在此秒数内打开连接,则会引发 Net::OpenTimeout 异常。默认值为 nil
。
当 true
时,连接处于被动模式。默认值:true
。
等待读取一个数据块(通过一个 read(2) 调用)的秒数。可以使用任何数字,包括小数秒的浮点数。如果 FTP
对象无法在此秒数内读取数据,则会引发 Timeout::Error 异常。默认值为 60 秒。
设置或检索 resume
状态,该状态决定是否恢复或重新启动未完成的传输。默认值:false
。
等待 TLS 握手的秒数。可以使用任何数字,包括小数秒的浮点数。如果 FTP
对象无法在此秒数内完成 TLS 握手,则会引发 Net::OpenTimeout 异常。默认值为 nil
。如果 ssl_handshake_timeout
为 nil
,则改用 open_timeout
。
当 true
时,使用 PASV 响应中的 IP 地址。否则,它使用与控制连接相同的 IP 地址。默认值:false
。
服务器的欢迎消息。
公共类方法
当 true
时,默认情况下连接处于被动模式。默认值:true
。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 165 def self.default_passive @@default_passive end
当 true
时,默认情况下连接处于被动模式。默认值:true
。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 159 def self.default_passive=(value) @@default_passive = value end
创建并返回一个新的 FTP
对象。如果给定 host
,则建立连接。
options
是一个选项哈希,每个键都是一个符号。
可用的选项有
- port
-
端口号(默认值为 21)
- ssl
-
如果
options
[:ssl] 为 true,则将尝试使用 SSL(现在是 TLS)连接到服务器。为此,需要安装 OpenSSL [OSSL] 和 Ruby OpenSSL [RSSL] 扩展。如果options
[:ssl] 是一个哈希,则将其作为参数传递给 OpenSSL::SSL::SSLContext#set_params。 - private_data_connection
-
如果为 true,则数据连接使用 TLS。默认值:当
options
[:ssl] 为 true 时为true
。 - implicit_ftps
-
如果为 true,则在初始连接上建立 TLS。默认值:
false
- username
-
登录的用户名。如果
options
[:username] 是字符串“anonymous”,并且options
[:password] 为nil
,则使用“anonymous@”作为密码。 - password
-
登录的密码。
- account
-
ACCT 的帐户信息。
- passive
-
当
true
时,连接处于被动模式。默认值:true
。 open_timeout
-
等待连接打开的秒数。有关详细信息,请参阅
Net::FTP#open_timeout
。默认值:nil
。 read_timeout
-
等待读取一个数据块的秒数。有关详细信息,请参阅
Net::FTP#read_timeout
。默认值:60
。 ssl_handshake_timeout
-
等待 TLS 握手的秒数。有关详细信息,请参阅
Net::FTP#ssl_handshake_timeout
。默认值:nil
。 use_pasv_ip
-
当
true
时,使用 PASV 响应中的 IP 地址。否则,它使用与控制连接相同的 IP 地址。默认值:false
。 debug_mode
-
当
true
时,所有与服务器的流量都会写入 +$stdout+。默认值:false
。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 230 def initialize(host = nil, user_or_options = {}, passwd = nil, acct = nil) super() begin options = user_or_options.to_hash rescue NoMethodError # for backward compatibility options = {} options[:username] = user_or_options options[:password] = passwd options[:account] = acct end @host = nil if options[:ssl] unless defined?(OpenSSL::SSL) raise "SSL extension not installed" end ssl_params = options[:ssl] == true ? {} : options[:ssl] @ssl_context = SSLContext.new @ssl_context.set_params(ssl_params) if defined?(VerifyCallbackProc) @ssl_context.verify_callback = VerifyCallbackProc end # jruby-openssl does not support session caching unless RUBY_ENGINE == "jruby" @ssl_context.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT | OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess } end @ssl_session = nil if options[:private_data_connection].nil? @private_data_connection = true else @private_data_connection = options[:private_data_connection] end if options[:implicit_ftps].nil? @implicit_ftps = false else @implicit_ftps = options[:implicit_ftps] end else @ssl_context = nil if options[:private_data_connection] raise ArgumentError, "private_data_connection can be set to true only when ssl is enabled" end @private_data_connection = false if options[:implicit_ftps] raise ArgumentError, "implicit_ftps can be set to true only when ssl is enabled" end @implicit_ftps = false end @binary = true if options[:passive].nil? @passive = @@default_passive else @passive = options[:passive] end if options[:debug_mode].nil? @debug_mode = false else @debug_mode = options[:debug_mode] end @debug_output = $stdout @resume = false @bare_sock = @sock = NullSocket.new @logged_in = false @open_timeout = options[:open_timeout] @ssl_handshake_timeout = options[:ssl_handshake_timeout] @read_timeout = options[:read_timeout] || 60 @use_pasv_ip = options[:use_pasv_ip] || false if host connect(host, options[:port] || FTP_PORT) if options[:username] login(options[:username], options[:password], options[:account]) end end end
FTP.new
的同义词,但带有强制性的主机参数。
如果给定了块,则会将 FTP
对象传递给该块,该对象将在块完成或引发异常时关闭。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 175 def FTP.open(host, *args) if block_given? ftp = new(host, *args) begin yield ftp ensure ftp.close end else new(host, *args) end end
公共实例方法
中止上一个命令(ABOR 命令)。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1283 def abort line = "ABOR" + CRLF debug_print "put: ABOR" @sock.send(line, Socket::MSG_OOB) resp = getmultiline unless ["426", "226", "225"].include?(resp[0, 3]) raise FTPProtoError, resp end return resp end
发送 ACCT 命令。
这是一个不太常见的 FTP
命令,用于在目标主机需要时发送帐户信息。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 925 def acct(account) cmd = "ACCT " + account voidcmd(cmd) end
用于切换二进制模式传输的 setter。newmode
为 true
或 false
# File net-ftp-0.3.8/lib/net/ftp.rb, line 314 def binary=(newmode) if newmode != @binary @binary = newmode send_type_command if @logged_in end end
更改(远程)目录。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1194 def chdir(dirname) if dirname == ".." begin voidcmd("CDUP") return rescue FTPPermError => e if e.message[0, 3] != "500" raise e end end end cmd = "CWD #{dirname}" voidcmd(cmd) end
关闭连接。除非使用 connect
打开新连接,否则无法进行进一步的操作。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1397 def close if @sock and not @sock.closed? begin @sock.shutdown(Socket::SHUT_WR) rescue nil orig, self.read_timeout = self.read_timeout, 3 @sock.read rescue nil ensure @sock.close self.read_timeout = orig end end end
当且仅当连接关闭时返回 true
。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1413 def closed? @sock == nil or @sock.closed? end
建立与主机的 FTP
连接,可以选择覆盖默认端口。如果设置了环境变量 SOCKS_SERVER
,则通过 SOCKS 代理建立连接。如果无法建立连接,则会引发异常(通常为 Errno::ECONNREFUSED
)。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 402 def connect(host, port = FTP_PORT) debug_print "connect: #{host}:#{port}" synchronize do @host = host @bare_sock = open_socket(host, port) if @ssl_context begin unless @implicit_ftps set_socket(BufferedSocket.new(@bare_sock, read_timeout: @read_timeout)) voidcmd("AUTH TLS") end set_socket(BufferedSSLSocket.new(start_tls_session(@bare_sock), read_timeout: @read_timeout), @implicit_ftps) if @private_data_connection voidcmd("PBSZ 0") voidcmd("PROT P") end rescue OpenSSL::SSL::SSLError, OpenTimeout @sock.close raise end else set_socket(BufferedSocket.new(@bare_sock, read_timeout: @read_timeout)) end end end
将调试消息写入调试输出流
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1488 def debug_print(msg) @debug_output << msg + "\n" if @debug_mode && @debug_output end
删除服务器上的文件。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1180 def delete(filename) resp = sendcmd("DELE #{filename}") if resp.start_with?("250") return elsif resp.start_with?("5") raise FTPPermError, resp else raise FTPReplyError, resp end end
发出 FEAT 命令
返回一个支持的可选功能数组
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1363 def features resp = sendcmd("FEAT") if !resp.start_with?("211") raise FTPReplyError, resp end feats = [] resp.each_line do |line| next if !line.start_with?(' ') # skip status lines feats << line.strip end return feats end
以会话设置的任何模式(文本或二进制)检索 remotefile
。请参阅 gettextfile
和 getbinaryfile
。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 849 def get(remotefile, localfile = File.basename(remotefile), blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data if @binary getbinaryfile(remotefile, localfile, blocksize, &block) else gettextfile(remotefile, localfile, &block) end end
以二进制模式检索 remotefile
,并将结果存储在 localfile
中。如果 localfile
为 nil,则返回检索到的数据。如果提供了块,则会将检索到的数据以 blocksize
块传递给它。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 788 def getbinaryfile(remotefile, localfile = File.basename(remotefile), blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data f = nil result = nil if localfile if @resume rest_offset = File.size?(localfile) f = File.open(localfile, "a") else rest_offset = nil f = File.open(localfile, "w") end elsif !block_given? result = String.new end begin f&.binmode retrbinary("RETR #{remotefile}", blocksize, rest_offset) do |data| f&.write(data) block&.(data) result&.concat(data) end return result ensure f&.close end end
以 ASCII (文本) 模式检索 remotefile
,并将结果存储在 localfile
中。如果 localfile
为 nil,则返回检索到的数据。如果提供了块,则会将检索到的数据逐行传递给该块。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 823 def gettextfile(remotefile, localfile = File.basename(remotefile), &block) # :yield: line f = nil result = nil if localfile f = File.open(localfile, "w") elsif !block_given? result = String.new end begin retrlines("RETR #{remotefile}") do |line, newline| l = newline ? line + "\n" : line f&.print(l) block&.(line, newline) result&.concat(l) end return result ensure f&.close end end
发出 HELP 命令。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1326 def help(arg = nil) cmd = "HELP" if arg cmd = cmd + " " + arg end sendcmd(cmd) end
返回目录中文件信息的数组(输出类似于 “ls -l”)。如果提供了块,则会遍历列表。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 949 def list(*args, &block) # :yield: line cmd = "LIST" args.each do |arg| cmd = "#{cmd} #{arg}" end lines = [] retrlines(cmd) do |line| lines << line end if block lines.each(&block) end return lines end
登录到远程主机。会话必须事先已连接。如果 user
是字符串 “anonymous” 且 password
为 nil
,则使用 “anonymous@” 作为密码。如果 acct
参数不为 nil
,则在成功登录后发送 FTP
ACCT 命令。如果发生错误,则会引发异常(通常为 Net::FTPPermError
)。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 635 def login(user = "anonymous", passwd = nil, acct = nil) if user == "anonymous" and passwd == nil passwd = "anonymous@" end resp = "" synchronize do resp = sendcmd('USER ' + user) if resp.start_with?("3") raise FTPReplyError, resp if passwd.nil? resp = sendcmd('PASS ' + passwd) end if resp.start_with?("3") raise FTPReplyError, resp if acct.nil? resp = sendcmd('ACCT ' + acct) end end if !resp.start_with?("2") raise FTPReplyError, resp end @welcome = resp send_type_command @logged_in = true end
以 “YYYYMMDDhhmmss” 格式返回(远程)文件的原始最后修改时间 (MDTM 命令)。
如果想要解析的 Time 实例,请使用 mtime
。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1316 def mdtm(filename) resp = sendcmd("MDTM #{filename}") if resp.start_with?("213") return get_body(resp) end end
创建一个远程目录。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1238 def mkdir(dirname) resp = sendcmd("MKD #{dirname}") return parse257(resp) end
返回由 pathname
指定的目录的条目数组。每个条目都有事实信息(例如,大小、最后修改时间等)和路径名。如果提供了块,则会遍历列表。如果省略 pathname
,则假定为当前目录。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1154 def mlsd(pathname = nil, &block) # :yield: entry cmd = pathname ? "MLSD #{pathname}" : "MLSD" entries = [] retrlines(cmd) do |line| entries << parse_mlsx_entry(line) end if block entries.each(&block) end return entries end
返回有关由 pathname
指定的文件或目录的数据(例如,大小、最后修改时间、条目类型等)。如果省略 pathname
,则假定为当前目录。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1132 def mlst(pathname = nil) cmd = pathname ? "MLST #{pathname}" : "MLST" resp = sendcmd(cmd) if !resp.start_with?("250") raise FTPReplyError, resp end line = resp.lines[1] unless line raise FTPProtoError, resp end entry = line.sub(/\A(250-| *)/, "") return parse_mlsx_entry(entry) end
返回(远程)文件的最后修改时间。如果 local
为 true
,则返回本地时间,否则返回 UTC 时间。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1231 def mtime(filename, local = false) return TIME_PARSER.(mdtm(filename), local) end
返回远程目录中文件名的数组。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 933 def nlst(dir = nil) cmd = "NLST" if dir cmd = "#{cmd} #{dir}" end files = [] retrlines(cmd) do |line| files.push(line) end return files end
发出 NOOP 命令。
除了返回响应之外,不做任何操作。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1346 def noop voidcmd("NOOP") end
发出 OPTS 命令
-
name 应该是要设置的选项的名称
-
params 是要与选项一起提供的任何可选参数
示例: option(‘UTF8’, ‘ON’) => ‘OPTS UTF8 ON’
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1386 def option(name, params = nil) cmd = "OPTS #{name}" cmd += " #{params}" if params voidcmd(cmd) end
以会话设置的任何模式(文本或二进制)将 localfile
传输到服务器。请参阅 puttextfile
和 putbinaryfile
。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 910 def put(localfile, remotefile = File.basename(localfile), blocksize = DEFAULT_BLOCKSIZE, &block) if @binary putbinaryfile(localfile, remotefile, blocksize, &block) else puttextfile(localfile, remotefile, &block) end end
以二进制模式将 localfile
传输到服务器,并将结果存储在 remotefile
中。如果提供了块,则会调用它,并以 blocksize
大小的块传入传输的数据。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 863 def putbinaryfile(localfile, remotefile = File.basename(localfile), blocksize = DEFAULT_BLOCKSIZE, &block) # :yield: data if @resume begin rest_offset = size(remotefile) rescue Net::FTPPermError rest_offset = nil end else rest_offset = nil end f = File.open(localfile) begin f.binmode if rest_offset storbinary("APPE #{remotefile}", f, blocksize, rest_offset, &block) else storbinary("STOR #{remotefile}", f, blocksize, rest_offset, &block) end ensure f.close end end
以 ASCII (文本) 模式将 localfile
传输到服务器,并将结果存储在 remotefile
中。如果提供了回调或关联的块,则会调用它,并逐行传入传输的数据。
返回响应,如果用户在发出 “quote site filetype=jes” 后以 ASCII 模式与大型机通信,则该响应将包含一个作业号。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 895 def puttextfile(localfile, remotefile = File.basename(localfile), &block) # :yield: line f = File.open(localfile) response = '' begin response = storlines("STOR #{remotefile}", f, &block) ensure f.close end response end
返回当前远程目录。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1263 def pwd resp = sendcmd("PWD") return parse257(resp) end
退出 FTP
会话。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1337 def quit voidcmd("QUIT") end
“quote” 子命令将参数逐字发送到远程 ftp 服务器。“literal” 子命令是 “quote” 的别名。@param arguments 要逐字发送到远程 ftp 服务器的 Array
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1248 def quote(arguments) sendcmd(arguments) end
设置 read_timeout
属性。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 142 def read_timeout=(sec) @sock.read_timeout = sec @read_timeout = sec end
重命名服务器上的文件。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1169 def rename(fromname, toname) resp = sendcmd("RNFR #{fromname}") if !resp.start_with?("3") raise FTPReplyError, resp end voidcmd("RNTO #{toname}") end
将连接置于二进制(图像)模式,发出给定的命令,并获取返回的数据,以 blocksize
字符的块将其传递给关联的块。请注意,cmd
是服务器命令(例如 “RETR myfile”)。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 666 def retrbinary(cmd, blocksize, rest_offset = nil) # :yield: data synchronize do with_binary(true) do begin conn = transfercmd(cmd, rest_offset) while data = conn.read(blocksize) yield(data) end conn.shutdown(Socket::SHUT_WR) rescue nil conn.read_timeout = 1 conn.read rescue nil ensure conn.close if conn end voidresp end end end
将连接置于 ASCII (文本) 模式,发出给定的命令,并将结果数据逐行传递给关联的块。如果没有提供块,则会打印这些行。请注意,cmd
是服务器命令(例如 “RETR myfile”)。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 691 def retrlines(cmd) # :yield: line synchronize do with_binary(false) do begin conn = transfercmd(cmd) while line = conn.gets yield(line.sub(/\r?\n\z/, ""), !line.match(/\n\z/).nil?) end conn.shutdown(Socket::SHUT_WR) rescue nil conn.read_timeout = 1 conn.read rescue nil ensure conn.close if conn end voidresp end end end
删除一个远程目录。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1256 def rmdir(dirname) voidcmd("RMD #{dirname}") end
发送命令并返回响应。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 523 def sendcmd(cmd) synchronize do putline(cmd) return getresp end end
设置用于连接到 FTP
服务器的套接字。
如果 get_greeting
为 false,则可能会引发 FTPReplyError。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 432 def set_socket(sock, get_greeting = true) synchronize do @sock = sock if get_greeting voidresp end end end
发出 SITE 命令。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1353 def site(arg) cmd = "SITE " + arg voidcmd(cmd) end
返回给定(远程)文件的大小。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1217 def size(filename) with_binary(true) do resp = sendcmd("SIZE #{filename}") if !resp.start_with?("213") raise FTPReplyError, resp end return get_body(resp).to_i end end
返回状态 (STAT 命令)。
- pathname
-
当使用 pathname 作为参数调用 stat 时,它的行为类似于 list,但速度更快,并且在相同的 tcp 会话中进行。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1300 def status(pathname = nil) line = pathname ? "STAT #{pathname}" : "STAT" if /[\r\n]/ =~ line raise ArgumentError, "A line must not contain CR or LF" end debug_print "put: #{line}" @sock.send(line + CRLF, Socket::MSG_OOB) return getresp end
将连接置于二进制(图像)模式,发出给定的服务器端命令(例如 “STOR myfile”),并将名为 file
的文件的内容发送到服务器。如果提供了可选的块,它还会以 blocksize
字符的块将其传递给该块。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 716 def storbinary(cmd, file, blocksize, rest_offset = nil) # :yield: data if rest_offset file.seek(rest_offset, IO::SEEK_SET) end synchronize do with_binary(true) do begin conn = transfercmd(cmd) while buf = file.read(blocksize) conn.write(buf) yield(buf) if block_given? end conn.shutdown(Socket::SHUT_WR) rescue nil conn.read_timeout = 1 conn.read rescue nil ensure conn.close if conn end voidresp end end rescue Errno::EPIPE # EPIPE, in this case, means that the data connection was unexpectedly # terminated. Rather than just raising EPIPE to the caller, check the # response on the control connection. If getresp doesn't raise a more # appropriate exception, re-raise the original exception. getresp raise end
将连接置于 ASCII (文本) 模式,发出给定的服务器端命令(例如 “STOR myfile”),并将名为 file
的文件的内容逐行发送到服务器。如果提供了可选的块,则还会将行传递给该块。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 752 def storlines(cmd, file) # :yield: line synchronize do with_binary(false) do begin conn = transfercmd(cmd) while buf = file.gets if buf[-2, 2] != CRLF buf = buf.chomp + CRLF end conn.write(buf) yield(buf) if block_given? end conn.shutdown(Socket::SHUT_WR) rescue nil conn.read_timeout = 1 conn.read rescue nil ensure conn.close if conn end getresp # The response might be important when connected to a mainframe end end rescue Errno::EPIPE # EPIPE, in this case, means that the data connection was unexpectedly # terminated. Rather than just raising EPIPE to the caller, check the # response on the control connection. If getresp doesn't raise a more # appropriate exception, re-raise the original exception. getresp raise end
返回系统信息。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1272 def system resp = sendcmd("SYST") if !resp.start_with?("215") raise FTPReplyError, resp end return get_body(resp) end
发送命令并期望响应以 “2” 开头。
# File net-ftp-0.3.8/lib/net/ftp.rb, line 533 def voidcmd(cmd) synchronize do putline(cmd) voidresp end end
私有实例方法
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1112 def parse_mlsx_entry(entry) facts, pathname = entry.chomp.split(/ /, 2) unless pathname raise FTPProtoError, entry end return MLSxEntry.new( facts.scan(/(.*?)=(.*?);/).each_with_object({}) { |(factname, value), h| name = factname.downcase h[name] = FACT_PARSERS[name].(value) }, pathname) end
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1438 def parse_pasv_ipv4_host(s) return s.tr(",", ".") end
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1443 def parse_pasv_ipv6_host(s) return s.split(/,/).map { |i| "%02x" % i.to_i }.each_slice(2).map(&:join).join(":") end
# File net-ftp-0.3.8/lib/net/ftp.rb, line 1450 def parse_pasv_port(s) return s.split(/,/).map(&:to_i).inject { |x, y| (x << 8) + y } end
# File net-ftp-0.3.8/lib/net/ftp.rb, line 379 def start_tls_session(sock) ssl_sock = SSLSocket.new(sock, @ssl_context) ssl_sock.sync_close = true ssl_sock.hostname = @host if ssl_sock.respond_to? :hostname= if @ssl_session && Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout # ProFTPD returns 425 for data connections if session is not reused. ssl_sock.session = @ssl_session end ssl_socket_connect(ssl_sock, @ssl_handshake_timeout || @open_timeout) if @ssl_context.verify_mode != VERIFY_NONE ssl_sock.post_connection_check(@host) end return ssl_sock end