| 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.
Cached RemoteFetcher instance.
# 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
variable setting
HTTP_PROXY_PASS)
# 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
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.
# 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.
# 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.
# 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