Project

General

Profile

Feature #13719 ยป 0001-net-http-allow-existing-socket-arg-for-Net-HTTP.star.patch

normalperson (Eric Wong), 07/05/2017 07:03 PM

View differences:

lib/net/http.rb
576 576
    #
577 577
    # _opt_ sets following values by its accessor.
578 578
    # The keys are ca_file, ca_path, cert, cert_store, ciphers,
579
    # close_on_empty_response, key, open_timeout, read_timeout, ssl_timeout,
580
    # ssl_version, use_ssl, verify_callback, verify_depth and verify_mode.
579
    # close_on_empty_response, key, open_timeout, read_timeout, socket,
580
    # ssl_timeout, ssl_version, use_ssl, verify_callback, verify_depth
581
    # and verify_mode.
581 582
    # If you set :use_ssl as true, you can use https and default value of
582 583
    # verify_mode is set as OpenSSL::SSL::VERIFY_PEER.
584
    # :socket may be any connected Socket object, including UNIXSocket
585
    # for connecting to nginx or similar.
583 586
    #
584 587
    # If the optional block is given, the newly
585 588
    # created Net::HTTP object is passed to it and closed when the
......
604 607
          opt.key?(key) or next
605 608
          http.__send__(meth, opt[key])
606 609
        end
610
        http.instance_variable_set(:@live_socket, opt[:socket])
607 611
      end
608 612

  
609 613
      http.start(&block)
......
666 670
      @last_communicated = nil
667 671
      @close_on_empty_response = false
668 672
      @socket  = nil
673
      @live_socket = nil
669 674
      @started = false
670 675
      @open_timeout = 60
671 676
      @read_timeout = 60
......
898 903
        conn_address = address
899 904
        conn_port    = port
900 905
      end
901

  
902
      D "opening connection to #{conn_address}:#{conn_port}..."
903
      s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
904
        begin
905
          TCPSocket.open(conn_address, conn_port, @local_host, @local_port)
906
        rescue => e
907
          raise e, "Failed to open TCP connection to " +
908
            "#{conn_address}:#{conn_port} (#{e.message})"
909
        end
910
      }
911
      s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
912
      D "opened"
906
      unless s = @live_socket
907
        D "opening connection to #{conn_address}:#{conn_port}..."
908
        s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
909
          begin
910
            TCPSocket.open(conn_address, conn_port, @local_host, @local_port)
911
          rescue => e
912
            raise e, "Failed to open TCP connection to " +
913
              "#{conn_address}:#{conn_port} (#{e.message})"
914
          end
915
        }
916
        s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
917
        D "opened"
918
      end
913 919
      if use_ssl?
914 920
        if proxy?
915 921
          plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
......
980 986
    def do_finish
981 987
      @started = false
982 988
      @socket.close if @socket
983
      @socket = nil
989
      @live_socket = @socket = nil
984 990
    end
985 991
    private :do_finish
986 992

  
test/net/http/test_http.rb
262 262
    assert_equal false, h.instance_variable_get(:@proxy_from_env)
263 263
  end
264 264

  
265
  def test_socket_arg_unix
266
    UNIXSocket.pair do |c,s|
267
      th = Thread.new do
268
        req = ''.b
269
        req << s.readpartial(128) until req.include?("\r\n\r\n")
270
        s.write("HTTP/1.1 200 OK\r\n" \
271
                "Content-Type: text/plain\r\n" \
272
                "Content-Length: 2\r\n\r\n")
273
        s.close
274
        req
275
      end
276
      Net::HTTP.start('example.com', 80, socket: c) do |http|
277
        res = http.head('/')
278
        assert_instance_of Net::HTTPOK, res
279
      end
280
      assert_match %r{\AHEAD / HTTP/1\.1\r\n}, th.value
281
      assert_predicate c, :closed?
282
    end
283
  end if defined?(UNIXSocket)
284

  
265 285
  def test_s_get
266 286
    assert_equal $test_net_http_data,
267 287
        Net::HTTP.get(config('host'), '/', config('port'))
268
-