webmock 3.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/.gitignore +34 -0
- data/.rspec-tm +2 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +1698 -0
- data/Gemfile +9 -0
- data/LICENSE +20 -0
- data/README.md +1125 -0
- data/Rakefile +28 -0
- data/lib/webmock.rb +59 -0
- data/lib/webmock/api.rb +109 -0
- data/lib/webmock/assertion_failure.rb +11 -0
- data/lib/webmock/callback_registry.rb +35 -0
- data/lib/webmock/config.rb +18 -0
- data/lib/webmock/cucumber.rb +10 -0
- data/lib/webmock/deprecation.rb +9 -0
- data/lib/webmock/errors.rb +17 -0
- data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +214 -0
- data/lib/webmock/http_lib_adapters/curb_adapter.rb +347 -0
- data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +228 -0
- data/lib/webmock/http_lib_adapters/excon_adapter.rb +162 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
- data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
- data/lib/webmock/http_lib_adapters/http_rb/client.rb +14 -0
- data/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
- data/lib/webmock/http_lib_adapters/http_rb/response.rb +43 -0
- data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
- data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
- data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
- data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +242 -0
- data/lib/webmock/http_lib_adapters/manticore_adapter.rb +130 -0
- data/lib/webmock/http_lib_adapters/net_http.rb +361 -0
- data/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
- data/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
- data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
- data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
- data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
- data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
- data/lib/webmock/matchers/hash_including_matcher.rb +17 -0
- data/lib/webmock/minitest.rb +41 -0
- data/lib/webmock/rack_response.rb +69 -0
- data/lib/webmock/request_body_diff.rb +64 -0
- data/lib/webmock/request_execution_verifier.rb +77 -0
- data/lib/webmock/request_pattern.rb +370 -0
- data/lib/webmock/request_registry.rb +35 -0
- data/lib/webmock/request_signature.rb +54 -0
- data/lib/webmock/request_signature_snippet.rb +61 -0
- data/lib/webmock/request_stub.rb +100 -0
- data/lib/webmock/response.rb +153 -0
- data/lib/webmock/responses_sequence.rb +40 -0
- data/lib/webmock/rspec.rb +41 -0
- data/lib/webmock/rspec/matchers.rb +27 -0
- data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
- data/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
- data/lib/webmock/stub_registry.rb +67 -0
- data/lib/webmock/stub_request_snippet.rb +38 -0
- data/lib/webmock/test_unit.rb +22 -0
- data/lib/webmock/util/hash_counter.rb +39 -0
- data/lib/webmock/util/hash_keys_stringifier.rb +25 -0
- data/lib/webmock/util/hash_validator.rb +17 -0
- data/lib/webmock/util/headers.rb +64 -0
- data/lib/webmock/util/json.rb +67 -0
- data/lib/webmock/util/query_mapper.rb +281 -0
- data/lib/webmock/util/uri.rb +110 -0
- data/lib/webmock/util/values_stringifier.rb +20 -0
- data/lib/webmock/util/version_checker.rb +111 -0
- data/lib/webmock/version.rb +3 -0
- data/lib/webmock/webmock.rb +161 -0
- data/minitest/test_helper.rb +34 -0
- data/minitest/test_webmock.rb +9 -0
- data/minitest/webmock_spec.rb +60 -0
- data/spec/acceptance/async_http_client/async_http_client_spec.rb +349 -0
- data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
- data/spec/acceptance/curb/curb_spec.rb +492 -0
- data/spec/acceptance/curb/curb_spec_helper.rb +147 -0
- data/spec/acceptance/em_http_request/em_http_request_spec.rb +406 -0
- data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
- data/spec/acceptance/excon/excon_spec.rb +77 -0
- data/spec/acceptance/excon/excon_spec_helper.rb +50 -0
- data/spec/acceptance/http_rb/http_rb_spec.rb +82 -0
- data/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
- data/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
- data/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
- data/spec/acceptance/manticore/manticore_spec.rb +56 -0
- data/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
- data/spec/acceptance/net_http/net_http_shared.rb +153 -0
- data/spec/acceptance/net_http/net_http_spec.rb +331 -0
- data/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
- data/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
- data/spec/acceptance/patron/patron_spec.rb +125 -0
- data/spec/acceptance/patron/patron_spec_helper.rb +54 -0
- data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
- data/spec/acceptance/shared/callbacks.rb +148 -0
- data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
- data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
- data/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
- data/spec/acceptance/shared/request_expectations.rb +930 -0
- data/spec/acceptance/shared/returning_declared_responses.rb +409 -0
- data/spec/acceptance/shared/stubbing_requests.rb +643 -0
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
- data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
- data/spec/acceptance/webmock_shared.rb +41 -0
- data/spec/fixtures/test.txt +1 -0
- data/spec/quality_spec.rb +84 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/support/example_curl_output.txt +22 -0
- data/spec/support/failures.rb +9 -0
- data/spec/support/my_rack_app.rb +53 -0
- data/spec/support/network_connection.rb +19 -0
- data/spec/support/webmock_server.rb +70 -0
- data/spec/unit/api_spec.rb +175 -0
- data/spec/unit/errors_spec.rb +129 -0
- data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
- data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
- data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
- data/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
- data/spec/unit/rack_response_spec.rb +112 -0
- data/spec/unit/request_body_diff_spec.rb +90 -0
- data/spec/unit/request_execution_verifier_spec.rb +208 -0
- data/spec/unit/request_pattern_spec.rb +601 -0
- data/spec/unit/request_registry_spec.rb +95 -0
- data/spec/unit/request_signature_snippet_spec.rb +89 -0
- data/spec/unit/request_signature_spec.rb +155 -0
- data/spec/unit/request_stub_spec.rb +199 -0
- data/spec/unit/response_spec.rb +282 -0
- data/spec/unit/stub_registry_spec.rb +103 -0
- data/spec/unit/stub_request_snippet_spec.rb +115 -0
- data/spec/unit/util/hash_counter_spec.rb +39 -0
- data/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
- data/spec/unit/util/headers_spec.rb +28 -0
- data/spec/unit/util/json_spec.rb +33 -0
- data/spec/unit/util/query_mapper_spec.rb +157 -0
- data/spec/unit/util/uri_spec.rb +361 -0
- data/spec/unit/util/version_checker_spec.rb +65 -0
- data/spec/unit/webmock_spec.rb +19 -0
- data/test/http_request.rb +24 -0
- data/test/shared_test.rb +108 -0
- data/test/test_helper.rb +23 -0
- data/test/test_webmock.rb +6 -0
- data/webmock.gemspec +45 -0
- metadata +496 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'manticore'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
# manticore not found
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
if defined?(Manticore)
|
|
8
|
+
module WebMock
|
|
9
|
+
module HttpLibAdapters
|
|
10
|
+
class ManticoreAdapter < HttpLibAdapter
|
|
11
|
+
adapter_for :manticore
|
|
12
|
+
|
|
13
|
+
OriginalManticoreClient = Manticore::Client
|
|
14
|
+
|
|
15
|
+
def self.enable!
|
|
16
|
+
Manticore.send(:remove_const, :Client)
|
|
17
|
+
Manticore.send(:const_set, :Client, WebMockManticoreClient)
|
|
18
|
+
Manticore.instance_variable_set(:@manticore_facade, WebMockManticoreClient.new)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.disable!
|
|
22
|
+
Manticore.send(:remove_const, :Client)
|
|
23
|
+
Manticore.send(:const_set, :Client, OriginalManticoreClient)
|
|
24
|
+
Manticore.instance_variable_set(:@manticore_facade, OriginalManticoreClient.new)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class WebMockManticoreClient < Manticore::Client
|
|
28
|
+
def request(klass, url, options={}, &block)
|
|
29
|
+
super(klass, WebMock::Util::URI.normalize_uri(url).to_s, format_options(options))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def format_options(options)
|
|
35
|
+
return options unless headers = options[:headers]
|
|
36
|
+
|
|
37
|
+
options.merge(headers: join_array_values(headers))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def join_array_values(headers)
|
|
41
|
+
headers.reduce({}) do |h, (k,v)|
|
|
42
|
+
v = v.join(', ') if v.is_a?(Array)
|
|
43
|
+
h.merge(k => v)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def response_object_for(request, context, &block)
|
|
48
|
+
request_signature = generate_webmock_request_signature(request, context)
|
|
49
|
+
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
|
50
|
+
|
|
51
|
+
if webmock_response = registered_response_for(request_signature)
|
|
52
|
+
webmock_response.raise_error_if_any
|
|
53
|
+
manticore_response = generate_manticore_response(webmock_response)
|
|
54
|
+
manticore_response.on_success do
|
|
55
|
+
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: false}, request_signature, webmock_response)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
elsif real_request_allowed?(request_signature.uri)
|
|
59
|
+
manticore_response = Manticore::Response.new(self, request, context, &block)
|
|
60
|
+
manticore_response.on_complete do |completed_response|
|
|
61
|
+
webmock_response = generate_webmock_response(completed_response)
|
|
62
|
+
WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: true}, request_signature, webmock_response)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
else
|
|
66
|
+
raise WebMock::NetConnectNotAllowedError.new(request_signature)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
manticore_response
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def registered_response_for(request_signature)
|
|
73
|
+
WebMock::StubRegistry.instance.response_for_request(request_signature)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def real_request_allowed?(uri)
|
|
77
|
+
WebMock.net_connect_allowed?(uri)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def generate_webmock_request_signature(request, context)
|
|
81
|
+
method = request.method.downcase
|
|
82
|
+
uri = request.uri.to_s
|
|
83
|
+
body = read_body(request)
|
|
84
|
+
headers = split_array_values(request.headers)
|
|
85
|
+
|
|
86
|
+
if context.get_credentials_provider && credentials = context.get_credentials_provider.get_credentials(AuthScope::ANY)
|
|
87
|
+
headers['Authorization'] = WebMock::Util::Headers.basic_auth_header(credentials.get_user_name,credentials.get_password)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
WebMock::RequestSignature.new(method, uri, {body: body, headers: headers})
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def read_body(request)
|
|
94
|
+
if request.respond_to?(:entity) && !request.entity.nil?
|
|
95
|
+
Manticore::EntityConverter.new.read_entity(request.entity)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def split_array_values(headers = [])
|
|
100
|
+
headers.each_with_object({}) do |(k, v), h|
|
|
101
|
+
h[k] = case v
|
|
102
|
+
when /,/ then v.split(',').map(&:strip)
|
|
103
|
+
else v
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def generate_manticore_response(webmock_response)
|
|
109
|
+
raise Manticore::ConnectTimeout if webmock_response.should_timeout
|
|
110
|
+
|
|
111
|
+
Manticore::StubbedResponse.stub(
|
|
112
|
+
code: webmock_response.status[0],
|
|
113
|
+
body: webmock_response.body,
|
|
114
|
+
headers: webmock_response.headers,
|
|
115
|
+
cookies: {}
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def generate_webmock_response(manticore_response)
|
|
120
|
+
webmock_response = WebMock::Response.new
|
|
121
|
+
webmock_response.status = [manticore_response.code, manticore_response.message]
|
|
122
|
+
webmock_response.body = manticore_response.body
|
|
123
|
+
webmock_response.headers = manticore_response.headers
|
|
124
|
+
webmock_response
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'net/https'
|
|
3
|
+
require 'stringio'
|
|
4
|
+
require File.join(File.dirname(__FILE__), 'net_http_response')
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module WebMock
|
|
8
|
+
module HttpLibAdapters
|
|
9
|
+
class NetHttpAdapter < HttpLibAdapter
|
|
10
|
+
adapter_for :net_http
|
|
11
|
+
|
|
12
|
+
OriginalNetHTTP = Net::HTTP unless const_defined?(:OriginalNetHTTP)
|
|
13
|
+
OriginalNetBufferedIO = Net::BufferedIO unless const_defined?(:OriginalNetBufferedIO)
|
|
14
|
+
|
|
15
|
+
def self.enable!
|
|
16
|
+
Net.send(:remove_const, :BufferedIO)
|
|
17
|
+
Net.send(:remove_const, :HTTP)
|
|
18
|
+
Net.send(:remove_const, :HTTPSession)
|
|
19
|
+
Net.send(:const_set, :HTTP, @webMockNetHTTP)
|
|
20
|
+
Net.send(:const_set, :HTTPSession, @webMockNetHTTP)
|
|
21
|
+
Net.send(:const_set, :BufferedIO, Net::WebMockNetBufferedIO)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.disable!
|
|
25
|
+
Net.send(:remove_const, :BufferedIO)
|
|
26
|
+
Net.send(:remove_const, :HTTP)
|
|
27
|
+
Net.send(:remove_const, :HTTPSession)
|
|
28
|
+
Net.send(:const_set, :HTTP, OriginalNetHTTP)
|
|
29
|
+
Net.send(:const_set, :HTTPSession, OriginalNetHTTP)
|
|
30
|
+
Net.send(:const_set, :BufferedIO, OriginalNetBufferedIO)
|
|
31
|
+
|
|
32
|
+
#copy all constants from @webMockNetHTTP to original Net::HTTP
|
|
33
|
+
#in case any constants were added to @webMockNetHTTP instead of Net::HTTP
|
|
34
|
+
#after WebMock was enabled.
|
|
35
|
+
#i.e Net::HTTP::DigestAuth
|
|
36
|
+
@webMockNetHTTP.constants.each do |constant|
|
|
37
|
+
if !OriginalNetHTTP.constants.map(&:to_s).include?(constant.to_s)
|
|
38
|
+
OriginalNetHTTP.send(:const_set, constant, @webMockNetHTTP.const_get(constant))
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
@webMockNetHTTP = Class.new(Net::HTTP) do
|
|
44
|
+
class << self
|
|
45
|
+
def socket_type
|
|
46
|
+
StubSocket
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if Module.method(:const_defined?).arity == 1
|
|
50
|
+
def const_defined?(name)
|
|
51
|
+
super || self.superclass.const_defined?(name)
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
def const_defined?(name, inherit=true)
|
|
55
|
+
super || self.superclass.const_defined?(name, inherit)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if Module.method(:const_get).arity != 1
|
|
60
|
+
def const_get(name, inherit=true)
|
|
61
|
+
super
|
|
62
|
+
rescue NameError
|
|
63
|
+
self.superclass.const_get(name, inherit)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
if Module.method(:constants).arity != 0
|
|
68
|
+
def constants(inherit=true)
|
|
69
|
+
(super + self.superclass.constants(inherit)).uniq
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def request(request, body = nil, &block)
|
|
75
|
+
request_signature = WebMock::NetHTTPUtility.request_signature_from_request(self, request, body)
|
|
76
|
+
|
|
77
|
+
WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
|
|
78
|
+
|
|
79
|
+
if webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
|
|
80
|
+
@socket = Net::HTTP.socket_type.new
|
|
81
|
+
WebMock::CallbackRegistry.invoke_callbacks(
|
|
82
|
+
{lib: :net_http}, request_signature, webmock_response)
|
|
83
|
+
build_net_http_response(webmock_response, &block)
|
|
84
|
+
elsif WebMock.net_connect_allowed?(request_signature.uri)
|
|
85
|
+
check_right_http_connection
|
|
86
|
+
after_request = lambda do |response|
|
|
87
|
+
if WebMock::CallbackRegistry.any_callbacks?
|
|
88
|
+
webmock_response = build_webmock_response(response)
|
|
89
|
+
WebMock::CallbackRegistry.invoke_callbacks(
|
|
90
|
+
{lib: :net_http, real_request: true}, request_signature, webmock_response)
|
|
91
|
+
end
|
|
92
|
+
response.extend Net::WebMockHTTPResponse
|
|
93
|
+
block.call response if block
|
|
94
|
+
response
|
|
95
|
+
end
|
|
96
|
+
super_with_after_request = lambda {
|
|
97
|
+
response = super(request, nil, &nil)
|
|
98
|
+
after_request.call(response)
|
|
99
|
+
}
|
|
100
|
+
if started?
|
|
101
|
+
if WebMock::Config.instance.net_http_connect_on_start
|
|
102
|
+
super_with_after_request.call
|
|
103
|
+
else
|
|
104
|
+
start_with_connect_without_finish {
|
|
105
|
+
super_with_after_request.call
|
|
106
|
+
}
|
|
107
|
+
end
|
|
108
|
+
else
|
|
109
|
+
start_with_connect {
|
|
110
|
+
super_with_after_request.call
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
else
|
|
114
|
+
raise WebMock::NetConnectNotAllowedError.new(request_signature)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def start_without_connect
|
|
119
|
+
raise IOError, 'HTTP session already opened' if @started
|
|
120
|
+
if block_given?
|
|
121
|
+
begin
|
|
122
|
+
@started = true
|
|
123
|
+
return yield(self)
|
|
124
|
+
ensure
|
|
125
|
+
do_finish
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
@started = true
|
|
129
|
+
self
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def start_with_connect_without_finish # :yield: http
|
|
134
|
+
if block_given?
|
|
135
|
+
begin
|
|
136
|
+
do_start
|
|
137
|
+
return yield(self)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
do_start
|
|
141
|
+
self
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
alias_method :start_with_connect, :start
|
|
145
|
+
|
|
146
|
+
def start(&block)
|
|
147
|
+
if WebMock::Config.instance.net_http_connect_on_start
|
|
148
|
+
super(&block)
|
|
149
|
+
else
|
|
150
|
+
start_without_connect(&block)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def build_net_http_response(webmock_response, &block)
|
|
155
|
+
response = Net::HTTPResponse.send(:response_class, webmock_response.status[0].to_s).new("1.0", webmock_response.status[0].to_s, webmock_response.status[1])
|
|
156
|
+
body = webmock_response.body
|
|
157
|
+
body = nil if webmock_response.status[0].to_s == '204'
|
|
158
|
+
|
|
159
|
+
response.instance_variable_set(:@body, body)
|
|
160
|
+
webmock_response.headers.to_a.each do |name, values|
|
|
161
|
+
values = [values] unless values.is_a?(Array)
|
|
162
|
+
values.each do |value|
|
|
163
|
+
response.add_field(name, value)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
response.instance_variable_set(:@read, true)
|
|
168
|
+
|
|
169
|
+
response.extend Net::WebMockHTTPResponse
|
|
170
|
+
|
|
171
|
+
if webmock_response.should_timeout
|
|
172
|
+
raise timeout_exception, "execution expired"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
webmock_response.raise_error_if_any
|
|
176
|
+
|
|
177
|
+
yield response if block_given?
|
|
178
|
+
|
|
179
|
+
response
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def timeout_exception
|
|
183
|
+
if defined?(Net::OpenTimeout)
|
|
184
|
+
# Ruby 2.x
|
|
185
|
+
Net::OpenTimeout
|
|
186
|
+
else
|
|
187
|
+
# Fallback, if things change
|
|
188
|
+
Timeout::Error
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def build_webmock_response(net_http_response)
|
|
193
|
+
webmock_response = WebMock::Response.new
|
|
194
|
+
webmock_response.status = [
|
|
195
|
+
net_http_response.code.to_i,
|
|
196
|
+
net_http_response.message]
|
|
197
|
+
webmock_response.headers = net_http_response.to_hash
|
|
198
|
+
webmock_response.body = net_http_response.body
|
|
199
|
+
webmock_response
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def check_right_http_connection
|
|
204
|
+
unless @@alredy_checked_for_right_http_connection ||= false
|
|
205
|
+
WebMock::NetHTTPUtility.puts_warning_for_right_http_if_needed
|
|
206
|
+
@@alredy_checked_for_right_http_connection = true
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
@webMockNetHTTP.version_1_2
|
|
211
|
+
[
|
|
212
|
+
[:Get, Net::HTTP::Get],
|
|
213
|
+
[:Post, Net::HTTP::Post],
|
|
214
|
+
[:Put, Net::HTTP::Put],
|
|
215
|
+
[:Delete, Net::HTTP::Delete],
|
|
216
|
+
[:Head, Net::HTTP::Head],
|
|
217
|
+
[:Options, Net::HTTP::Options]
|
|
218
|
+
].each do |c|
|
|
219
|
+
@webMockNetHTTP.const_set(c[0], c[1])
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# patch for StringIO behavior in Ruby 2.2.3
|
|
226
|
+
# https://github.com/bblimke/webmock/issues/558
|
|
227
|
+
class PatchedStringIO < StringIO #:nodoc:
|
|
228
|
+
|
|
229
|
+
alias_method :orig_read_nonblock, :read_nonblock
|
|
230
|
+
|
|
231
|
+
def read_nonblock(size, *args)
|
|
232
|
+
args.reject! {|arg| !arg.is_a?(Hash)}
|
|
233
|
+
orig_read_nonblock(size, *args)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
class StubSocket #:nodoc:
|
|
239
|
+
|
|
240
|
+
attr_accessor :read_timeout, :continue_timeout, :write_timeout
|
|
241
|
+
|
|
242
|
+
def initialize(*args)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def closed?
|
|
246
|
+
@closed ||= true
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def close
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def readuntil(*args)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
module Net #:nodoc: all
|
|
258
|
+
|
|
259
|
+
class WebMockNetBufferedIO < BufferedIO
|
|
260
|
+
def initialize(io, *args)
|
|
261
|
+
io = case io
|
|
262
|
+
when Socket, OpenSSL::SSL::SSLSocket, IO
|
|
263
|
+
io
|
|
264
|
+
when StringIO
|
|
265
|
+
PatchedStringIO.new(io.string)
|
|
266
|
+
when String
|
|
267
|
+
PatchedStringIO.new(io)
|
|
268
|
+
end
|
|
269
|
+
raise "Unable to create local socket" unless io
|
|
270
|
+
|
|
271
|
+
super
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
if RUBY_VERSION >= '2.6.0'
|
|
275
|
+
def rbuf_fill
|
|
276
|
+
current_thread_id = Thread.current.object_id
|
|
277
|
+
|
|
278
|
+
trace = TracePoint.trace(:line) do |tp|
|
|
279
|
+
next unless Thread.current.object_id == current_thread_id
|
|
280
|
+
if tp.binding.local_variable_defined?(:tmp)
|
|
281
|
+
tp.binding.local_variable_set(:tmp, nil)
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
super
|
|
286
|
+
ensure
|
|
287
|
+
trace.disable
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
module WebMock
|
|
296
|
+
module NetHTTPUtility
|
|
297
|
+
|
|
298
|
+
def self.request_signature_from_request(net_http, request, body = nil)
|
|
299
|
+
protocol = net_http.use_ssl? ? "https" : "http"
|
|
300
|
+
|
|
301
|
+
path = request.path
|
|
302
|
+
|
|
303
|
+
if path.respond_to?(:request_uri) #https://github.com/bblimke/webmock/issues/288
|
|
304
|
+
path = path.request_uri
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
path = WebMock::Util::URI.heuristic_parse(path).request_uri if path =~ /^http/
|
|
308
|
+
|
|
309
|
+
uri = "#{protocol}://#{net_http.address}:#{net_http.port}#{path}"
|
|
310
|
+
method = request.method.downcase.to_sym
|
|
311
|
+
|
|
312
|
+
headers = Hash[*request.to_hash.map {|k,v| [k, v]}.inject([]) {|r,x| r + x}]
|
|
313
|
+
validate_headers(headers)
|
|
314
|
+
|
|
315
|
+
if request.body_stream
|
|
316
|
+
body = request.body_stream.read
|
|
317
|
+
request.body_stream = nil
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
if body != nil && body.respond_to?(:read)
|
|
321
|
+
request.set_body_internal body.read
|
|
322
|
+
else
|
|
323
|
+
request.set_body_internal body
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
WebMock::RequestSignature.new(method, uri, body: request.body, headers: headers)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def self.validate_headers(headers)
|
|
330
|
+
# For Ruby versions < 2.3.0, if you make a request with headers that are symbols
|
|
331
|
+
# Net::HTTP raises a NoMethodError
|
|
332
|
+
#
|
|
333
|
+
# WebMock normalizes headers when creating a RequestSignature,
|
|
334
|
+
# and will update all headers from symbols to strings.
|
|
335
|
+
#
|
|
336
|
+
# This could create a false positive in a test suite with WebMock.
|
|
337
|
+
#
|
|
338
|
+
# So before this point, WebMock raises an ArgumentError if any of the headers are symbols
|
|
339
|
+
# instead of the cryptic NoMethodError "undefined method `split' ...` from Net::HTTP
|
|
340
|
+
if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.3.0')
|
|
341
|
+
header_as_symbol = headers.keys.find {|header| header.is_a? Symbol}
|
|
342
|
+
if header_as_symbol
|
|
343
|
+
raise ArgumentError.new("Net:HTTP does not accept headers as symbols")
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def self.check_right_http_connection
|
|
349
|
+
@was_right_http_connection_loaded = defined?(RightHttpConnection)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def self.puts_warning_for_right_http_if_needed
|
|
353
|
+
if !@was_right_http_connection_loaded && defined?(RightHttpConnection)
|
|
354
|
+
$stderr.puts "\nWarning: RightHttpConnection has to be required before WebMock is required !!!\n"
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
WebMock::NetHTTPUtility.check_right_http_connection
|