Skip to content

Commit

Permalink
Merge pull request #992 from rzane/request-connect
Browse files Browse the repository at this point in the history
Simplify Net::HTTP connection handing
  • Loading branch information
bblimke authored Aug 17, 2022
2 parents 102dd56 + 5567e1d commit 2c10bd9
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 52 deletions.
79 changes: 29 additions & 50 deletions lib/webmock/http_lib_adapters/net_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,78 +67,57 @@ def constants(inherit=true)
end

def request(request, body = nil, &block)
return super unless started?

request_signature = WebMock::NetHTTPUtility.request_signature_from_request(self, request, body)

WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)

if webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
@socket = Net::HTTP.socket_type.new
WebMock::CallbackRegistry.invoke_callbacks(
{lib: :net_http}, request_signature, webmock_response)
build_net_http_response(webmock_response, &block)
elsif WebMock.net_connect_allowed?(request_signature.uri)
check_right_http_connection
after_request = lambda do |response|
if WebMock::CallbackRegistry.any_callbacks?
webmock_response = build_webmock_response(response)
WebMock::CallbackRegistry.invoke_callbacks(
{lib: :net_http, real_request: true}, request_signature, webmock_response)
end
response.extend Net::WebMockHTTPResponse
block.call response if block
response
end
super_with_after_request = lambda {
response = super(request, nil, &nil)
after_request.call(response)
}
if started?
ensure_actual_connection
super_with_after_request.call
else
start_with_connect {
super_with_after_request.call
}
ensure_actually_connected

response = super(request, nil, &nil)

if WebMock::CallbackRegistry.any_callbacks?
WebMock::CallbackRegistry.invoke_callbacks(
{lib: :net_http, real_request: true},
request_signature,
build_webmock_response(response)
)
end

response.extend Net::WebMockHTTPResponse
block.call response if block
response
else
raise WebMock::NetConnectNotAllowedError.new(request_signature)
end
end

def start_without_connect
raise IOError, 'HTTP session already opened' if @started
if block_given?
begin
@socket = Net::HTTP.socket_type.new
@started = true
return yield(self)
ensure
do_finish
end
end
@socket = Net::HTTP.socket_type.new
@started = true
self
end
private

alias_method :actually_connect, :connect

def ensure_actual_connection
if @socket.is_a?(StubSocket)
@socket&.close
@socket = nil
do_start
end
end

alias_method :start_with_connect, :start

def start(&block)
def connect
uri = Addressable::URI.parse(WebMock::NetHTTPUtility.get_uri(self))

if WebMock.net_http_connect_on_start?(uri)
super(&block)
super
else
start_without_connect(&block)
@socket = StubSocket.new
end
end

def ensure_actually_connected
if @socket.is_a?(StubSocket)
@socket&.close
@socket = nil
actually_connect
end
end

Expand Down
4 changes: 2 additions & 2 deletions spec/acceptance/net_http/net_http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,14 @@ class TestMarshalingInWebMockNetHTTP

if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
it "uses the StubSocket to provide IP address" do
Net::HTTP.start("http://example.com") do |http|
Net::HTTP.start("example.com") do |http|
expect(http.ipaddr).to eq("127.0.0.1")
end
end
end

it "defines common socket methods" do
Net::HTTP.start("http://example.com") do |http|
Net::HTTP.start("example.com") do |http|
socket = http.instance_variable_get(:@socket)
expect(socket.io.ssl_version).to eq("TLSv1.3")
expect(socket.io.cipher).to eq(["TLS_AES_128_GCM_SHA256", "TLSv1.3", 128, 128])
Expand Down

0 comments on commit 2c10bd9

Please sign in to comment.