From: Jake Farrell Date: Tue, 28 May 2013 02:01:36 +0000 (-0400) Subject: Thrift-1978: Ruby: Thrift should allow for the SSL verify mode to be set X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=fbb78a65897ff40a7a40daa1b90aef5e23789827;p=common%2Fthrift.git Thrift-1978: Ruby: Thrift should allow for the SSL verify mode to be set Client: rb Patch: Timur Alperovich Ruby SSL verify mode cannot be specified, which means thrift cannot be used against servers with self-signed certificates over SSL. The suggested fix is to expose the SSL verification mode as a constructor argument in lib/rb/lib/thrift/transport/http_client_transport.rb. --- diff --git a/lib/rb/lib/thrift/transport/http_client_transport.rb b/lib/rb/lib/thrift/transport/http_client_transport.rb index 07f74bc4..77ffe356 100644 --- a/lib/rb/lib/thrift/transport/http_client_transport.rb +++ b/lib/rb/lib/thrift/transport/http_client_transport.rb @@ -20,16 +20,18 @@ require 'net/http' require 'net/https' +require 'openssl' require 'uri' require 'stringio' module Thrift class HTTPClientTransport < BaseTransport - def initialize(url) + def initialize(url, opts = {}) @url = URI url @headers = {'Content-Type' => 'application/x-thrift'} @outbuf = Bytes.empty_byte_buffer + @ssl_verify_mode = opts.fetch(:ssl_verify_mode, OpenSSL::SSL::VERIFY_PEER) end def open?; true end @@ -43,6 +45,7 @@ module Thrift def flush http = Net::HTTP.new @url.host, @url.port http.use_ssl = @url.scheme == 'https' + http.verify_mode = @ssl_verify_mode if @url.scheme == 'https' resp = http.post(@url.request_uri, @outbuf, @headers) data = resp.body data = Bytes.force_binary_encoding(data) diff --git a/lib/rb/spec/http_client_spec.rb b/lib/rb/spec/http_client_spec.rb index 0890a8bc..793fc73a 100644 --- a/lib/rb/spec/http_client_spec.rb +++ b/lib/rb/spec/http_client_spec.rb @@ -68,4 +68,53 @@ describe 'Thrift::HTTPClientTransport' do @client.flush end end + + describe 'ssl enabled' do + before(:each) do + @service_path = "/path/to/service?param=value" + @server_uri = "https://my.domain.com" + end + + it "should use SSL for https" do + client = Thrift::HTTPClientTransport.new("#{@server_uri}#{@service_path}") + + client.write "test" + + Net::HTTP.should_receive(:new).with("my.domain.com", 443).and_return do + mock("Net::HTTP").tap do |http| + http.should_receive(:use_ssl=).with(true) + http.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER) + http.should_receive(:post).with(@service_path, "test", + "Content-Type" => "application/x-thrift").and_return do + mock("Net::HTTPOK").tap do |response| + response.should_receive(:body).and_return "data" + end + end + end + end + client.flush + client.read(4).should == "data" + end + + it "should set SSL verify mode when specified" do + client = Thrift::HTTPClientTransport.new("#{@server_uri}#{@service_path}", + :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) + + client.write "test" + Net::HTTP.should_receive(:new).with("my.domain.com", 443).and_return do + mock("Net::HTTP").tap do |http| + http.should_receive(:use_ssl=).with(true) + http.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE) + http.should_receive(:post).with(@service_path, "test", + "Content-Type" => "application/x-thrift").and_return do + mock("Net::HTTPOK").tap do |response| + response.should_receive(:body).and_return "data" + end + end + end + end + client.flush + client.read(4).should == "data" + end + end end