diff --git a/lib/net/http.rb b/lib/net/http.rb index 83cf46cb..d5b340f2 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -1664,15 +1664,15 @@ def connect } s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) debug "opened" + + if proxy? && @proxy_use_ssl + s = OpenSSL::SSL::SSLSocket.new(s) + ssl_socket_connect(s, @open_timeout) + end + if use_ssl? if proxy? - if @proxy_use_ssl - proxy_sock = OpenSSL::SSL::SSLSocket.new(s) - ssl_socket_connect(proxy_sock, @open_timeout) - else - proxy_sock = s - end - proxy_sock = BufferedIO.new(proxy_sock, read_timeout: @read_timeout, + proxy_sock = BufferedIO.new(s, read_timeout: @read_timeout, write_timeout: @write_timeout, continue_timeout: @continue_timeout, debug_output: @debug_output) diff --git a/test/net/http/test_https_proxy.rb b/test/net/http/test_https_proxy.rb index f4c6aa0b..05031862 100644 --- a/test/net/http/test_https_proxy.rb +++ b/test/net/http/test_https_proxy.rb @@ -49,7 +49,7 @@ def read_fixture(key) File.read(File.expand_path("../fixtures/#{key}", __dir__)) end - def test_https_proxy_ssl_connection + def test_https_proxy_ssl_connection_tunneled_https begin OpenSSL rescue LoadError @@ -91,4 +91,48 @@ def test_https_proxy_ssl_connection assert_join_threads([client_thread, server_thread]) } end + + def test_https_proxy_ssl_connection_tunneled_http + begin + OpenSSL + rescue LoadError + omit 'autoload problem. see [ruby-dev:45021][Bug #5786]' + end + + TCPServer.open("127.0.0.1", 0) {|tcpserver| + ctx = OpenSSL::SSL::SSLContext.new + ctx.key = OpenSSL::PKey.read(read_fixture("server.key")) + ctx.cert = OpenSSL::X509::Certificate.new(read_fixture("server.crt")) + serv = OpenSSL::SSL::SSLServer.new(tcpserver, ctx) + + _, port, _, _ = serv.addr + client_thread = Thread.new { + proxy = Net::HTTP.Proxy("127.0.0.1", port, 'user', 'password', true) + http = proxy.new("foo.example.org", 8000) + begin + http.start + http.get('/') + rescue OpenSSL::SSL::SSLError + end + } + server_thread = Thread.new { + sock = serv.accept + begin + proxy_request = sock.gets("\r\n\r\n") + assert_equal( + "GET http://foo.example.org:8000/ HTTP/1.1\r\n" + + "Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\n" + + "Accept: */*\r\n" + + "User-Agent: Ruby\r\n" + + "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==\r\n" + + "Host: foo.example.org:8000\r\n" + + "\r\n", + proxy_request) + ensure + sock.close + end + } + assert_join_threads([client_thread, server_thread]) + } + end end if defined?(OpenSSL)