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.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +34 -0
  4. data/.rspec-tm +2 -0
  5. data/.travis.yml +19 -0
  6. data/CHANGELOG.md +1698 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE +20 -0
  9. data/README.md +1125 -0
  10. data/Rakefile +28 -0
  11. data/lib/webmock.rb +59 -0
  12. data/lib/webmock/api.rb +109 -0
  13. data/lib/webmock/assertion_failure.rb +11 -0
  14. data/lib/webmock/callback_registry.rb +35 -0
  15. data/lib/webmock/config.rb +18 -0
  16. data/lib/webmock/cucumber.rb +10 -0
  17. data/lib/webmock/deprecation.rb +9 -0
  18. data/lib/webmock/errors.rb +17 -0
  19. data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +214 -0
  20. data/lib/webmock/http_lib_adapters/curb_adapter.rb +347 -0
  21. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +228 -0
  22. data/lib/webmock/http_lib_adapters/excon_adapter.rb +162 -0
  23. data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  24. data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  25. data/lib/webmock/http_lib_adapters/http_rb/client.rb +14 -0
  26. data/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
  27. data/lib/webmock/http_lib_adapters/http_rb/response.rb +43 -0
  28. data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
  29. data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
  30. data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
  31. data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +242 -0
  32. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +130 -0
  33. data/lib/webmock/http_lib_adapters/net_http.rb +361 -0
  34. data/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
  35. data/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
  36. data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
  37. data/lib/webmock/matchers/any_arg_matcher.rb +13 -0
  38. data/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
  39. data/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
  40. data/lib/webmock/matchers/hash_including_matcher.rb +17 -0
  41. data/lib/webmock/minitest.rb +41 -0
  42. data/lib/webmock/rack_response.rb +69 -0
  43. data/lib/webmock/request_body_diff.rb +64 -0
  44. data/lib/webmock/request_execution_verifier.rb +77 -0
  45. data/lib/webmock/request_pattern.rb +370 -0
  46. data/lib/webmock/request_registry.rb +35 -0
  47. data/lib/webmock/request_signature.rb +54 -0
  48. data/lib/webmock/request_signature_snippet.rb +61 -0
  49. data/lib/webmock/request_stub.rb +100 -0
  50. data/lib/webmock/response.rb +153 -0
  51. data/lib/webmock/responses_sequence.rb +40 -0
  52. data/lib/webmock/rspec.rb +41 -0
  53. data/lib/webmock/rspec/matchers.rb +27 -0
  54. data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
  55. data/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
  56. data/lib/webmock/stub_registry.rb +67 -0
  57. data/lib/webmock/stub_request_snippet.rb +38 -0
  58. data/lib/webmock/test_unit.rb +22 -0
  59. data/lib/webmock/util/hash_counter.rb +39 -0
  60. data/lib/webmock/util/hash_keys_stringifier.rb +25 -0
  61. data/lib/webmock/util/hash_validator.rb +17 -0
  62. data/lib/webmock/util/headers.rb +64 -0
  63. data/lib/webmock/util/json.rb +67 -0
  64. data/lib/webmock/util/query_mapper.rb +281 -0
  65. data/lib/webmock/util/uri.rb +110 -0
  66. data/lib/webmock/util/values_stringifier.rb +20 -0
  67. data/lib/webmock/util/version_checker.rb +111 -0
  68. data/lib/webmock/version.rb +3 -0
  69. data/lib/webmock/webmock.rb +161 -0
  70. data/minitest/test_helper.rb +34 -0
  71. data/minitest/test_webmock.rb +9 -0
  72. data/minitest/webmock_spec.rb +60 -0
  73. data/spec/acceptance/async_http_client/async_http_client_spec.rb +349 -0
  74. data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
  75. data/spec/acceptance/curb/curb_spec.rb +492 -0
  76. data/spec/acceptance/curb/curb_spec_helper.rb +147 -0
  77. data/spec/acceptance/em_http_request/em_http_request_spec.rb +406 -0
  78. data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
  79. data/spec/acceptance/excon/excon_spec.rb +77 -0
  80. data/spec/acceptance/excon/excon_spec_helper.rb +50 -0
  81. data/spec/acceptance/http_rb/http_rb_spec.rb +82 -0
  82. data/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
  83. data/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
  84. data/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
  85. data/spec/acceptance/manticore/manticore_spec.rb +56 -0
  86. data/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
  87. data/spec/acceptance/net_http/net_http_shared.rb +153 -0
  88. data/spec/acceptance/net_http/net_http_spec.rb +331 -0
  89. data/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
  90. data/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
  91. data/spec/acceptance/patron/patron_spec.rb +125 -0
  92. data/spec/acceptance/patron/patron_spec_helper.rb +54 -0
  93. data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
  94. data/spec/acceptance/shared/callbacks.rb +148 -0
  95. data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
  96. data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
  97. data/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
  98. data/spec/acceptance/shared/request_expectations.rb +930 -0
  99. data/spec/acceptance/shared/returning_declared_responses.rb +409 -0
  100. data/spec/acceptance/shared/stubbing_requests.rb +643 -0
  101. data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
  102. data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
  103. data/spec/acceptance/webmock_shared.rb +41 -0
  104. data/spec/fixtures/test.txt +1 -0
  105. data/spec/quality_spec.rb +84 -0
  106. data/spec/spec_helper.rb +48 -0
  107. data/spec/support/example_curl_output.txt +22 -0
  108. data/spec/support/failures.rb +9 -0
  109. data/spec/support/my_rack_app.rb +53 -0
  110. data/spec/support/network_connection.rb +19 -0
  111. data/spec/support/webmock_server.rb +70 -0
  112. data/spec/unit/api_spec.rb +175 -0
  113. data/spec/unit/errors_spec.rb +129 -0
  114. data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
  115. data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  116. data/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
  117. data/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
  118. data/spec/unit/rack_response_spec.rb +112 -0
  119. data/spec/unit/request_body_diff_spec.rb +90 -0
  120. data/spec/unit/request_execution_verifier_spec.rb +208 -0
  121. data/spec/unit/request_pattern_spec.rb +601 -0
  122. data/spec/unit/request_registry_spec.rb +95 -0
  123. data/spec/unit/request_signature_snippet_spec.rb +89 -0
  124. data/spec/unit/request_signature_spec.rb +155 -0
  125. data/spec/unit/request_stub_spec.rb +199 -0
  126. data/spec/unit/response_spec.rb +282 -0
  127. data/spec/unit/stub_registry_spec.rb +103 -0
  128. data/spec/unit/stub_request_snippet_spec.rb +115 -0
  129. data/spec/unit/util/hash_counter_spec.rb +39 -0
  130. data/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
  131. data/spec/unit/util/headers_spec.rb +28 -0
  132. data/spec/unit/util/json_spec.rb +33 -0
  133. data/spec/unit/util/query_mapper_spec.rb +157 -0
  134. data/spec/unit/util/uri_spec.rb +361 -0
  135. data/spec/unit/util/version_checker_spec.rb +65 -0
  136. data/spec/unit/webmock_spec.rb +19 -0
  137. data/test/http_request.rb +24 -0
  138. data/test/shared_test.rb +108 -0
  139. data/test/test_helper.rb +23 -0
  140. data/test/test_webmock.rb +6 -0
  141. data/webmock.gemspec +45 -0
  142. 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