From de800735c2488319cecec8560524e14c299a9ecb Mon Sep 17 00:00:00 2001 From: akr Date: Sat, 19 Feb 2005 15:53:43 +0000 Subject: * lib/open-uri.rb (URI::FTP#buffer_open): access mechanism re-implemented according to RFC 1738. reported by Guillaume Marcais. [ruby-talk:131650] git-svn-id: http://svn.ruby-lang.org/repos/ruby/branches/ruby_1_8@8003 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/open-uri.rb | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/open-uri.rb b/lib/open-uri.rb index db35a5c15..f33dc3890 100644 --- a/lib/open-uri.rb +++ b/lib/open-uri.rb @@ -634,17 +634,46 @@ module URI return end require 'net/ftp' + + directories = self.path.split(%r{/}, -1) + directories.shift if directories[0] == '' # strip a field before leading slash + directories.each {|d| + d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") } + } + unless filename = directories.pop + raise ArgumentError, "no filename: #{self.inspect}" + end + directories.each {|d| + if /[\r\n]/ =~ d + raise ArgumentError, "invalid directory: #{d.inspect}" + end + } + if /[\r\n]/ =~ filename + raise ArgumentError, "invalid filename: #{filename.inspect}" + end + typecode = self.typecode + if typecode && /\A[aid]\z/ !~ typecode + raise ArgumentError, "invalid typecode: #{typecode.inspect}" + end + + # The access sequence is defined by RFC 1738 + ftp = Net::FTP.open(self.host) # todo: extract user/passwd from .netrc. user = 'anonymous' passwd = nil user, passwd = self.userinfo.split(/:/) if self.userinfo - - ftp = Net::FTP.open(self.host) ftp.login(user, passwd) + directories.each {|cwd| + ftp.voidcmd("CWD #{cwd}") + } + if typecode + # xxx: typecode D is not handled. + ftp.voidcmd("TYPE #{typecode.upcase}") + end if options[:content_length_proc] - options[:content_length_proc].call(ftp.size(self.path)) + options[:content_length_proc].call(ftp.size(filename)) end - ftp.getbinaryfile(self.path, '/dev/null', Net::FTP::DEFAULT_BLOCKSIZE) {|str| + ftp.retrbinary("RETR #{filename}", 4096) { |str| buf << str options[:progress_proc].call(buf.size) if options[:progress_proc] } -- cgit