Skip to content

Commit

Permalink
Add support for net-http2 backend
Browse files Browse the repository at this point in the history
  • Loading branch information
singpolyma-shopify committed Feb 8, 2019
1 parent 90f0bb7 commit d49a413
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/webmock.rb
Expand Up @@ -46,6 +46,7 @@
require_relative 'webmock/http_lib_adapters/http_lib_adapter_registry'
require_relative 'webmock/http_lib_adapters/http_lib_adapter'
require_relative 'webmock/http_lib_adapters/net_http'
require_relative 'webmock/http_lib_adapters/net_http2_adapter'
require_relative 'webmock/http_lib_adapters/http_rb_adapter'
require_relative 'webmock/http_lib_adapters/httpclient_adapter'
require_relative 'webmock/http_lib_adapters/patron_adapter'
Expand Down
76 changes: 76 additions & 0 deletions lib/webmock/http_lib_adapters/net_http2_adapter.rb
@@ -0,0 +1,76 @@
require 'net-http2'

module WebMock
module HttpLibAdapters
class NetHttp2Adapter < HttpLibAdapter
adapter_for :net_http2

OriginalClient = NetHttp2::Client unless const_defined?(:OriginalClient)
OriginalStream = NetHttp2::Stream unless const_defined?(:OriginalStream)

def self.enable!
NetHttp2.send(:remove_const, :Stream)
NetHttp2.send(:remove_const, :Client)
NetHttp2.send(:const_set, :Stream, @webMockNetHTTP2Stream)
NetHttp2.send(:const_set, :Client, @webMockNetHTTP2Client)
end

def self.disable!
NetHttp2.send(:remove_const, :Stream)
NetHttp2.send(:remove_const, :Client)
NetHttp2.send(:const_set, :Stream, OriginalStream)
NetHttp2.send(:const_set, :Client, OriginalClient)
end

@webMockNetHTTP2Stream = Class.new(OriginalStream) do
def initialize(*)
@webmock_queue = Queue.new
super
end

def send_request_data
uri = @request.uri.dup
uri.path = @request.full_path.to_s
sig = WebMock::RequestSignature.new(@request.method, uri.to_s, body: @request.body, headers: @request.headers)
WebMock::RequestRegistry.instance.requested_signatures.put(sig)

if webmock_response = WebMock::StubRegistry.instance.response_for_request(sig)
WebMock::CallbackRegistry.invoke_callbacks({ lib: :net_http2 }, sig, webmock_response)
return if webmock_response.should_timeout

if async?
@request.emit(:headers, webmock_response.headers.merge(":status" => webmock_response.status.first.to_s))
@request.emit(:body_chunk, webmock_response.body)
@request.emit(:close, nil)
else
@headers.merge!((webmock_response.headers || {}).merge(":status" => webmock_response.status.first.to_s))
@data << webmock_response.body
@completed = true
Thread.new do
@webmock_queue.pop
@mutex.synchronize { @cv.signal }
end
end
elsif WebMock.net_connect_allowed?(sig.uri)
raise "WebMock NetHTTP2 backend does not support net_connect_allowed yet"
else
raise WebMock::NetConnectNotAllowedError, sig
end
end

def wait_for_completed
@mutex.synchronize do
@webmock_queue.push(:waiting)
@cv.wait(@mutex, @request.timeout)
end
end
end

@webMockNetHTTP2Client = Class.new(OriginalClient) do
def new_socket
StubSocket.new
end
end
end
end
end
1 change: 1 addition & 0 deletions webmock.gemspec
Expand Up @@ -35,6 +35,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'em-http-request', '>= 1.0.2'
s.add_development_dependency 'em-synchrony', '>= 1.0.0'
s.add_development_dependency 'excon', '>= 0.27.5'
s.add_development_dependency 'net-http2', '>= 0.18.0'
s.add_development_dependency 'minitest', '>= 5.0.0'
s.add_development_dependency 'test-unit', '>= 3.0.0'
s.add_development_dependency 'rdoc', '> 3.5.0'
Expand Down

0 comments on commit d49a413

Please sign in to comment.