diff --git a/lib/pact/consumer_contract/pact_file.rb b/lib/pact/consumer_contract/pact_file.rb index fa6725e..f855129 100644 --- a/lib/pact/consumer_contract/pact_file.rb +++ b/lib/pact/consumer_contract/pact_file.rb @@ -79,12 +79,37 @@ def get_remote_with_retry(uri_string, options) def get_remote(uri, options) request = Net::HTTP::Get.new(uri) + request = prepare_auth(request, options) if options[:username] || options[:token] + + http = prepare_request(uri) + response = perform_http_request(http, request, options) + + if response.is_a?(Net::HTTPRedirection) + uri = URI(response.header['location']) + req = Net::HTTP::Get.new(uri) + req = prepare_auth(req, options) if options[:username] || options[:token] + + http = prepare_request(uri) + response = perform_http_request(http, req, options) + end + response + end + + def prepare_auth(request, options) request.basic_auth(options[:username], options[:password]) if options[:username] request['Authorization'] = "Bearer #{options[:token]}" if options[:token] + request + end + + def prepare_request(uri) http = Net::HTTP.new(uri.host, uri.port, :ENV) http.use_ssl = (uri.scheme == 'https') http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && ENV['SSL_CERT_FILE'] != '' http.ca_path = ENV['SSL_CERT_DIR'] if ENV['SSL_CERT_DIR'] && ENV['SSL_CERT_DIR'] != '' + http + end + + def perform_http_request(http, request, options) http.start do |http| http.open_timeout = options[:open_timeout] || OPEN_TIMEOUT http.read_timeout = options[:read_timeout] || READ_TIMEOUT diff --git a/spec/lib/pact/consumer_contract/pact_file_spec.rb b/spec/lib/pact/consumer_contract/pact_file_spec.rb index 0af0f91..3608f6d 100644 --- a/spec/lib/pact/consumer_contract/pact_file_spec.rb +++ b/spec/lib/pact/consumer_contract/pact_file_spec.rb @@ -7,6 +7,7 @@ module Pact describe PactFile do describe 'render_pact' do let(:uri_without_userinfo) { 'http://pactbroker.com'} + let(:redirect_uri_without_userinfo) { 'http://alternate-pactbroker.com'} let(:pact_content) { 'api contract'} describe 'from a local file URI' do @@ -106,6 +107,18 @@ def render_pact(options = {}) end end + context 'with redirect' do + before do + stub_request(:get, uri_without_userinfo).to_return(status: 302, headers: {"location" => redirect_uri_without_userinfo}) + stub_request(:get, redirect_uri_without_userinfo).to_return(status: 200, body: pact_content) + end + + it 'succeeds' do + expect(PactFile).not_to receive(:delay_retry) + expect(render_pact).to eq(pact_content) + end + end + context 'with single server error' do before do stub_request(:get, uri_without_userinfo).to_return(status: 500).