Class Gem::RemoteFetcher
In: lib/rubygems/remote_fetcher.rb
Parent: Object

RemoteFetcher handles the details of fetching gems and gem information from a remote source.

Methods

download   fetch_path   fetch_size   fetcher   new  

Included Modules

Gem::UserInteraction

Classes and Modules

Class Gem::RemoteFetcher::FetchError

Public Class methods

Cached RemoteFetcher instance.

[Source]

    # File lib/rubygems/remote_fetcher.rb, line 19
19:   def self.fetcher
20:     @fetcher ||= self.new Gem.configuration[:http_proxy]
21:   end

Initialize a remote fetcher using the source URI and possible proxy information.

proxy

  • [String]: explicit specification of proxy; overrides any environment
              variable setting
    
  • nil: respect environment variables (HTTP_PROXY, HTTP_PROXY_USER,
         HTTP_PROXY_PASS)
    
  • :no_proxy: ignore environment variables and _don‘t_ use a proxy

[Source]

    # File lib/rubygems/remote_fetcher.rb, line 32
32:   def initialize(proxy)
33:     Socket.do_not_reverse_lookup = true
34: 
35:     @connections = {}
36:     @requests = Hash.new 0
37:     @proxy_uri =
38:       case proxy
39:       when :no_proxy then nil
40:       when nil then get_proxy_from_env
41:       when URI::HTTP then proxy
42:       else URI.parse(proxy)
43:       end
44:   end

Public Instance methods

Moves the gem spec from source_uri to the cache dir unless it is already there. If the source_uri is local the gem cache dir copy is always replaced.

[Source]

     # File lib/rubygems/remote_fetcher.rb, line 50
 50:   def download(spec, source_uri, install_dir = Gem.dir)
 51:     gem_file_name = "#{spec.full_name}.gem"
 52:     local_gem_path = File.join install_dir, 'cache', gem_file_name
 53: 
 54:     Gem.ensure_gem_subdirectories install_dir
 55: 
 56:     source_uri = URI.parse source_uri unless URI::Generic === source_uri
 57:     scheme = source_uri.scheme
 58: 
 59:     # URI.parse gets confused by MS Windows paths with forward slashes.
 60:     scheme = nil if scheme =~ /^[a-z]$/i
 61: 
 62:     case scheme
 63:     when 'http' then
 64:       unless File.exist? local_gem_path then
 65:         begin
 66:           say "Downloading gem #{gem_file_name}" if
 67:             Gem.configuration.really_verbose
 68: 
 69:           remote_gem_path = source_uri + "gems/#{gem_file_name}"
 70: 
 71:           gem = Gem::RemoteFetcher.fetcher.fetch_path remote_gem_path
 72:         rescue Gem::RemoteFetcher::FetchError
 73:           raise if spec.original_platform == spec.platform
 74: 
 75:           alternate_name = "#{spec.original_name}.gem"
 76: 
 77:           say "Failed, downloading gem #{alternate_name}" if
 78:             Gem.configuration.really_verbose
 79: 
 80:           remote_gem_path = source_uri + "gems/#{alternate_name}"
 81: 
 82:           gem = Gem::RemoteFetcher.fetcher.fetch_path remote_gem_path
 83:         end
 84: 
 85:         File.open local_gem_path, 'wb' do |fp|
 86:           fp.write gem
 87:         end
 88:       end
 89:     when nil, 'file' then # TODO test for local overriding cache
 90:       begin
 91:         FileUtils.cp source_uri.to_s, local_gem_path
 92:       rescue Errno::EACCES
 93:         local_gem_path = source_uri.to_s
 94:       end
 95: 
 96:       say "Using local gem #{local_gem_path}" if
 97:         Gem.configuration.really_verbose
 98:     else
 99:       raise Gem::InstallError, "unsupported URI scheme #{source_uri.scheme}"
100:     end
101: 
102:     local_gem_path
103:   end

Downloads uri.

[Source]

     # File lib/rubygems/remote_fetcher.rb, line 106
106:   def fetch_path(uri)
107:     open_uri_or_path(uri) do |input|
108:       input.read
109:     end
110:   rescue Timeout::Error
111:     raise FetchError, "timed out fetching #{uri}"
112:   rescue IOError, SocketError, SystemCallError => e
113:     raise FetchError, "#{e.class}: #{e} reading #{uri}"
114:   rescue => e
115:     message = "#{e.class}: #{e} reading #{uri}"
116:     raise FetchError, message
117:   end

Returns the size of uri in bytes.

[Source]

     # File lib/rubygems/remote_fetcher.rb, line 120
120:   def fetch_size(uri)
121:     return File.size(get_file_uri_path(uri)) if file_uri? uri
122: 
123:     uri = URI.parse uri unless URI::Generic === uri
124: 
125:     raise ArgumentError, 'uri is not an HTTP URI' unless URI::HTTP === uri
126: 
127:     http = connect_to uri.host, uri.port
128: 
129:     request = Net::HTTP::Head.new uri.request_uri
130: 
131:     request.basic_auth unescape(uri.user), unescape(uri.password) unless
132:       uri.user.nil? or uri.user.empty?
133: 
134:     resp = http.request request
135: 
136:     if resp.code !~ /^2/ then
137:       raise Gem::RemoteSourceException,
138:             "HTTP Response #{resp.code} fetching #{uri}"
139:     end
140: 
141:     if resp['content-length'] then
142:       return resp['content-length'].to_i
143:     else
144:       resp = http.get uri.request_uri
145:       return resp.body.size
146:     end
147: 
148:   rescue SocketError, SystemCallError, Timeout::Error => e
149:     raise Gem::RemoteFetcher::FetchError,
150:           "#{e.message} (#{e.class})\n\tgetting size of #{uri}"
151:   end

[Validate]