diff --git a/lib/httparty/request.rb b/lib/httparty/request.rb index ff3ecd03..48fd0147 100644 --- a/lib/httparty/request.rb +++ b/lib/httparty/request.rb @@ -141,8 +141,12 @@ def perform(&block) validate setup_raw_request chunked_body = nil + peer_cert = nil + current_http = http + + self.last_response = current_http.request(@raw_request) do |http_response| + peer_cert ||= current_http.peer_cert - self.last_response = http.request(@raw_request) do |http_response| if block chunks = [] @@ -155,10 +159,9 @@ def perform(&block) end end - handle_host_redirection if response_redirects? result = handle_unauthorized - result ||= handle_response(chunked_body, &block) + result ||= handle_response(chunked_body, peer_cert, &block) result end @@ -340,7 +343,7 @@ def encode_body(body) end end - def handle_response(body, &block) + def handle_response(body, peer_cert, &block) if response_redirects? options[:limit] -= 1 if options[:logger] @@ -363,7 +366,7 @@ def handle_response(body, &block) else body ||= last_response.body body = body.nil? ? body : encode_body(body) - Response.new(self, last_response, lambda { parse_response(body) }, body: body) + Response.new(self, last_response, lambda { parse_response(body) }, body: body, peer_cert: peer_cert) end end diff --git a/lib/httparty/response.rb b/lib/httparty/response.rb index 4ae7bafc..003e4af7 100644 --- a/lib/httparty/response.rb +++ b/lib/httparty/response.rb @@ -10,7 +10,7 @@ def self._load(data) new(req, resp, -> { parsed_resp }, body: resp_body) end - attr_reader :request, :response, :body, :headers + attr_reader :request, :response, :body, :headers, :peer_cert def initialize(request, response, parsed_block, options = {}) @request = request @@ -18,6 +18,7 @@ def initialize(request, response, parsed_block, options = {}) @body = options[:body] || response.body @parsed_block = parsed_block @headers = Headers.new(response.to_hash) + @peer_cert = options[:peer_cert] if request.options[:logger] logger = ::HTTParty::Logger.build( diff --git a/spec/httparty/ssl_spec.rb b/spec/httparty/ssl_spec.rb index b6c081f8..72a64467 100644 --- a/spec/httparty/ssl_spec.rb +++ b/spec/httparty/ssl_spec.rb @@ -3,11 +3,11 @@ RSpec.describe HTTParty::Request do context "SSL certificate verification" do before do - WebMock.allow_net_connect! + WebMock.disable! end after do - WebMock.disable_net_connect! + WebMock.enable! end it "should fail when no trusted CA list is specified, by default" do @@ -70,5 +70,9 @@ ssl_verify_test(:ssl_ca_path, ".", "bogushost.crt") end.to raise_error(OpenSSL::SSL::SSLError) end + + it "should provide the certificate used by the server via peer_cert" do + expect(ssl_verify_test(:ssl_ca_file, "ca.crt", "server.crt").peer_cert).to be_a OpenSSL::X509::Certificate + end end end diff --git a/spec/support/stub_response.rb b/spec/support/stub_response.rb index c305b272..a4f8f060 100644 --- a/spec/support/stub_response.rb +++ b/spec/support/stub_response.rb @@ -9,6 +9,7 @@ def stub_http_response_with(filename) http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', format: format) allow(http_request).to receive_message_chain(:http, :request).and_return(response) + allow(http_request).to receive_message_chain(:http, :peer_cert).and_return(nil) expect(HTTParty::Request).to receive(:new).and_return(http_request) end @@ -22,6 +23,7 @@ def response.read_body(&block) http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', options) allow(http_request).to receive_message_chain(:http, :request).and_yield(response).and_return(response) + allow(http_request).to receive_message_chain(:http, :peer_cert).and_return(nil) expect(HTTParty::Request).to receive(:new).and_return(http_request) end