class Gem::RemoteFetcher
RemoteFetcher behandelt die Details des Abrufens von Gems und Gem-Informationen von einer entfernten Quelle.
Attribute
Öffentliche Klassenmethoden
Source
# File lib/rubygems/remote_fetcher.rb, line 55 def self.fetcher @fetcher ||= new Gem.configuration[:http_proxy] end
Instanz von RemoteFetcher im Cache.
Source
# File lib/rubygems/remote_fetcher.rb, line 75 def initialize(proxy = nil, dns = nil, headers = {}) require_relative "core_ext/tcpsocket_init" if Gem.configuration.ipv4_fallback_enabled require_relative "vendored_net_http" require_relative "vendor/uri/lib/uri" Socket.do_not_reverse_lookup = true @proxy = proxy @pools = {} @pool_lock = Thread::Mutex.new @pool_size = 1 @cert_files = Gem::Request.get_cert_files @headers = headers end
Initialisiert einen entfernten Fetcher unter Verwendung der Quell-URI und möglicher Proxy-Informationen.
proxy
-
[String]: explizite Angabe des Proxys; überschreibt jede Umgebung
variable setting
-
nil: Umgebungsvariablen berücksichtigen (HTTP_PROXY, HTTP_PROXY_USER,
HTTP_PROXY_PASS)
-
:no_proxy: Umgebungsvariablen ignorieren und KEINEN Proxy verwenden
headers: Eine Menge zusätzlicher HTTP-Header, die an den Server gesendet werden, wenn
fetching the gem.
Öffentliche Instanzmethoden
Source
# File lib/rubygems/remote_fetcher.rb, line 290 def cache_update_path(uri, path = nil, update = true) mtime = begin path && File.stat(path).mtime rescue StandardError nil end data = fetch_path(uri, mtime) if data.nil? # indicates the server returned 304 Not Modified return Gem.read_binary(path) end if update && path Gem.write_binary(path, data) end data end
Lädt uri nach path herunter, falls erforderlich. Wenn kein Pfad angegeben ist, werden nur die Daten übergeben.
Source
# File lib/rubygems/remote_fetcher.rb, line 330 def close_all @pools.each_value(&:close_all) end
Source
# File lib/rubygems/remote_fetcher.rb, line 113 def download(spec, source_uri, install_dir = Gem.dir) install_cache_dir = File.join install_dir, "cache" cache_dir = if Dir.pwd == install_dir # see fetch_command install_dir elsif File.writable?(install_cache_dir) || (File.writable?(install_dir) && !File.exist?(install_cache_dir)) install_cache_dir else File.join Gem.user_dir, "cache" end gem_file_name = File.basename spec.cache_file local_gem_path = File.join cache_dir, gem_file_name require "fileutils" begin FileUtils.mkdir_p cache_dir rescue StandardError nil end unless File.exist? cache_dir source_uri = Gem::Uri.new(source_uri) scheme = source_uri.scheme # Gem::URI.parse gets confused by MS Windows paths with forward slashes. scheme = nil if /^[a-z]$/i.match?(scheme) # REFACTOR: split this up and dispatch on scheme (eg download_http) # REFACTOR: be sure to clean up fake fetcher when you do this... cleaner case scheme when "http", "https", "s3" then unless File.exist? local_gem_path begin verbose "Downloading gem #{gem_file_name}" remote_gem_path = source_uri + "gems/#{gem_file_name}" cache_update_path remote_gem_path, local_gem_path rescue FetchError raise if spec.original_platform == spec.platform alternate_name = "#{spec.original_name}.gem" verbose "Failed, downloading gem #{alternate_name}" remote_gem_path = source_uri + "gems/#{alternate_name}" cache_update_path remote_gem_path, local_gem_path end end when "file" then begin path = source_uri.path path = File.dirname(path) if File.extname(path) == ".gem" remote_gem_path = Gem::Util.correct_for_windows_path(File.join(path, "gems", gem_file_name)) FileUtils.cp(remote_gem_path, local_gem_path) rescue Errno::EACCES local_gem_path = source_uri.to_s end verbose "Using local gem #{local_gem_path}" when nil then # TODO: test for local overriding cache source_path = if Gem.win_platform? && source_uri.scheme && !source_uri.path.include?(":") "#{source_uri.scheme}:#{source_uri.path}" else source_uri.path end source_path = Gem::UriFormatter.new(source_path).unescape begin FileUtils.cp source_path, local_gem_path unless File.identical?(source_path, local_gem_path) rescue Errno::EACCES local_gem_path = source_uri.to_s end verbose "Using local gem #{local_gem_path}" else raise ArgumentError, "unsupported URI scheme #{source_uri.scheme}" end local_gem_path end
Verschiebt das Gem spec von source_uri in das Cache-Verzeichnis, es sei denn, es ist bereits dort. Wenn source_uri lokal ist, wird die Kopie im Gem-Cache-Verzeichnis immer ersetzt.
Source
# File lib/rubygems/remote_fetcher.rb, line 98 def download_to_cache(dependency) found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency return if found.empty? spec, source = found.max_by {|(s,_)| s.version } download spec, source.uri end
Lädt dieses Gem basierend auf Name und Anforderung in den Cache und gibt den Dateinamen zurück. Gibt nil zurück, wenn das Gem nicht gefunden werden kann.
Source
# File lib/rubygems/remote_fetcher.rb, line 205 def fetch_file(uri, *_) Gem.read_binary Gem::Util.correct_for_windows_path uri.path end
Fetcher für File. Wird von fetch_path aufgerufen. Benutzen Sie stattdessen diesen.
Source
# File lib/rubygems/remote_fetcher.rb, line 212 def fetch_http(uri, last_modified = nil, head = false, depth = 0) fetch_type = head ? Gem::Net::HTTP::Head : Gem::Net::HTTP::Get response = request uri, fetch_type, last_modified do |req| headers.each {|k,v| req.add_field(k,v) } end case response when Gem::Net::HTTPOK, Gem::Net::HTTPNotModified then response.uri = uri head ? response : response.body when Gem::Net::HTTPMovedPermanently, Gem::Net::HTTPFound, Gem::Net::HTTPSeeOther, Gem::Net::HTTPTemporaryRedirect then raise FetchError.new("too many redirects", uri) if depth > 10 unless location = response["Location"] raise FetchError.new("redirecting but no redirect location was given", uri) end location = Gem::Uri.new location if https?(uri) && !https?(location) raise FetchError.new("redirecting to non-https resource: #{location}", uri) end fetch_http(location, last_modified, head, depth + 1) else raise FetchError.new("bad response #{response.message} #{response.code}", uri) end end
HTTP Fetcher. Wird von fetch_path aufgerufen. Benutzen Sie stattdessen diesen.
Source
# File lib/rubygems/remote_fetcher.rb, line 246 def fetch_path(uri, mtime = nil, head = false) uri = Gem::Uri.new uri method = { "http" => "fetch_http", "https" => "fetch_http", "s3" => "fetch_s3", "file" => "fetch_file", }.fetch(uri.scheme) { raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}" } data = send method, uri, mtime, head if data && !head && uri.to_s.end_with?(".gz") begin data = Gem::Util.gunzip data rescue Zlib::GzipFile::Error raise FetchError.new("server did not return a valid file", uri) end end data rescue Gem::Timeout::Error, IOError, SocketError, SystemCallError, *(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e raise FetchError.new("#{e.class}: #{e}", uri) end
Lädt uri herunter und gibt es als String zurück.
Source
# File lib/rubygems/remote_fetcher.rb, line 272 def fetch_s3(uri, mtime = nil, head = false) begin public_uri = s3_uri_signer(uri, head ? "HEAD" : "GET").sign rescue Gem::S3URISigner::ConfigurationError, Gem::S3URISigner::InstanceProfileError => e raise FetchError.new(e.message, "s3://#{uri.host}") end fetch_https public_uri, mtime, head end
Source
# File lib/rubygems/remote_fetcher.rb, line 326 def https?(uri) uri.scheme.casecmp("https").zero? end
Source
# File lib/rubygems/remote_fetcher.rb, line 315 def request(uri, request_class, last_modified = nil) proxy = proxy_for @proxy, uri pool = pools_for(proxy).pool_for uri request = Gem::Request.new uri, request_class, last_modified, pool request.fetch do |req| yield req if block_given? end end
Führt eine Gem::Net::HTTP-Anfrage vom Typ request_class an uri durch und gibt ein Gem::Net::HTTP-Antwortobjekt zurück. `request` unterhält eine Tabelle mit persistenten Verbindungen, um den Verbindungsaufwand zu reduzieren.
Source
# File lib/rubygems/remote_fetcher.rb, line 282 def s3_uri_signer(uri, method) Gem::S3URISigner.new(uri, method) end
Wir haben hier unseren eigenen Signierungscode, um eine Abhängigkeit vom aws-sdk-Gem zu vermeiden
Private Instanzmethoden
Source
# File lib/rubygems/remote_fetcher.rb, line 340 def pools_for(proxy) @pool_lock.synchronize do @pools[proxy] ||= Gem::Request::ConnectionPools.new proxy, @cert_files, @pool_size end end
Source
# File lib/rubygems/remote_fetcher.rb, line 336 def proxy_for(proxy, uri) Gem::Request.proxy_uri(proxy || Gem::Request.get_proxy_from_env(uri.scheme)) end