PageRenderTime 52ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/gatk3_haplotype_caller_swift/ruby/1.9.3-p488/lib/ruby/1.9.1/rubygems/remote_fetcher.rb

https://gitlab.com/pooja043/Globus_Docker_3
Ruby | 507 lines | 323 code | 122 blank | 62 comment | 45 complexity | 5602b2aca4a021349c8ef2ac8a73ad30 MD5 | raw file
  1. require 'rubygems'
  2. require 'rubygems/user_interaction'
  3. require 'uri'
  4. ##
  5. # RemoteFetcher handles the details of fetching gems and gem information from
  6. # a remote source.
  7. class Gem::RemoteFetcher
  8. BuiltinSSLCerts = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__))
  9. include Gem::UserInteraction
  10. ##
  11. # A FetchError exception wraps up the various possible IO and HTTP failures
  12. # that could happen while downloading from the internet.
  13. class FetchError < Gem::Exception
  14. ##
  15. # The URI which was being accessed when the exception happened.
  16. attr_accessor :uri
  17. def initialize(message, uri)
  18. super message
  19. @uri = uri
  20. end
  21. def to_s # :nodoc:
  22. "#{super} (#{uri})"
  23. end
  24. end
  25. @fetcher = nil
  26. ##
  27. # Cached RemoteFetcher instance.
  28. def self.fetcher
  29. @fetcher ||= self.new Gem.configuration[:http_proxy]
  30. end
  31. ##
  32. # Initialize a remote fetcher using the source URI and possible proxy
  33. # information.
  34. #
  35. # +proxy+
  36. # * [String]: explicit specification of proxy; overrides any environment
  37. # variable setting
  38. # * nil: respect environment variables (HTTP_PROXY, HTTP_PROXY_USER,
  39. # HTTP_PROXY_PASS)
  40. # * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy
  41. def initialize(proxy = nil)
  42. require 'net/http'
  43. require 'stringio'
  44. require 'time'
  45. require 'uri'
  46. Socket.do_not_reverse_lookup = true
  47. @connections = {}
  48. @requests = Hash.new 0
  49. @proxy_uri =
  50. case proxy
  51. when :no_proxy then nil
  52. when nil then get_proxy_from_env
  53. when URI::HTTP then proxy
  54. else URI.parse(proxy)
  55. end
  56. @user_agent = user_agent
  57. end
  58. ##
  59. # Given a name and requirement, downloads this gem into cache and returns the
  60. # filename. Returns nil if the gem cannot be located.
  61. #--
  62. # Should probably be integrated with #download below, but that will be a
  63. # larger, more emcompassing effort. -erikh
  64. def download_to_cache dependency
  65. found = Gem::SpecFetcher.fetcher.fetch dependency, true, true,
  66. dependency.prerelease?
  67. return if found.empty?
  68. spec, source_uri = found.sort_by { |(s,_)| s.version }.last
  69. download spec, source_uri
  70. end
  71. ##
  72. # Moves the gem +spec+ from +source_uri+ to the cache dir unless it is
  73. # already there. If the source_uri is local the gem cache dir copy is
  74. # always replaced.
  75. def download(spec, source_uri, install_dir = Gem.dir)
  76. Gem.ensure_gem_subdirectories(install_dir) rescue nil
  77. if File.writable?(install_dir)
  78. cache_dir = File.join install_dir, "cache"
  79. else
  80. cache_dir = File.join Gem.user_dir, "cache"
  81. end
  82. gem_file_name = File.basename spec.cache_file
  83. local_gem_path = File.join cache_dir, gem_file_name
  84. FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
  85. # Always escape URI's to deal with potential spaces and such
  86. unless URI::Generic === source_uri
  87. source_uri = URI.parse(URI.const_defined?(:DEFAULT_PARSER) ?
  88. URI::DEFAULT_PARSER.escape(source_uri.to_s) :
  89. URI.escape(source_uri.to_s))
  90. end
  91. scheme = source_uri.scheme
  92. # URI.parse gets confused by MS Windows paths with forward slashes.
  93. scheme = nil if scheme =~ /^[a-z]$/i
  94. case scheme
  95. when 'http', 'https' then
  96. unless File.exist? local_gem_path then
  97. begin
  98. say "Downloading gem #{gem_file_name}" if
  99. Gem.configuration.really_verbose
  100. remote_gem_path = source_uri + "gems/#{gem_file_name}"
  101. gem = self.fetch_path remote_gem_path
  102. rescue Gem::RemoteFetcher::FetchError
  103. raise if spec.original_platform == spec.platform
  104. alternate_name = "#{spec.original_name}.gem"
  105. say "Failed, downloading gem #{alternate_name}" if
  106. Gem.configuration.really_verbose
  107. remote_gem_path = source_uri + "gems/#{alternate_name}"
  108. gem = self.fetch_path remote_gem_path
  109. end
  110. File.open local_gem_path, 'wb' do |fp|
  111. fp.write gem
  112. end
  113. end
  114. when 'file' then
  115. begin
  116. path = source_uri.path
  117. path = File.dirname(path) if File.extname(path) == '.gem'
  118. remote_gem_path = correct_for_windows_path(File.join(path, 'gems', gem_file_name))
  119. FileUtils.cp(remote_gem_path, local_gem_path)
  120. rescue Errno::EACCES
  121. local_gem_path = source_uri.to_s
  122. end
  123. say "Using local gem #{local_gem_path}" if
  124. Gem.configuration.really_verbose
  125. when nil then # TODO test for local overriding cache
  126. source_path = if Gem.win_platform? && source_uri.scheme &&
  127. !source_uri.path.include?(':') then
  128. "#{source_uri.scheme}:#{source_uri.path}"
  129. else
  130. source_uri.path
  131. end
  132. source_path = unescape source_path
  133. begin
  134. FileUtils.cp source_path, local_gem_path unless
  135. File.expand_path(source_path) == File.expand_path(local_gem_path)
  136. rescue Errno::EACCES
  137. local_gem_path = source_uri.to_s
  138. end
  139. say "Using local gem #{local_gem_path}" if
  140. Gem.configuration.really_verbose
  141. else
  142. raise Gem::InstallError, "unsupported URI scheme #{source_uri.scheme}"
  143. end
  144. local_gem_path
  145. end
  146. ##
  147. # File Fetcher. Dispatched by +fetch_path+. Use it instead.
  148. def fetch_file uri, *_
  149. Gem.read_binary correct_for_windows_path uri.path
  150. end
  151. ##
  152. # HTTP Fetcher. Dispatched by +fetch_path+. Use it instead.
  153. def fetch_http uri, last_modified = nil, head = false, depth = 0
  154. fetch_type = head ? Net::HTTP::Head : Net::HTTP::Get
  155. response = request uri, fetch_type, last_modified
  156. case response
  157. when Net::HTTPOK, Net::HTTPNotModified then
  158. head ? response : response.body
  159. when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
  160. Net::HTTPTemporaryRedirect then
  161. raise FetchError.new('too many redirects', uri) if depth > 10
  162. location = URI.parse response['Location']
  163. if https?(uri) && !https?(location)
  164. raise FetchError.new("redirecting to non-https resource: #{location}", uri)
  165. end
  166. fetch_http(location, last_modified, head, depth + 1)
  167. else
  168. raise FetchError.new("bad response #{response.message} #{response.code}", uri)
  169. end
  170. end
  171. alias :fetch_https :fetch_http
  172. ##
  173. # Downloads +uri+ and returns it as a String.
  174. def fetch_path(uri, mtime = nil, head = false)
  175. uri = URI.parse uri unless URI::Generic === uri
  176. raise ArgumentError, "bad uri: #{uri}" unless uri
  177. raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}" unless
  178. uri.scheme
  179. data = send "fetch_#{uri.scheme}", uri, mtime, head
  180. data = Gem.gunzip data if data and not head and uri.to_s =~ /gz$/
  181. data
  182. rescue FetchError
  183. raise
  184. rescue Timeout::Error
  185. raise FetchError.new('timed out', uri.to_s)
  186. rescue IOError, SocketError, SystemCallError => e
  187. raise FetchError.new("#{e.class}: #{e}", uri.to_s)
  188. end
  189. ##
  190. # Returns the size of +uri+ in bytes.
  191. def fetch_size(uri) # TODO: phase this out
  192. response = fetch_path(uri, nil, true)
  193. response['content-length'].to_i
  194. end
  195. def escape(str)
  196. return unless str
  197. @uri_parser ||= uri_escaper
  198. @uri_parser.escape str
  199. end
  200. def unescape(str)
  201. return unless str
  202. @uri_parser ||= uri_escaper
  203. @uri_parser.unescape str
  204. end
  205. def uri_escaper
  206. URI::Parser.new
  207. rescue NameError
  208. URI
  209. end
  210. ##
  211. # Returns an HTTP proxy URI if one is set in the environment variables.
  212. def get_proxy_from_env
  213. env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
  214. return nil if env_proxy.nil? or env_proxy.empty?
  215. uri = URI.parse(normalize_uri(env_proxy))
  216. if uri and uri.user.nil? and uri.password.nil? then
  217. # Probably we have http_proxy_* variables?
  218. uri.user = escape(ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER'])
  219. uri.password = escape(ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS'])
  220. end
  221. uri
  222. end
  223. ##
  224. # Normalize the URI by adding "http://" if it is missing.
  225. def normalize_uri(uri)
  226. (uri =~ /^(https?|ftp|file):/) ? uri : "http://#{uri}"
  227. end
  228. ##
  229. # Creates or an HTTP connection based on +uri+, or retrieves an existing
  230. # connection, using a proxy if needed.
  231. def connection_for(uri)
  232. net_http_args = [uri.host, uri.port]
  233. if @proxy_uri then
  234. net_http_args += [
  235. @proxy_uri.host,
  236. @proxy_uri.port,
  237. @proxy_uri.user,
  238. @proxy_uri.password
  239. ]
  240. end
  241. connection_id = [Thread.current.object_id, *net_http_args].join ':'
  242. @connections[connection_id] ||= Net::HTTP.new(*net_http_args)
  243. connection = @connections[connection_id]
  244. if https?(uri) and !connection.started? then
  245. configure_connection_for_https(connection)
  246. end
  247. connection.start unless connection.started?
  248. connection
  249. rescue OpenSSL::SSL::SSLError, Errno::EHOSTDOWN => e
  250. raise FetchError.new(e.message, uri)
  251. end
  252. def configure_connection_for_https(connection)
  253. require 'net/https'
  254. connection.use_ssl = true
  255. connection.verify_mode =
  256. Gem.configuration.ssl_verify_mode || OpenSSL::SSL::VERIFY_PEER
  257. store = OpenSSL::X509::Store.new
  258. if Gem.configuration.ssl_ca_cert
  259. if File.directory? Gem.configuration.ssl_ca_cert
  260. store.add_path Gem.configuration.ssl_ca_cert
  261. else
  262. store.add_file Gem.configuration.ssl_ca_cert
  263. end
  264. else
  265. store.set_default_paths
  266. add_rubygems_trusted_certs(store)
  267. end
  268. connection.cert_store = store
  269. end
  270. def add_rubygems_trusted_certs(store)
  271. Dir.glob(BuiltinSSLCerts).each do |ssl_cert_file|
  272. store.add_file ssl_cert_file
  273. end
  274. end
  275. def correct_for_windows_path(path)
  276. if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
  277. path = path[1..-1]
  278. else
  279. path
  280. end
  281. end
  282. ##
  283. # Read the data from the (source based) URI, but if it is a file:// URI,
  284. # read from the filesystem instead.
  285. def open_uri_or_path(uri, last_modified = nil, head = false, depth = 0)
  286. raise "NO: Use fetch_path instead"
  287. # TODO: deprecate for fetch_path
  288. end
  289. ##
  290. # Performs a Net::HTTP request of type +request_class+ on +uri+ returning
  291. # a Net::HTTP response object. request maintains a table of persistent
  292. # connections to reduce connect overhead.
  293. def request(uri, request_class, last_modified = nil)
  294. request = request_class.new uri.request_uri
  295. unless uri.nil? || uri.user.nil? || uri.user.empty? then
  296. request.basic_auth uri.user, uri.password
  297. end
  298. request.add_field 'User-Agent', @user_agent
  299. request.add_field 'Connection', 'keep-alive'
  300. request.add_field 'Keep-Alive', '30'
  301. if last_modified then
  302. last_modified = last_modified.utc
  303. request.add_field 'If-Modified-Since', last_modified.rfc2822
  304. end
  305. yield request if block_given?
  306. connection = connection_for uri
  307. retried = false
  308. bad_response = false
  309. begin
  310. @requests[connection.object_id] += 1
  311. say "#{request.method} #{uri}" if
  312. Gem.configuration.really_verbose
  313. file_name = File.basename(uri.path)
  314. # perform download progress reporter only for gems
  315. if request.response_body_permitted? && file_name =~ /\.gem$/
  316. reporter = ui.download_reporter
  317. response = connection.request(request) do |incomplete_response|
  318. if Net::HTTPOK === incomplete_response
  319. reporter.fetch(file_name, incomplete_response.content_length)
  320. downloaded = 0
  321. data = ''
  322. incomplete_response.read_body do |segment|
  323. data << segment
  324. downloaded += segment.length
  325. reporter.update(downloaded)
  326. end
  327. reporter.done
  328. if incomplete_response.respond_to? :body=
  329. incomplete_response.body = data
  330. else
  331. incomplete_response.instance_variable_set(:@body, data)
  332. end
  333. end
  334. end
  335. else
  336. response = connection.request request
  337. end
  338. say "#{response.code} #{response.message}" if
  339. Gem.configuration.really_verbose
  340. rescue Net::HTTPBadResponse
  341. say "bad response" if Gem.configuration.really_verbose
  342. reset connection
  343. raise FetchError.new('too many bad responses', uri) if bad_response
  344. bad_response = true
  345. retry
  346. # HACK work around EOFError bug in Net::HTTP
  347. # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
  348. # to install gems.
  349. rescue EOFError, Timeout::Error,
  350. Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE
  351. requests = @requests[connection.object_id]
  352. say "connection reset after #{requests} requests, retrying" if
  353. Gem.configuration.really_verbose
  354. raise FetchError.new('too many connection resets', uri) if retried
  355. reset connection
  356. retried = true
  357. retry
  358. end
  359. response
  360. end
  361. ##
  362. # Resets HTTP connection +connection+.
  363. def reset(connection)
  364. @requests.delete connection.object_id
  365. connection.finish
  366. connection.start
  367. end
  368. def user_agent
  369. ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}"
  370. ruby_version = RUBY_VERSION
  371. ruby_version += 'dev' if RUBY_PATCHLEVEL == -1
  372. ua << " Ruby/#{ruby_version} (#{RUBY_RELEASE_DATE}"
  373. if RUBY_PATCHLEVEL >= 0 then
  374. ua << " patchlevel #{RUBY_PATCHLEVEL}"
  375. elsif defined?(RUBY_REVISION) then
  376. ua << " revision #{RUBY_REVISION}"
  377. end
  378. ua << ")"
  379. ua << " #{RUBY_ENGINE}" if defined?(RUBY_ENGINE) and RUBY_ENGINE != 'ruby'
  380. ua
  381. end
  382. def https?(uri)
  383. uri.scheme.downcase == 'https'
  384. end
  385. end