webmock 3.6.0 → 3.7.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 137bc694f0b4f457b84a5fc6f93a7b2227ff19bcb6e8bd1525244649df56898c
4
- data.tar.gz: f998d2cd340cffd2637bcc3cf8cfe322c85de1055d07b51c7e193acde549d340
3
+ metadata.gz: 27c0b6ee25eb2a1a31df70a1725d3fcda71aec62460d79b3ba7e05109d602fc1
4
+ data.tar.gz: 07a3ae5f5d93e5c5b86ddae8ab4f351c48777d98a80d4f997faa062b5ca3619a
5
5
  SHA512:
6
- metadata.gz: 9b36a8ce4d2b4b779e89f5e7db1ed1c8e17817f1088fcd9d92e8f2154373a254292240dffc0d7f376fb86c1230f0371aefa6a56163710cc2ed86301915270b52
7
- data.tar.gz: 54d26c28e44ebec703628a4473f4bc1547f7c6fad2eeefbffea77398fed62759f131f94bd7fceb78275a8be70d30c94586383ecb43c1f16882a8dfe4e89dcf53
6
+ metadata.gz: 13c2debfa3694d911cb44abb89be6f205427dc952fa3e3680d5a0035807c5443f2dace34fe2135f5ecd53bf6da6e206b90f7ee9231f6a8251d8ac79d4ce00e1a
7
+ data.tar.gz: 7bdd1a5b5df68f92eb75ef2686a95cf0a40423d603177470e2940c0317f87e3b73aba8d92547eaad34d3a5225d8627ac026e964a09280d7259c5b272321619c0
@@ -5,12 +5,13 @@ rvm:
5
5
  - 2.3.8
6
6
  - 2.4.6
7
7
  - 2.5.5
8
- - 2.6.2
8
+ - 2.6.3
9
9
  - rbx-2
10
10
  - ruby-head
11
11
  - jruby-9.1.17.0
12
- - jruby-9.2.6.0
12
+ - jruby-9.2.7.0
13
13
  - jruby-head
14
+ jdk: openjdk8
14
15
  matrix:
15
16
  allow_failures:
16
17
  - rvm: jruby-head
