@@ -20,8 +20,8 @@ def add_file(pems)
2020 end
2121 end
2222 end
23- # since open-uri internally checks ssl_ca_cert by File.directory?, to allow
24- # accept an array.
23+ # since open-uri internally checks ssl_ca_cert using File.directory?,
24+ # allow to accept an array.
2525 class <<File
2626 alias orig_directory? directory?
2727 def File . directory? files
@@ -31,48 +31,53 @@ def File.directory? files
3131end
3232
3333class Downloader
34+ def self . https = ( https )
35+ @@https = https
36+ end
37+
38+ def self . https?
39+ @@https == 'https'
40+ end
41+
3442 def self . https
35- if @@https != 'https'
36- warn "*** using http instead of https ***"
37- end
3843 @@https
3944 end
4045
4146 class GNU < self
4247 def self . download ( name , *rest )
43- if https == 'https'
48+ if https?
4449 super ( "https://raw.githubusercontent.com/gcc-mirror/gcc/master/#{ name } " , name , *rest )
4550 else
46- super ( "http ://repo.or.cz/official-gcc.git/blob_plain/HEAD:/#{ name } " , name , *rest )
51+ super ( "https ://repo.or.cz/official-gcc.git/blob_plain/HEAD:/#{ name } " , name , *rest )
4752 end
4853 end
4954 end
5055
5156 class RubyGems < self
52- def self . download ( name , dir = nil , ims = true , options = { } )
57+ def self . download ( name , dir = nil , since = true , options = { } )
5358 require 'rubygems'
5459 require 'rubygems/package'
55- options [ :ssl_ca_cert ] = Dir . glob ( File . expand_path ( "../lib/rubygems/ssl_certs/*.pem" , File . dirname ( __FILE__ ) ) )
60+ verify = options . delete ( :verify ) { Gem ::VERSION >= "2.4." }
61+ options [ :ssl_ca_cert ] = Dir . glob ( File . expand_path ( "../lib/rubygems/ssl_certs/**/*.pem" , File . dirname ( __FILE__ ) ) )
5662 file = under ( dir , name )
57- super ( "#{ https } ://rubygems.org/downloads/#{ name } " , file , nil , ims , options ) or
63+ super ( "https://rubygems.org/downloads/#{ name } " , file , nil , since , options ) or
5864 return false
65+ return true unless verify
5966 policy = Gem ::Security ::LowSecurity
6067 ( policy = policy . dup ) . ui = Gem ::SilentUI . new if policy . respond_to? ( :'ui=' )
6168 pkg = Gem ::Package . new ( file )
6269 pkg . security_policy = policy
6370 begin
71+ $stdout. puts "verifying #{ name } "
6472 pkg . verify
6573 rescue Gem ::Security ::Exception => e
66- $stderr. puts e . message
74+ $stderr. puts " #{ name } : #{ e . message } "
6775 File . unlink ( file )
6876 false
6977 else
7078 true
7179 end
7280 end
73-
74- def self . verify ( pkg )
75- end
7681 end
7782
7883 Gems = RubyGems
@@ -104,50 +109,68 @@ def self.http_options(file, since)
104109 options
105110 end
106111
107- # Downloader.download(url, name, [dir, [ims ]])
112+ # Downloader.download(url, name, [dir, [since ]])
108113 #
109114 # Update a file from url if newer version is available.
110115 # Creates the file if the file doesn't yet exist; however, the
111116 # directory where the file is being created has to exist already.
112- # If +ims+ is false, always download url regardless of its last
113- # modified time.
117+ # The +since+ parameter can take the following values, with associated meanings:
118+ # true ::
119+ # Take the last-modified time of the current file on disk, and only download
120+ # if the server has a file that was modified later. Download unconditionally
121+ # if we don't have the file yet. Default.
122+ # +some time value+ ::
123+ # Use this time value instead of the time of modification of the file on disk.
124+ # nil ::
125+ # Only download the file if it doesn't exist yet.
126+ # false ::
127+ # always download url regardless of whether we already have a file,
128+ # and regardless of modification times. (This is essentially just a waste of
129+ # network resources, except in the case that the file we have is somehow damaged.
130+ # Please note that using this recurringly might create or be seen as a
131+ # denial of service attack.)
114132 #
115133 # Example usage:
116134 # download 'http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt',
117135 # 'UnicodeData.txt', 'enc/unicode/data'
118- def self . download ( url , name , dir = nil , ims = true , options = { } )
136+ def self . download ( url , name , dir = nil , since = true , options = { } )
137+ options . delete ( :verify )
119138 file = under ( dir , name )
120- if ims . nil? and File . exist? ( file )
139+ if since . nil? and File . exist? ( file )
121140 if $VERBOSE
122141 $stdout. puts "#{ name } already exists"
123142 $stdout. flush
124143 end
125144 return true
126145 end
146+ if !https? and url . start_with? ( "https:" )
147+ warn "*** using http instead of https ***"
148+ url = url . sub ( /\A https/ , 'http' )
149+ end
127150 url = URI ( url )
128151 if $VERBOSE
129152 $stdout. print "downloading #{ name } ... "
130153 $stdout. flush
131154 end
132155 begin
133- data = url . read ( options . merge ( http_options ( file , ims . nil? ? true : ims ) ) )
156+ data = url . read ( options . merge ( http_options ( file , since . nil? ? true : since ) ) )
134157 rescue OpenURI ::HTTPError => http_error
135158 if http_error . message =~ /^304 / # 304 Not Modified
136159 if $VERBOSE
137- $stdout. puts "not modified"
160+ $stdout. puts "#{ name } not modified"
138161 $stdout. flush
139162 end
140163 return true
141164 end
142165 raise
143166 rescue Timeout ::Error
144- if ims . nil? and File . exist? ( file )
167+ if since . nil? and File . exist? ( file )
145168 puts "Request for #{ url } timed out, using old version."
146169 return true
147170 end
148171 raise
149172 rescue SocketError
150- if ims . nil? and File . exist? ( file )
173+ if since . nil? and File . exist? ( file )
151174 puts "No network connection, unable to download #{ url } , using old version."
152175 return true
153176 end
@@ -172,24 +195,36 @@ def self.download(url, name, dir = nil, ims = true, options = {})
172195 raise "failed to download #{ name } \n #{ e . message } : #{ url } "
173196 end
174197
198+ def self . verify ( file )
199+ true
200+ end
201+
175202 def self . under ( dir , name )
176203 dir ? File . join ( dir , File . basename ( name ) ) : name
177204 end
178205end
179206
180- Downloader . class_variable_set ( :@@ https, https . freeze )
207+ Downloader . https = https . freeze
181208
182209if $0 == __FILE__
183- ims = true
210+ since = true
211+ options = { }
184212 until ARGV . empty?
185213 case ARGV [ 0 ]
186214 when '-d'
187215 destdir = ARGV [ 1 ]
188216 ARGV . shift
217+ when '-p'
218+ # strip directory names from the name to download, and add the
219+ # prefix instead.
220+ prefix = ARGV [ 1 ]
221+ ARGV . shift
189222 when '-e'
190- ims = nil
223+ since = nil
191224 when '-a'
192- ims = true
225+ since = false
226+ when '-V'
227+ options [ :verify ] = true
193228 when /\A -/
194229 abort "#{ $0} : unknown option #{ ARGV [ 0 ] } "
195230 else
@@ -205,10 +240,11 @@ def self.under(dir, name)
205240 dl = Downloader . const_get ( dl )
206241 ARGV . shift
207242 ARGV . each do |name |
208- dl . download ( name , destdir , ims )
243+ name = "#{ prefix } /#{ File . basename ( name ) } " if prefix
244+ dl . download ( name , destdir , since , options )
209245 end
210246 else
211247 abort "usage: #{ $0} url name" unless ARGV . size == 2
212- Downloader . download ( ARGV [ 0 ] , ARGV [ 1 ] , destdir , ims )
248+ Downloader . download ( ARGV [ 0 ] , ARGV [ 1 ] , destdir , since , options )
213249 end
214250end
0 commit comments