7 def buffer_open(buf, proxy, options) # :nodoc:
9 OpenURI.open_http(buf, self, proxy, options)
14 directories = self.path.split(%r{/}, -1)
15 directories.shift if directories[0] == '' # strip a field before leading slash
17 d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
19 unless filename = directories.pop
20 raise ArgumentError, "no filename: #{self.inspect}"
24 raise ArgumentError, "invalid directory: #{d.inspect}"
27 if /[\r\n]/ =~ filename
28 raise ArgumentError, "invalid filename: #{filename.inspect}"
30 typecode = self.typecode
31 if typecode && /\A[aid]\z/ !~ typecode
32 raise ArgumentError, "invalid typecode: #{typecode.inspect}"
35 # The access sequence is defined by RFC 1738
36 ftp = Net::FTP.open(self.host)
37 ftp.passive = true if !options[:ftp_active_mode]
38 # todo: extract user/passwd from .netrc.
41 user, passwd = self.userinfo.split(/:/) if self.userinfo
42 ftp.login(user, passwd)
43 directories.each {|cwd|
44 ftp.voidcmd("CWD #{cwd}")
47 # xxx: typecode D is not handled.
48 ftp.voidcmd("TYPE #{typecode.upcase}")
50 if options[:content_length_proc]
51 options[:content_length_proc].call(ftp.size(filename))
53 ftp.retrbinary("RETR #{filename}", 4096) { |str|
55 options[:progress_proc].call(buf.size) if options[:progress_proc]
61 include OpenURI::OpenRead