@@ -1,5 +1,73 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.7.5
4
+
5
+ * Suppress Excon warning generated by extra key
6
+
7
+ Thanks to [Marco Costa](https://github.com/marcotc)
8
+
9
+ ## 3.7.4
10
+
11
+ * Resetting memoized response fields in Curb adapter.
12
+
13
+ Thanks to [Andrei Sidorov](https://github.com/heretge)
14
+
15
+ ## 3.7.3
16
+
17
+ * Fix for http.rb. Allow passing an output buffer to HTTP::Response::Body#readpartial
18
+
19
+ Thanks to [George Claghorn](https://github.com/georgeclaghorn)
20
+
21
+ * Fixed Manticore adapter to invoke Manticore failure handler on stubbed timeout
22
+
23
+ Thanks to [Alex Junger](https://github.com/alexJunger)
24
+
25
+ * Added project metadata to the gemspec
26
+
27
+ Thanks to [Orien Madgwick](https://github.com/orien)
28
+
29
+ ## 3.7.2
30
+
31
+ * Fixed handling of non UTF-8 encoded urls
32
+
33
+ Thanks to [Rafael França](https://github.com/rafaelfranca)
34
+
35
+ * Fixed "shadowing outer local variable" warning
36
+
37
+ Thanks to [y-yagi](https://github.com/y-yagi)
38
+
39
+ ## 3.7.1
40
+
41
+ * Fixed Async::HTTP::Client adapter code to not cause Ruby warning
42
+
43
+ Thanks to [y-yagi](https://github.com/y-yagi)
44
+
45
+ ## 3.7.0
46
+
47
+ * Support for Async::HTTP::Client
48
+
49
+ Thanks to [Andriy Yanko](https://github.com/ayanko)
50
+
51
+ ## 3.6.2
52
+
53
+ * Fixed Patron adapter to handle HTTP/2 status line.
54
+
55
+ Thanks to [Fábio D. Batista](https://github.com/fabiob)
56
+
57
+ ## 3.6.1
58
+
59
+ * Fixed issue with matching Addressable::Template without a period in the domain
60
+
61
+ Thanks to [Eike Send](https://github.com/eikes)
62
+
63
+ * Support for `write_timeout` in Net::HTTP
64
+
65
+ Thanks to [Claudio Poli](https://github.com/masterkain)
66
+
67
+ * Fixed issue with handling urls with ":80" or ":443" in the path.
68
+
69
+ Thanks to [Csaba Apagyi](https://github.com/thisismydesign) for reporting and to [Frederick Cheung](https://github.com/fcheung) for fixing the issue.
70
+
3
71
  ## 3.6.0
4
72
 
5
73
  * Compatibility with the latest version of hashdiff gem, with constant changed from HashDiff to Hashdiff
data/README.md CHANGED
@@ -33,6 +33,7 @@ Supported HTTP libraries
33
33
  * Excon
34
34
  * HTTP Gem
35
35
  * Manticore
36
+ * Async::HTTP::Client
36
37
 
37
38
  Supported Ruby Interpreters
38
39
  ---------------------------
@@ -878,6 +879,10 @@ end
878
879
 
879
880
  Please submit them here [http://github.com/bblimke/webmock/issues](http://github.com/bblimke/webmock/issues)
880
881
 
882
+ ## Issue triage [![Open Source Helpers](https://www.codetriage.com/bblimke/webmock/badges/users.svg)](https://www.codetriage.com/bblimke/webmock)
883
+
884
+ You can contribute by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to webmock on CodeTriage](https://www.codetriage.com/bblimke/webmock).
885
+
881
886
  ## Suggestions
882
887
 
883
888
  If you have any suggestions on how to improve WebMock please send an email to the mailing list [groups.google.com/group/webmock-users](http://groups.google.com/group/webmock-users)
@@ -1096,6 +1101,19 @@ People who submitted patches and new features or suggested improvements. Many th
1096
1101
  * Pavel Valena
1097
1102
  * Adam Sokolnicki
1098
1103
  * Jeff Felchner
1104
+ * Eike Send
1105
+ * Claudio Poli
1106
+ * Csaba Apagyi
1107
+ * Frederick Cheung
1108
+ * Fábio D. Batista
1109
+ * Andriy Yanko
1110
+ * y-yagi
1111
+ * Rafael França
1112
+ * George Claghorn
1113
+ * Alex Junger
1114
+ * Orien Madgwick
1115
+ * Andrei Sidorov
1116
+ * Marco Costa
1099
1117
 
1100
1118
  For a full list of contributors you can visit the
1101
1119
  [contributors](https://github.com/bblimke/webmock/contributors) page.
@@ -54,5 +54,6 @@ require_relative 'webmock/http_lib_adapters/em_http_request_adapter'
54
54
  require_relative 'webmock/http_lib_adapters/typhoeus_hydra_adapter'
55
55
  require_relative 'webmock/http_lib_adapters/excon_adapter'
56
56
  require_relative 'webmock/http_lib_adapters/manticore_adapter'
57
+ require_relative 'webmock/http_lib_adapters/async_http_client_adapter'
57
58
 
58
59
  require_relative 'webmock/webmock'
@@ -0,0 +1,214 @@
1
+ begin
2
+ require 'async'
3
+ require 'async/http'
4
+ rescue LoadError
5
+ # async-http not found
6
+ end
7
+
8
+ if defined?(Async::HTTP)
9
+ module WebMock
10
+ module HttpLibAdapters
11
+ class AsyncHttpClientAdapter < HttpLibAdapter
12
+ adapter_for :async_http_client
13
+
14
+ OriginalAsyncHttpClient = Async::HTTP::Client unless const_defined?(:OriginalAsyncHttpClient)
15
+
16
+ class << self
17
+ def enable!
18
+ Async::HTTP.send(:remove_const, :Client)
19
+ Async::HTTP.send(:const_set, :Client, Async::HTTP::WebMockClientWrapper)
20
+ end
21
+
22
+ def disable!
23
+ Async::HTTP.send(:remove_const, :Client)
24
+ Async::HTTP.send(:const_set, :Client, OriginalAsyncHttpClient)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ module Async
32
+ module HTTP
33
+ class WebMockClientWrapper < Client
34
+ def initialize(
35
+ endpoint,
36
+ protocol = endpoint.protocol,
37
+ scheme = endpoint.scheme,
38
+ authority = endpoint.authority,
39
+ options = {}
40
+ )
41
+ webmock_endpoint = WebMockEndpoint.new(scheme, authority, protocol)
42
+
43
+ @network_client = WebMockClient.new(endpoint, protocol, scheme, authority, options)
44
+ @webmock_client = WebMockClient.new(webmock_endpoint, protocol, scheme, authority, options)
45
+
46
+ @scheme = scheme
47
+ @authority = authority
48
+ end
49
+
50
+ def call(request)
51
+ request.scheme ||= self.scheme
52
+ request.authority ||= self.authority
53
+
54
+ request_signature = build_request_signature(request)
55
+ WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
56
+ webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
57
+ net_connect_allowed = WebMock.net_connect_allowed?(request_signature.uri)
58
+
59
+ if webmock_response
60
+ webmock_response.raise_error_if_any
61
+ raise Async::TimeoutError, 'WebMock timeout error' if webmock_response.should_timeout
62
+ WebMockApplication.add_webmock_response(request, webmock_response)
63
+ response = @webmock_client.call(request)
64
+ elsif net_connect_allowed
65
+ response = @network_client.call(request)
66
+ else
67
+ raise WebMock::NetConnectNotAllowedError.new(request_signature) unless webmock_response
68
+ end
69
+
70
+ if WebMock::CallbackRegistry.any_callbacks?
71
+ webmock_response ||= build_webmock_response(response)
72
+ WebMock::CallbackRegistry.invoke_callbacks(
73
+ {
74
+ lib: :async_http_client,
75
+ real_request: net_connect_allowed
76
+ },
77
+ request_signature,
78
+ webmock_response
79
+ )
80
+ end
81
+
82
+ response
83
+ end
84
+
85
+ def close
86
+ @network_client.close
87
+ @webmock_client.close
88
+ end
89
+
90
+ private
91
+
92
+ def build_request_signature(request)
93
+ body = request.read
94
+ request.body = ::Protocol::HTTP::Body::Buffered.wrap(body)
95
+ WebMock::RequestSignature.new(
96
+ request.method.downcase.to_sym,
97
+ "#{request.scheme}://#{request.authority}#{request.path}",
98
+ headers: request.headers.to_h,
99
+ body: body
100
+ )
101
+ end
102
+
103
+ def build_webmock_response(response)
104
+ body = response.read
105
+ response.body = ::Protocol::HTTP::Body::Buffered.wrap(body)
106
+
107
+ webmock_response = WebMock::Response.new
108
+ webmock_response.status = [
109
+ response.status,
110
+ ::Protocol::HTTP1::Reason::DESCRIPTIONS[response.status]
111
+ ]
112
+ webmock_response.headers = build_webmock_response_headers(response)
113
+ webmock_response.body = body
114
+ webmock_response
115
+ end
116
+
117
+ def build_webmock_response_headers(response)
118
+ response.headers.each.each_with_object({}) do |(k, v), o|
119
+ o[k] ||= []
120
+ o[k] << v
121
+ end
122
+ end
123
+ end
124
+
125
+ class WebMockClient < Client
126
+ end
127
+
128
+ class WebMockEndpoint
129
+ def initialize(scheme, authority, protocol)
130
+ @scheme = scheme
131
+ @authority = authority
132
+ @protocol = protocol
133
+ end
134
+
135
+ attr :scheme, :authority, :protocol
136
+
137
+ def connect
138
+ server_socket, client_socket = create_connected_sockets
139
+ Async do
140
+ accept_socket(server_socket)
141
+ end
142
+ client_socket
143
+ end
144
+
145
+ def inspect
146
+ "\#<#{self.class}> #{scheme}://#{authority} protocol=#{protocol}"
147
+ end
148
+
149
+ private
150
+
151
+ def create_connected_sockets
152
+ Async::IO::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM).tap do |sockets|
153
+ sockets.each do |socket|
154
+ socket.instance_variable_set :@alpn_protocol, @alpn_protocol
155
+ socket.instance_eval do
156
+ def alpn_protocol
157
+ nil # means HTTP11 will be used for HTTPS
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ def accept_socket(socket)
165
+ server = Async::HTTP::Server.new(WebMockApplication, self)
166
+ server.accept(socket, socket.remote_address)
167
+ end
168
+ end
169
+
170
+ module WebMockApplication
171
+ WEBMOCK_REQUEST_ID_HEADER = 'x-webmock-request-id'.freeze
172
+
173
+ class << self
174
+ def call(request)
175
+ request.read
176
+ webmock_response = get_webmock_response(request)
177
+ build_response(webmock_response)
178
+ end
179
+
180
+ def add_webmock_response(request, webmock_response)
181
+ webmock_request_id = request.object_id.to_s
182
+ request.headers.add(WEBMOCK_REQUEST_ID_HEADER, webmock_request_id)
183
+ webmock_responses[webmock_request_id] = webmock_response
184
+ end
185
+
186
+ def get_webmock_response(request)
187
+ webmock_request_id = request.headers[WEBMOCK_REQUEST_ID_HEADER][0]
188
+ webmock_responses.fetch(webmock_request_id)
189
+ end
190
+
191
+ private
192
+
193
+ def webmock_responses
194
+ @webmock_responses ||= {}
195
+ end
196
+
197
+ def build_response(webmock_response)
198
+ headers = (webmock_response.headers || {}).each_with_object([]) do |(k, value), o|
199
+ Array(value).each do |v|
200
+ o.push [k, v]
201
+ end
202
+ end
203
+
204
+ ::Protocol::HTTP::Response[
205
+ webmock_response.status[0],
206
+ headers,
207
+ webmock_response.body
208
+ ]
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -340,6 +340,10 @@ if defined?(Curl)
340
340
 
341
341
  def reset
342
342
  instance_variable_set(:@body_str, nil)
343
+ instance_variable_set(:@content_type, nil)
344
+ instance_variable_set(:@header_str, nil)
345
+ instance_variable_set(:@last_effective_url, nil)
346
+ instance_variable_set(:@response_code, nil)
343
347
  super
344
348
  end
345
349
  end
@@ -107,7 +107,7 @@ if defined?(EventMachine::HttpClient)
107
107
  @uri ||= nil
108
108
  EM.next_tick {
109
109
  setup(make_raw_response(stubbed_webmock_response), @uri,
110
- stubbed_webmock_response.should_timeout ? "WebMock timeout error" : nil)
110
+ stubbed_webmock_response.should_timeout ? Errno::ETIMEDOUT : nil)
111
111
  }
112
112
  self
113
113
  elsif WebMock.net_connect_allowed?(request_signature.uri)
@@ -159,4 +159,7 @@ if defined?(Excon)
159
159
  end
160
160
  end
161
161
  end
162
+
163
+ # Suppresses Excon connection argument validation warning
164
+ Excon::VALID_CONNECTION_KEYS << :__construction_args
162
165
  end
@@ -5,7 +5,7 @@ module HTTP
5
5
  @io = StringIO.new str
6
6
  end
7
7
 
8
- def readpartial(size = nil)
8
+ def readpartial(size = nil, outbuf = nil)
9
9
  unless size
10
10
  if defined?(HTTP::Client::BUFFER_SIZE)
11
11
  size = HTTP::Client::BUFFER_SIZE
@@ -14,7 +14,7 @@ module HTTP
14
14
  end
15
15
  end
16
16
 
17
- @io.read size
17
+ @io.read size, outbuf
18
18
  end
19
19
 
20
20
  def close
@@ -24,6 +24,12 @@ if defined?(Manticore)
24
24
  Manticore.instance_variable_set(:@manticore_facade, OriginalManticoreClient.new)
25
25
  end
26
26
 
27
+ class StubbedTimeoutResponse < Manticore::StubbedResponse
28
+ def call
29
+ @handlers[:failure].call(Manticore::ConnectTimeout.new("Too slow (mocked timeout)"))
30
+ end
31
+ end
32
+
27
33
  class WebMockManticoreClient < Manticore::Client
28
34
  def request(klass, url, options={}, &block)
29
35
  super(klass, WebMock::Util::URI.normalize_uri(url).to_s, format_options(options))
@@ -50,19 +56,22 @@ if defined?(Manticore)
50
56
 
51
57
  if webmock_response = registered_response_for(request_signature)
52
58
  webmock_response.raise_error_if_any
53
- manticore_response = generate_manticore_response(webmock_response).call
54
- real_request = false
59
+ manticore_response = generate_manticore_response(webmock_response)
60
+ manticore_response.on_success do
61
+ WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: false}, request_signature, webmock_response)
62
+ end
55
63
 
56
64
  elsif real_request_allowed?(request_signature.uri)
57
- manticore_response = Manticore::Response.new(self, request, context, &block).call
58
- webmock_response = generate_webmock_response(manticore_response)
59
- real_request = true
65
+ manticore_response = Manticore::Response.new(self, request, context, &block)
66
+ manticore_response.on_complete do |completed_response|
67
+ webmock_response = generate_webmock_response(completed_response)
68
+ WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: true}, request_signature, webmock_response)
69
+ end
60
70
 
61
71
  else
62
72
  raise WebMock::NetConnectNotAllowedError.new(request_signature)
63
73
  end
64
74
 
65
- WebMock::CallbackRegistry.invoke_callbacks({lib: :manticore, real_request: real_request}, request_signature, webmock_response)
66
75
  manticore_response
67
76
  end
68
77
 
@@ -103,14 +112,16 @@ if defined?(Manticore)
103
112
  end
104
113
 
105
114
  def generate_manticore_response(webmock_response)
106
- raise Manticore::ConnectTimeout if webmock_response.should_timeout
107
-
108
- Manticore::StubbedResponse.stub(
109
- code: webmock_response.status[0],
110
- body: webmock_response.body,
111
- headers: webmock_response.headers,
112
- cookies: {}
113
- )
115
+ if webmock_response.should_timeout
116
+ StubbedTimeoutResponse.new
117
+ else
118
+ Manticore::StubbedResponse.stub(
119
+ code: webmock_response.status[0],
120
+ body: webmock_response.body,
121
+ headers: webmock_response.headers,
122
+ cookies: {}
123
+ )
124
+ end
114
125
  end
115
126
 
116
127
  def generate_webmock_response(manticore_response)