webmock 3.8.3 → 3.14.0

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/CI.yml +37 -0
  3. data/CHANGELOG.md +132 -0
  4. data/Gemfile +1 -1
  5. data/README.md +70 -30
  6. data/Rakefile +12 -2
  7. data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +7 -5
  8. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +6 -3
  9. data/lib/webmock/http_lib_adapters/http_rb/client.rb +4 -1
  10. data/lib/webmock/http_lib_adapters/http_rb/response.rb +13 -2
  11. data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +1 -1
  12. data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +23 -6
  13. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +8 -1
  14. data/lib/webmock/http_lib_adapters/net_http.rb +17 -3
  15. data/lib/webmock/request_pattern.rb +77 -46
  16. data/lib/webmock/response.rb +11 -5
  17. data/lib/webmock/rspec.rb +2 -1
  18. data/lib/webmock/stub_registry.rb +26 -11
  19. data/lib/webmock/test_unit.rb +1 -3
  20. data/lib/webmock/version.rb +1 -1
  21. data/lib/webmock/webmock.rb +5 -3
  22. data/spec/acceptance/async_http_client/async_http_client_spec.rb +27 -1
  23. data/spec/acceptance/em_http_request/em_http_request_spec.rb +56 -0
  24. data/spec/acceptance/manticore/manticore_spec.rb +32 -0
  25. data/spec/acceptance/net_http/net_http_spec.rb +38 -0
  26. data/spec/acceptance/patron/patron_spec_helper.rb +2 -2
  27. data/spec/acceptance/shared/stubbing_requests.rb +35 -0
  28. data/spec/unit/request_pattern_spec.rb +171 -48
  29. data/spec/unit/response_spec.rb +22 -18
  30. data/spec/unit/webmock_spec.rb +52 -11
  31. data/test/test_webmock.rb +6 -0
  32. data/webmock.gemspec +2 -1
  33. metadata +25 -11
  34. data/.travis.yml +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c101b3661b9aeb49e30e85da73705637944747d62eef4d463a9c30866431b10
4
- data.tar.gz: 3c2a7ae9e28143b97b83c5a93cc14950748dc68969790d80f0d62a28600d7a5a
3
+ metadata.gz: a8f150fbeccca419468dfebe632e3b5d365cb8c2df9a5e2a31e65591298786fb
4
+ data.tar.gz: d92950bc5ae3510e599c40545f3e7a0ebaafa54a698f79a3c82243e240d35948
5
5
  SHA512:
6
- metadata.gz: 60174ed92a21c2f304d29e4d00edb7447eae871b37ddc2bb6b0a4704bf42492c9632913cee2c040644e6decc95242f39bf32728fe0df3b34d936cc9f78a42f2f
7
- data.tar.gz: e7c4dc5363ec3f8028852b1d2173b214742bc03ca2ee25599a6d38d8c3a291f517890168dc74a69cd4f90f3f840e94fdd857941ab853a833ae5d77bc8282e464
6
+ metadata.gz: f58d569f7c633d758cee725e5dafb39edacb74e0017ba9c29de0cad8fe16d1f7740cc30847a9f129f6571232d2ca8172d7fb76a1eb3383e31ee8371472f141f9
7
+ data.tar.gz: 52191c4e12ac3bf79b575f36d58823ea37ab17f83c7a62602889f361eafadabfa4b0b8ffc1f466eee6de53ea77578fc0149a60e14abdd8a7459b651afbeb85d0
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby:
16
+ - head
17
+ - '3.0'
18
+ - '2.7'
19
+ - '2.6'
20
+ - '2.5'
21
+ - jruby
22
+ continue-on-error: ${{ matrix.ruby == 'head' }}
23
+ name: Ruby ${{ matrix.ruby }}
24
+ env:
25
+ JRUBY_OPTS: "--debug"
26
+ steps:
27
+ - uses: actions/checkout@v2
28
+ - name: Install Apt Packages
29
+ run: |
30
+ sudo apt-get install libcurl4-openssl-dev -y
31
+ - uses: ruby/setup-ruby@v1
32
+ continue-on-error: true
33
+ with:
34
+ ruby-version: ${{ matrix.ruby }}
35
+ bundler-cache: true
36
+ - run: |
37
+ bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,137 @@
1
1
  # Changelog
