diff --git a/lib/bundler/mirror.rb b/lib/bundler/mirror.rb index 97a6776adb8..9903e158abb 100644 --- a/lib/bundler/mirror.rb +++ b/lib/bundler/mirror.rb @@ -37,7 +37,7 @@ def parse(key, value) mirror = if config.all? @all else - (@mirrors[config.uri] = @mirrors[config.uri] || Mirror.new) + @mirrors[config.uri] ||= Mirror.new end config.update_mirror(mirror) end @@ -45,7 +45,8 @@ def parse(key, value) private def fetch_valid_mirror_for(uri) - mirror = (@mirrors[URI(uri.to_s.downcase)] || @mirrors[URI(uri.to_s).host] || Mirror.new(uri)).validate!(@prober) + mirror = @mirrors[uri.to_s.downcase] || @mirrors[URI(uri.to_s).host] || Mirror.new(uri) + mirror.validate!(@prober) mirror = Mirror.new(uri) unless mirror.valid? mirror end @@ -71,7 +72,7 @@ def uri=(uri) @uri = if uri.nil? nil else - URI(uri.to_s) + URI(uri.to_s.downcase) end @valid = nil end @@ -117,7 +118,7 @@ class MirrorConfig def initialize(config_line, value) uri, fallback = - config_line.match(%r{^mirror\.(all|.+?)(\.fallback_timeout)?\/?$}).captures + config_line.match(%r{\Amirror\.(all|.+?)(\.fallback_timeout)?\/?\z}).captures @fallback = !fallback.nil? @all = false if uri == "all" diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index 7339f721ada..3612023cb2c 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -140,7 +140,7 @@ def credentials_for(uri) def gem_mirrors all.inject(Mirrors.new) do |mirrors, k| - mirrors.parse(k, self[k]) if k =~ /^mirror\./ + mirrors.parse(k, self[k]) if k.start_with?("mirror.") mirrors end end @@ -321,16 +321,34 @@ def load_config(config_file) end end + PER_URI_OPTIONS = %w( + fallback_timeout + ).freeze + + NORMALIZE_URI_OPTIONS_PATTERN = + / + \A + (\w+\.)? # optional prefix key + (https?.*?) # URI + (\.#{Regexp.union(PER_URI_OPTIONS)})? # optional suffix key + \z + /ix + # TODO: duplicates Rubygems#normalize_uri # TODO: is this the correct place to validate mirror URIs? def self.normalize_uri(uri) uri = uri.to_s - uri = "#{uri}/" unless uri =~ %r{/\Z} + if uri =~ NORMALIZE_URI_OPTIONS_PATTERN + prefix = $1 + uri = $2 + suffix = $3 + end + uri = "#{uri}/" unless uri.end_with?("/") uri = URI(uri) unless uri.absolute? raise ArgumentError, format("Gem sources must be absolute. You provided '%s'.", uri) end - uri + "#{prefix}#{uri}#{suffix}".downcase end end end diff --git a/spec/bundler/settings_spec.rb b/spec/bundler/settings_spec.rb index 020897882cb..ec018275004 100644 --- a/spec/bundler/settings_spec.rb +++ b/spec/bundler/settings_spec.rb @@ -251,6 +251,16 @@ URI("http://rubygems-mirror.org/") ) end + + it "normalizes URIs with a fallback_timeout option" do + settings["mirror.https://rubygems.org/.fallback_timeout"] = "true" + expect(settings.all).to include("mirror.https://rubygems.org/.fallback_timeout") + end + + it "normalizes URIs with a fallback_timeout option without a trailing slash" do + settings["mirror.https://rubygems.org.fallback_timeout"] = "true" + expect(settings.all).to include("mirror.https://rubygems.org/.fallback_timeout") + end end describe "BUNDLE_ keys format" do