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 42
42:   def self.fetcher
43:     @fetcher ||= self.new Gem.configuration[:http_proxy]
44:   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 57
57:   def initialize(proxy)
58:     Socket.do_not_reverse_lookup = true
59: 
60:     @connections = {}
61:     @requests = Hash.new 0
62:     @proxy_uri =
63:       case proxy
64:       when :no_proxy then nil
65:       when nil then get_proxy_from_env
66:       when URI::HTTP then proxy
67:       else URI.parse(proxy)
68:       end
69:   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 76
 76:   def download(spec, source_uri, install_dir = Gem.dir)
 77:     cache_dir = File.join install_dir, 'cache'
 78:     gem_file_name = "#{spec.full_name}.gem"
 79:     local_gem_path = File.join cache_dir, gem_file_name
 80: 
 81:     FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
 82: 
 83:     source_uri = URI.parse source_uri unless URI::Generic === source_uri
 84:     scheme = source_uri.scheme
 85: 
 86:     # URI.parse gets confused by MS Windows paths with forward slashes.
 87:     scheme = nil if scheme =~ /^[a-z]$/i
 88: 
 89:     case scheme
 90:     when 'http' then
 91:       unless File.exist? local_gem_path then
 92:         begin
 93:           say "Downloading gem #{gem_file_name}" if
 94:             Gem.configuration.really_verbose
 95: 
 96:           remote_gem_path = source_uri + "gems/#{gem_file_name}"
 97: 
 98:           gem = Gem::RemoteFetcher.fetcher.fetch_path remote_gem_path
 99:         rescue Gem::RemoteFetcher::FetchError
100:           raise if spec.original_platform == spec.platform
101: 
102:           alternate_name = "#{spec.original_name}.gem"
103: 
104:           say "Failed, downloading gem #{alternate_name}" if
105:             Gem.configuration.really_verbose
106: 
107:           remote_gem_path = source_uri + "gems/#{alternate_name}"
108: 
109:           gem = Gem::RemoteFetcher.fetcher.fetch_path remote_gem_path
110:         end
111: 
112:         File.open local_gem_path, 'wb' do |fp|
113:           fp.write gem
114:         end
115:       end
116:     when nil, 'file' then # TODO test for local overriding cache
117:       begin
118:         FileUtils.cp source_uri.to_s, local_gem_path
119:       rescue Errno::EACCES
120:         local_gem_path = source_uri.to_s
121:       end
122: 
123:       say "Using local gem #{local_gem_path}" if
124:         Gem.configuration.really_verbose
125:     else
126:       raise Gem::InstallError, "unsupported URI scheme #{source_uri.scheme}"
127:     end
128: 
129:     local_gem_path
130:   end

Downloads uri and returns it as a String.

[Source]

     # File lib/rubygems/remote_fetcher.rb, line 135
135:   def fetch_path(uri)
136:     open_uri_or_path(uri) do |input|
137:       input.read
138:     end
139:   rescue FetchError
140:     raise
141:   rescue Timeout::Error
142:     raise FetchError.new('timed out', uri)
143:   rescue IOError, SocketError, SystemCallError => e
144:     raise FetchError.new("#{e.class}: #{e}", uri)
145:   rescue => e
146:     raise FetchError.new("#{e.class}: #{e}", uri)
147:   end

Returns the size of uri in bytes.

[Source]

     # File lib/rubygems/remote_fetcher.rb, line 152
152:   def fetch_size(uri)
153:     return File.size(get_file_uri_path(uri)) if file_uri? uri
154: 
155:     uri = URI.parse uri unless URI::Generic === uri
156: 
157:     raise ArgumentError, 'uri is not an HTTP URI' unless URI::HTTP === uri
158: 
159:     response = request uri, Net::HTTP::Head
160: 
161:     case response
162:     when Net::HTTPOK then
163:     else
164:       raise FetchError.new("bad response #{response.message} #{response.code}", uri)
165:     end
166: 
167:     if response['content-length'] then
168:       return response['content-length'].to_i
169:     else
170:       response = http.get uri.request_uri
171:       return response.body.size
172:     end
173: 
174:   rescue SocketError, SystemCallError, Timeout::Error => e
175:     raise FetchError.new("#{e.message} (#{e.class})\n\tfetching size", uri)
176:   end

[Validate]