webmock 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
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