Merge branch '1.4.x' into 14x-merge
[puppet-modules/puppetlabs-apt.git] / lib / puppet_x / apt_key / patch_openuri.rb
1 require 'uri'
2 require 'stringio'
3 require 'time'
4
5 module URI
6   class FTP
7     def buffer_open(buf, proxy, options) # :nodoc:
8       if proxy
9         OpenURI.open_http(buf, self, proxy, options)
10         return
11       end
12       require 'net/ftp'
13
14       directories = self.path.split(%r{/}, -1)
15       directories.shift if directories[0] == '' # strip a field before leading slash
16       directories.each {|d|
17         d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") }
18       }
19       unless filename = directories.pop
20         raise ArgumentError, "no filename: #{self.inspect}"
21       end
22       directories.each {|d|
23         if /[\r\n]/ =~ d
24           raise ArgumentError, "invalid directory: #{d.inspect}"
25         end
26       }
27       if /[\r\n]/ =~ filename
28         raise ArgumentError, "invalid filename: #{filename.inspect}"
29       end
30       typecode = self.typecode
31       if typecode && /\A[aid]\z/ !~ typecode
32         raise ArgumentError, "invalid typecode: #{typecode.inspect}"
33       end
34
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.
39       user = 'anonymous'
40       passwd = nil
41       user, passwd = self.userinfo.split(/:/) if self.userinfo
42       ftp.login(user, passwd)
43       directories.each {|cwd|
44         ftp.voidcmd("CWD #{cwd}")
45       }
46       if typecode
47         # xxx: typecode D is not handled.
48         ftp.voidcmd("TYPE #{typecode.upcase}")
49       end
50       if options[:content_length_proc]
51         options[:content_length_proc].call(ftp.size(filename))
52       end
53       ftp.retrbinary("RETR #{filename}", 4096) { |str|
54         buf << str
55         options[:progress_proc].call(buf.size) if options[:progress_proc]
56       }
57       ftp.close
58       buf.io.rewind
59     end
60
61     include OpenURI::OpenRead
62   end
63 end