2
2
 
3
+ # 3.14.0
4
+
5
+ * Bump Addressable from 2.3.6 to 2.8.0
6
+
7
+ Thanks to [Eduardo Hernandez](https://github.com/EduardoGHdez)
8
+
9
+ # 3.13.0
10
+
11
+ * Support http.rb 5.x
12
+
13
+ Thanks to [Will Storey](https://github.com/horgh)
14
+
15
+ # 3.12.2
16
+
17
+ * Fixed em-http-request adapter to avoid calling middleware twice.
18
+
19
+ Thanks to [Alex Vondrak](https://github.com/ajvondrak)
20
+
21
+ # 3.12.1
22
+
23
+ * Fixed handling of URIs with IPv6 addresses with square brackets when in Net::HTTP adapter.
24
+
25
+ Thanks to [Johanna Hartmann](https://github.com/JohannaHartmann)
26
+
27
+ # 3.12.0
28
+
29
+ * Added support for handling custom JSON and XML content types e.g. 'application/vnd.api+json'
30
+
31
+ # 3.11.3
32
+
33
+ * Fixed async-http adapter to only considered requests as real if they are real.
34
+
35
+ Thanks to Thanks to [Tony Schneider](https://github.com/tonywok) and [Samuel Williams](https://github.com/ioquatix)
36
+
37
+ # 3.11.2
38
+
39
+ * Fix for Manticore streaming mode
40
+
41
+ Thanks to [Oleksiy Kovyrin](https://github.com/kovyrin)
42
+
43
+ # 3.11.1
44
+
45
+ * Compatibility with async-http 0.54+
46
+
47
+ Thanks to [Jun Jiang](https://github.com/jasl)
48
+
49
+ # 3.11.0
50
+
51
+ * Added support for `features` in http.rb adapter.
52
+
53
+ Thanks to [Carl (ce07c3)](https://github.com/ce07c3)
54
+
55
+ # 3.10.0
56
+
57
+ * Added option to global stubs to have lower priority than local stubs.
58
+
59
+ WebMock.globally_stub_request(:after_local_stubs) do
60
+ { body: "global stub body" }
61
+ end
62
+
63
+ stub_request(:get, "www.example.com").to_return(body: 'non-global stub body')
64
+
65
+ expect(http_request(:get, "http://www.example.com/").body).to eq("non-global stub body")
66
+
67
+ Thanks to [Marek Kasztelnik](https://github.com/mkasztelnik)
68
+
69
+ # 3.9.5
70
+
71
+ * Prevent overwriting `teardown` method in Test::Unit
72
+
73
+ Thanks to [Jesse Bowes](https://github.com/jessebs)
74
+
75
+ # 3.9.4
76
+
77
+ * More intuitive error message when stubbed response body was provided as Hash
78
+
79
+ Thanks to [Ben Koshy](https://github.com/BKSpurgeon)
80
+
81
+ # 3.9.3
82
+
83
+ * Make httpclient_adapter thread-safe
84
+
85
+ Thanks to [Adam Harwood](https://github.com/adam-harwood)
86
+
87
+ # 3.9.2
88
+
89
+ * Made global stubs thread-safe
90
+
91
+ Thanks to [Adam Harwood](https://github.com/adam-harwood)
92
+
93
+ # 3.9.1
94
+
95
+ * Fixed support for passing `URI` objects as second argument of `stub_request`
96
+
97
+ Thanks to [Ryan Kerr](https://github.com/leboshi)
98
+
99
+ ## 3.9.0
100
+
101
+ * Allow using a "callable" (like a proc) as URI pattern
102
+
103
+ stub_request(:any, ->(uri) { true })
104
+
105
+ Thanks to [John Hawthorn](https://github.com/jhawthorn)
106
+
107
+ * Added stubbed IO on stubbed socket in Net::HTTP adapter.
108
+
109
+ Thanks to [Thilo Rusche](https://github.com/trusche)
110
+
111
+ * When 'webmock/rspec' is required, reset WebMock after all after(:each/example) hooks
112
+
113
+ Thanks to [Andrew Stuntz](https://github.com/drews256)
114
+
115
+ * Fixed `net_connect_allowed?` when invoked with no arguments, when there were any allowed URIs passed to `disable_net_connect?`.
116
+
117
+ Thanks to [Lucas Uyezu](https://github.com/lucasuyezu)
118
+
119
+ * Fixed async-http adapter which caused Async::HTTP::Client or Async::HTTP::Internet to hang and never return a response.
120
+
121
+ Thanks to [Bruno Sutic](https://github.com/bruno-) and [Samuel Williams](https://github.com/ioquatix)
122
+
123
+ * Fixed warning when using async-http adapter
124
+
125
+ Thanks to [Bruno Sutic](https://github.com/bruno-)
126
+
127
+ * Dropped support for Ruby 2.3 - EOL date: 2019-03-31
128
+
129
+ * Dropped support for Ruby 2.4 - EOL date: 2020-03-31
130
+
131
+ * Handling matching of Addressable::Template patterns that have an ip address without port and patterns that have ip address and don’t have schema and path.
132
+
133
+ Thanks to [Rafael França](https://github.com/rafaelfranca) and [guppy0356](https://github.com/guppy0356)
134
+
3
135
  ## 3.8.3
4
136
 
5
137
  * Fixed problem introduced in version 3.4.2, which caused matching against Addressable::Template representing host part of the URI to raise an error.
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'http://rubygems.org/'
1
+ source 'https://rubygems.org/'
2
2
 
3
3
  gemspec
4
4
 
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  WebMock
2
2
  =======
3
3
  [![Gem Version](https://badge.fury.io/rb/webmock.svg)](http://badge.fury.io/rb/webmock)
4
- [![Build Status](https://secure.travis-ci.org/bblimke/webmock.svg?branch=master)](http://travis-ci.org/bblimke/webmock)
4
+ [![Build Status](https://github.com/bblimke/webmock/workflows/CI/badge.svg?branch=master)](https://github.com/bblimke/webmock/actions)
5
5
  [![Code Climate](https://codeclimate.com/github/bblimke/webmock/badges/gpa.svg)](https://codeclimate.com/github/bblimke/webmock)
6
6
  [![Mentioned in Awesome Ruby](https://awesome.re/mentioned-badge.svg)](https://github.com/markets/awesome-ruby)
7
7
  [![Inline docs](http://inch-ci.org/github/bblimke/webmock.svg?branch=master)](http://inch-ci.org/github/bblimke/webmock)
@@ -24,23 +24,23 @@ Features
24
24
  Supported HTTP libraries
25
25
  ------------------------
26
26
 
27
- * Net::HTTP and libraries based on Net::HTTP (i.e RightHttpConnection, REST Client, HTTParty)
28
- * HTTPClient
29
- * Patron
30
- * EM-HTTP-Request
31
- * Curb (currently only Curb::Easy)
32
- * Typhoeus (currently only Typhoeus::Hydra)
33
- * Excon
34
- * HTTP Gem
35
- * Manticore
36
- * Async::HTTP::Client
27
+ * [Async::HTTP::Client](https://github.com/socketry/async-http)
28
+ * [Curb](https://github.com/taf2/curb) (currently only Curb::Easy)
29
+ * [EM-HTTP-Request](https://github.com/igrigorik/em-http-request)
30
+ * [Excon](https://github.com/excon/excon)
31
+ * [HTTPClient](https://github.com/nahi/httpclient)
32
+ * [HTTP Gem (also known as http.rb)](https://github.com/httprb/http)
33
+ * [httpx](https://honeyryderchuck.gitlab.io/httpx/wiki/Webmock-Adapter)
34
+ * [Manticore](https://github.com/cheald/manticore)
35
+ * [Net::HTTP](https://ruby-doc.org/stdlib-2.7.0/libdoc/net/http/rdoc/Net/HTTP.html) and other libraries based on Net::HTTP, e.g.:
36
+ * [HTTParty](https://github.com/jnunemaker/httparty)
37
+ * [REST Client](https://github.com/rest-client/rest-client)
38
+ * [Patron](https://github.com/toland/patron)
39
+ * [Typhoeus](https://github.com/typhoeus/typhoeus) (currently only Typhoeus::Hydra)
37
40
 
38
41
  Supported Ruby Interpreters
39
42
  ---------------------------
40
43
 
41
- * MRI 2.2
42
- * MRI 2.3
43
- * MRI 2.4
44
44
  * MRI 2.5
45
45
  * MRI 2.6
46
46
  * MRI 2.7
@@ -49,7 +49,17 @@ Supported Ruby Interpreters
49
49
 
50
50
  ## Installation
51
51
 
52
+ ```bash
52
53
  gem install webmock
54
+ ```
55
+ or alternatively:
56
+
57
+ ```ruby
58
+ # add to your Gemfile
59
+ group :test do
60
+ gem "webmock"
61
+ end
62
+ ```
53
63
 
54
64
  ### or to install the latest development version from github master
55
65
 
@@ -61,36 +71,36 @@ Supported Ruby Interpreters
61
71
 
62
72
  WebMock 2.x has changed somewhat since version 1.x. Changes are listed in [CHANGELOG.md](CHANGELOG.md)
63
73
 
64
- ### Test::Unit
74
+ ### Cucumber
65
75
 
66
- Add the following code to `test/test_helper.rb`
76
+ Create a file `features/support/webmock.rb` with the following contents:
67
77
 
68
78
  ```ruby
69
- require 'webmock/test_unit'
79
+ require 'webmock/cucumber'
70
80
  ```
71
81
 
72
- ### RSpec
82
+ ### MiniTest
73
83
 
74
- Add the following code to `spec/spec_helper`:
84
+ Add the following code to `test/test_helper`:
75
85
 
76
86
  ```ruby
77
- require 'webmock/rspec'
87
+ require 'webmock/minitest'
78
88
  ```
79
89
 
80
- ### MiniTest
90
+ ### RSpec
81
91
 
82
- Add the following code to `test/test_helper`:
92
+ Add the following code to `spec/spec_helper`:
83
93
 
84
94
  ```ruby
85
- require 'webmock/minitest'
95
+ require 'webmock/rspec'
86
96
  ```
87
97
 
88
- ### Cucumber
98
+ ### Test::Unit
89
99
 
90
- Create a file `features/support/webmock.rb` with the following contents:
100
+ Add the following code to `test/test_helper.rb`
91
101
 
92
102
  ```ruby
93
- require 'webmock/cucumber'
103
+ require 'webmock/test_unit'
94
104
  ```
95
105
 
96
106
  ### Outside a test framework
@@ -104,13 +114,10 @@ include WebMock::API
104
114
  WebMock.enable!
105
115
  ```
106
116
 
107
- ## Examples
108
-
109
-
117
+ # Examples
110
118
 
111
119
  ## Stubbing
112
120
 
113
-
114
121
  ### Stubbed request based on uri only and with the default response
115
122
 
116
123
  ```ruby
@@ -243,6 +250,12 @@ stub_request(:any, /example/)
243
250
  Net::HTTP.get('www.example.com', '/') # ===> Success
244
251
  ```
245
252
 
253
+ ### Matching uris using lambda
254
+
255
+ ```ruby
256
+ stub_request(:any, ->(uri) { true })
257
+ ```
258
+
246
259
  ### Matching uris using RFC 6570 - Basic Example
247
260
 
248
261
  ```ruby
@@ -300,6 +313,12 @@ stub_request(:any, "www.example.com").
300
313
  Net::HTTP.get("www.example.com", '/') # ===> "abc"
301
314
  ```
302
315
 
316
+ Set appropriate Content-Type for HTTParty's `parsed_response`.
317
+
318
+ ```ruby
319
+ stub_request(:any, "www.example.com").to_return body: '{}', headers: {content_type: 'application/json'}
320
+ ```
321
+
303
322
  ### Response with body specified as IO object
304
323
 
305
324
  ```ruby
@@ -1121,6 +1140,27 @@ People who submitted patches and new features or suggested improvements. Many th
1121
1140
  * Patrik Ragnarsson
1122
1141
  * Alex Coomans
1123
1142
  * Vesa Laakso
1143
+ * John Hawthorn
1144
+ * guppy0356
1145
+ * Thilo Rusche
1146
+ * Andrew Stuntz
1147
+ * Lucas Uyezu
1148
+ * Bruno Sutic
1149
+ * Ryan Kerr
1150
+ * Adam Harwood
1151
+ * Ben Koshy
1152
+ * Jesse Bowes
1153
+ * Marek Kasztelnik
1154
+ * ce07c3
1155
+ * Jun Jiang
1156
+ * Oleksiy Kovyrin
1157
+ * Matt Larraz
1158
+ * Tony Schneider
1159
+ * Niklas Hösl
1160
+ * Johanna Hartmann
1161
+ * Alex Vondrak
1162
+ * Will Storey
1163
+ * Eduardo Hernandez
1124
1164
 
1125
1165
  For a full list of contributors you can visit the
1126
1166
  [contributors](https://github.com/bblimke/webmock/contributors) page.
data/Rakefile CHANGED
@@ -3,24 +3,34 @@ Bundler::GemHelper.install_tasks
3
3
 
4
4
  require "rspec/core/rake_task"
5
5
  RSpec::Core::RakeTask.new(:spec) do |t|
6
- t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
6
+ t.rspec_opts = %w[
7
+ --force-color
8
+ --format progress
9
+ --require ./spec/spec_helper.rb
10
+ ]
7
11
  t.pattern = 'spec/**/*_spec.rb'
8
12
  end
9
13
 
10
14
  RSpec::Core::RakeTask.new(:spec_http_without_webmock) do |t|
11
- t.rspec_opts = ["-c", "-f progress", "-r ./spec/acceptance/net_http/real_net_http_spec.rb"]
15
+ t.rspec_opts = %w[
16
+ --force-color
17
+ --format progress
18
+ --require ./spec/acceptance/net_http/real_net_http_spec.rb
19
+ ]
12
20
  t.pattern = 'spec/acceptance/net_http/real_net_http_spec.rb'
13
21
  end
14
22
 
15
23
  require 'rake/testtask'
16
24
  Rake::TestTask.new(:test) do |test|
17
25
  test.test_files = FileList["test/**/*.rb"].exclude("test/test_helper.rb")
26
+ test.options = "--use-color"
18
27
  test.verbose = false
19
28
  test.warning = false
20
29
  end
21
30
 
22
31
  Rake::TestTask.new(:minitest) do |test|
23
32
  test.test_files = FileList["minitest/**/*.rb"].exclude("test/test_helper.rb")
33
+ test.options = "--pride"
24
34
  test.verbose = false
25
35
  test.warning = false
26
36
  end
@@ -40,8 +40,8 @@ if defined?(Async::HTTP)
40
40
  )
41
41
  webmock_endpoint = WebMockEndpoint.new(scheme, authority, protocol)
42
42
 
43
- @network_client = WebMockClient.new(endpoint, protocol, scheme, authority, **options)
44
- @webmock_client = WebMockClient.new(webmock_endpoint, protocol, scheme, authority, **options)
43
+ @network_client = WebMockClient.new(endpoint, **options)
44
+ @webmock_client = WebMockClient.new(webmock_endpoint, **options)
45
45
 
46
46
  @scheme = scheme
47
47
  @authority = authority
@@ -55,6 +55,7 @@ if defined?(Async::HTTP)
55
55
  WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
56
56
  webmock_response = WebMock::StubRegistry.instance.response_for_request(request_signature)
57
57
  net_connect_allowed = WebMock.net_connect_allowed?(request_signature.uri)
58
+ real_request = false
58
59
 
59
60
  if webmock_response
60
61
  webmock_response.raise_error_if_any
@@ -63,6 +64,7 @@ if defined?(Async::HTTP)
63
64
  response = @webmock_client.call(request)
64
65
  elsif net_connect_allowed
65
66
  response = @network_client.call(request)
67
+ real_request = true
66
68
  else
67
69
  raise WebMock::NetConnectNotAllowedError.new(request_signature) unless webmock_response
68
70
  end
@@ -72,7 +74,7 @@ if defined?(Async::HTTP)
72
74
  WebMock::CallbackRegistry.invoke_callbacks(
73
75
  {
74
76
  lib: :async_http_client,
75
- real_request: net_connect_allowed
77
+ real_request: real_request
76
78
  },
77
79
  request_signature,
78
80
  webmock_response
@@ -136,7 +138,7 @@ if defined?(Async::HTTP)
136
138
 
137
139
  def connect
138
140
  server_socket, client_socket = create_connected_sockets
139
- Async do
141
+ Async(transient: true) do
140
142
  accept_socket(server_socket)
141
143
  end
142
144
  client_socket
@@ -151,7 +153,7 @@ if defined?(Async::HTTP)
151
153
  def create_connected_sockets
152
154
  Async::IO::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM).tap do |sockets|
153
155
  sockets.each do |socket|
154
- socket.instance_variable_set :@alpn_protocol, @alpn_protocol
156
+ socket.instance_variable_set :@alpn_protocol, nil
155
157
  socket.instance_eval do
156
158
  def alpn_protocol
157
159
  nil # means HTTP11 will be used for HTTPS
@@ -99,6 +99,11 @@ if defined?(EventMachine::HttpClient)
99
99
  end
100
100
  end
101
101
 
102
+ def connection_completed
103
+ @state = :response_header
104
+ send_request(request_signature.headers, request_signature.body)
105
+ end
106
+
102
107
  def send_request(head, body)
103
108
  WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
104
109
 
@@ -164,7 +169,7 @@ if defined?(EventMachine::HttpClient)
164
169
  end
165
170
 
166
171
  def build_request_signature
167
- headers, body = @req.headers, @req.body
172
+ headers, body = build_request, @req.body
168
173
 
169
174
  @conn.middleware.select {|m| m.respond_to?(:request) }.each do |m|
170
175
  headers, body = m.request(self, headers, body)
@@ -178,8 +183,6 @@ if defined?(EventMachine::HttpClient)
178
183
 
179
184
  body = form_encode_body(body) if body.is_a?(Hash)
180
185
 
181
- headers = @req.headers
182
-
183
186
  if headers['authorization'] && headers['authorization'].is_a?(Array)
184
187
  headers['Authorization'] = WebMock::Util::Headers.basic_auth_header(headers.delete('authorization'))
185
188
  end
@@ -4,7 +4,10 @@ module HTTP
4
4
 
5
5
  def perform(request, options)
6
6
  return __perform__(request, options) unless webmock_enabled?
7
- WebMockPerform.new(request) { __perform__(request, options) }.exec
7
+
8
+ response = WebMockPerform.new(request) { __perform__(request, options) }.exec
9
+ options.features.each { |_name, feature| response = feature.wrap_response(response) }
10
+ response
8
11
  end
9
12
 
10
13
  def webmock_enabled?
@@ -11,7 +11,7 @@ module HTTP
11
11
  end
12
12
 
13
13
  class << self
14
- def from_webmock(webmock_response, request_signature = nil)
14
+ def from_webmock(request, webmock_response, request_signature = nil)
15
15
  status = Status.new(webmock_response.status.first)
16
16
  headers = webmock_response.headers || {}
17
17
  uri = normalize_uri(request_signature && request_signature.uri)
@@ -29,12 +29,23 @@ module HTTP
29
29
 
30
30
  return new(status, "1.1", headers, body, uri) if HTTP::VERSION < "1.0.0"
31
31
 
32
+ # 5.0.0 had a breaking change to require request instead of uri.
33
+ if HTTP::VERSION < '5.0.0'
34
+ return new({
35
+ status: status,
36
+ version: "1.1",
37
+ headers: headers,
38
+ body: body,
39
+ uri: uri
40
+ })
41
+ end
42
+
32
43
  new({
33
44
  status: status,
34
45
  version: "1.1",
35
46
  headers: headers,
36
47
  body: body,
37
- uri: uri
48
+ request: request,
38
49
  })
39
50
  end
40
51
 
@@ -38,7 +38,7 @@ module HTTP
38
38
  webmock_response.raise_error_if_any
39
39
 
40
40
  invoke_callbacks(webmock_response, real_request: false)
41
- ::HTTP::Response.from_webmock webmock_response, request_signature
41
+ ::HTTP::Response.from_webmock @request, webmock_response, request_signature
42
42
  end
43
43
 
44
44
  def raise_timeout_error
@@ -43,6 +43,9 @@ if defined?(::HTTPClient)
43
43
  end
44
44
 
45
45
  module WebMockHTTPClients
46
+
47
+ REQUEST_RESPONSE_LOCK = Mutex.new
48
+
46
49
  def do_get_block(req, proxy, conn, &block)
47
50
  do_get(req, proxy, conn, false, &block)
48
51
  end
@@ -57,7 +60,7 @@ if defined?(::HTTPClient)
57
60
  WebMock::RequestRegistry.instance.requested_signatures.put(request_signature)
58
61
 
59
62
  if webmock_responses[request_signature]
60
- webmock_response = webmock_responses.delete(request_signature)
63
+ webmock_response = synchronize_request_response { webmock_responses.delete(request_signature) }
61
64
  response = build_httpclient_response(webmock_response, stream, req.header, &block)
62
65
  @request_filter.each do |filter|
63
66
  filter.filter_response(req, response)
@@ -68,7 +71,7 @@ if defined?(::HTTPClient)
68
71
  res
69
72
  elsif WebMock.net_connect_allowed?(request_signature.uri)
70
73
  # in case there is a nil entry in the hash...
71
- webmock_responses.delete(request_signature)
74
+ synchronize_request_response { webmock_responses.delete(request_signature) }
72
75
 
73
76
  res = if stream
74
77
  do_get_stream_without_webmock(req, proxy, conn, &block)
@@ -100,7 +103,7 @@ if defined?(::HTTPClient)
100
103
  def do_request_async(method, uri, query, body, extheader)
101
104
  req = create_request(method, uri, query, body, extheader)
102
105
  request_signature = build_request_signature(req)
103
- webmock_request_signatures << request_signature
106
+ synchronize_request_response { webmock_request_signatures << request_signature }
104
107
 
105
108
  if webmock_responses[request_signature] || WebMock.net_connect_allowed?(request_signature.uri)
106
109
  super
@@ -184,7 +187,9 @@ if defined?(::HTTPClient)
184
187
 
185
188
  def webmock_responses
186
189
  @webmock_responses ||= Hash.new do |hash, request_signature|
187
- hash[request_signature] = WebMock::StubRegistry.instance.response_for_request(request_signature)
190
+ synchronize_request_response do
191
+ hash[request_signature] = WebMock::StubRegistry.instance.response_for_request(request_signature)
192
+ end
188
193
  end
189
194
  end
190
195
 
@@ -193,8 +198,10 @@ if defined?(::HTTPClient)
193
198
  end
194
199
 
195
200
  def previous_signature_for(signature)
196
- return nil unless index = webmock_request_signatures.index(signature)
197
- webmock_request_signatures.delete_at(index)
201
+ synchronize_request_response do
202
+ return nil unless index = webmock_request_signatures.index(signature)
203
+ webmock_request_signatures.delete_at(index)
204
+ end
198
205
  end
199
206
 
200
207
  private
@@ -209,6 +216,16 @@ if defined?(::HTTPClient)
209
216
  hdrs
210
217
  end
211
218
  end
219
+
220
+ def synchronize_request_response
221
+ if REQUEST_RESPONSE_LOCK.owned?
222
+ yield
223
+ else
224
+ REQUEST_RESPONSE_LOCK.synchronize do
225
+ yield
226
+ end
227
+ end
228
+ end
212
229
  end
213
230
 
214
231
  class WebMockHTTPClient < HTTPClient
@@ -127,8 +127,15 @@ if defined?(Manticore)
127
127
  def generate_webmock_response(manticore_response)
128
128
  webmock_response = WebMock::Response.new
129
129
  webmock_response.status = [manticore_response.code, manticore_response.message]
130
- webmock_response.body = manticore_response.body
131
130
  webmock_response.headers = manticore_response.headers
131
+
132
+ # The attempt to read the body could fail if manticore is used in a streaming mode
133
+ webmock_response.body = begin
134
+ manticore_response.body
135
+ rescue ::Manticore::StreamClosedException
136
+ nil
137
+ end
138
+
132
139
  webmock_response
133
140
  end
134
141
  end