webmock 3.11.1 → 3.18.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/CI.yml +38 -0
  3. data/CHANGELOG.md +126 -2
  4. data/Gemfile +1 -1
  5. data/README.md +33 -16
  6. data/Rakefile +12 -2
  7. data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +9 -2
  8. data/lib/webmock/http_lib_adapters/curb_adapter.rb +2 -2
  9. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +6 -3
  10. data/lib/webmock/http_lib_adapters/http_rb/client.rb +1 -3
  11. data/lib/webmock/http_lib_adapters/http_rb/response.rb +17 -3
  12. data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +4 -2
  13. data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +6 -2
  14. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +8 -1
  15. data/lib/webmock/http_lib_adapters/net_http.rb +29 -115
  16. data/lib/webmock/request_pattern.rb +30 -8
  17. data/lib/webmock/request_signature.rb +2 -2
  18. data/lib/webmock/request_stub.rb +15 -0
  19. data/lib/webmock/response.rb +8 -8
  20. data/lib/webmock/version.rb +1 -1
  21. data/lib/webmock/webmock.rb +10 -0
  22. data/minitest/webmock_spec.rb +1 -1
  23. data/spec/acceptance/async_http_client/async_http_client_spec.rb +27 -5
  24. data/spec/acceptance/curb/curb_spec.rb +11 -0
  25. data/spec/acceptance/em_http_request/em_http_request_spec.rb +57 -1
  26. data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +1 -1
  27. data/spec/acceptance/excon/excon_spec.rb +2 -2
  28. data/spec/acceptance/manticore/manticore_spec.rb +32 -0
  29. data/spec/acceptance/net_http/net_http_shared.rb +46 -9
  30. data/spec/acceptance/net_http/net_http_spec.rb +75 -23
  31. data/spec/acceptance/net_http/real_net_http_spec.rb +1 -1
  32. data/spec/acceptance/patron/patron_spec.rb +19 -21
  33. data/spec/acceptance/patron/patron_spec_helper.rb +2 -2
  34. data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +14 -14
  35. data/spec/acceptance/shared/callbacks.rb +2 -2
  36. data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +1 -1
  37. data/spec/unit/request_pattern_spec.rb +82 -46
  38. data/spec/unit/request_signature_spec.rb +21 -1
  39. data/spec/unit/request_stub_spec.rb +35 -0
  40. data/spec/unit/response_spec.rb +29 -1
  41. data/spec/unit/webmock_spec.rb +54 -0
  42. data/webmock.gemspec +6 -5
  43. metadata +46 -32
  44. data/.travis.yml +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc97c874689b792ce7a6a84750b324c2cb610fd667c0fbc341dccaf14cc26fc1
4
- data.tar.gz: 05c2e55ba9554c1066f6631c5b5beabfafc05904ce811aef7ceb944b99d5367d
3
+ metadata.gz: 3a7e964f28dd42787fd854c5fcc87dba4cd61ef214c3dee485d9bd0d71fc1cdd
4
+ data.tar.gz: f6921a9b14ccd71f18b4674aca8d4d24bf377545a4ef8c56862f95cc56b6e8a7
5
5
  SHA512:
6
- metadata.gz: 27824be10a455582f88966a60539c2f2af49fca630e7ef5f9c49ef342c22d1f28e4abd3fe52a4882cdeb756bb04853798d24f43a4a64575f9e070f287d1cb905
7
- data.tar.gz: 37cbd35aabaff9f013a5305163ef1420dd00b4d3635e1c70bedb246e44e152c189cff4cca9ff561a89220b68e876d80cdfa31aeffdcd7841a36105fa96be2904
6
+ metadata.gz: 80e85d1bb83018bdaab80aed649134757ee8ac591b98e9ccf1b6df10c0d8930db167dd5fd3bb039dd56a955d22c0cc6b1a1227bb88e8f3e56d31d0e1c9d7708e
7
+ data.tar.gz: c67f1f8486d6ee932bd9d01dff2bfcec35d9c3e3ed937e50e1f56d34f664ca11db4c9399c51e82da9316245c1d4727c726b9e307646aef80477764609ecf95ee
@@ -0,0 +1,38 @@
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.1'
18
+ - '3.0'
19
+ - '2.7'
20
+ - '2.6'
21
+ - '2.5'
22
+ - jruby
23
+ continue-on-error: ${{ matrix.ruby == 'head' }}
24
+ name: Ruby ${{ matrix.ruby }}
25
+ env:
26
+ JRUBY_OPTS: "--debug"
27
+ steps:
28
+ - uses: actions/checkout@v2
29
+ - name: Install Apt Packages
30
+ run: |
31
+ sudo apt-get install libcurl4-openssl-dev -y
32
+ - uses: ruby/setup-ruby@v1
33
+ continue-on-error: true
34
+ with:
35
+ ruby-version: ${{ matrix.ruby }}
36
+ bundler-cache: true
37
+ - run: |
38
+ bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,129 @@
1
1
  # Changelog
2
2
 
3
+ # 3.18.1
4
+
5
+ * Reverted simplified connection handing in Net::HTTP adapter due to https://github.com/bblimke/webmock/issues/999
6
+
7
+ # 3.18.0
8
+
9
+ * Net::BufferedIO is not replaced anymore.
10
+
11
+ Thanks to [Ray Zane](https://github.com/rzane)
12
+
13
+ * Simplified connection handing in Net::HTTP adapter.
14
+
15
+ Thanks to [Ray Zane](https://github.com/rzane)
16
+
17
+ # 3.17.1
18
+
19
+ * Fixed Syntax Error
20
+
21
+ Thanks to [Mark Spangler](https://github.com/mspangler)
22
+
23
+ # 3.17.0
24
+
25
+ * Minimum required Ruby version is 2.3
26
+
27
+ Thanks to [Go Sueyoshi](https://github.com/sue445)
28
+
29
+ * When using Net::HTTP, stubbed socket StubSocket#close and StubSocket#closed? behave more like the real sockets.
30
+
31
+ Thanks to [Ray Zane](https://github.com/rzane)
32
+
33
+ * Added `peeraddr`, `ssl_version` and `cipher` methods to stubbed sockets used by Net::HTTP.
34
+
35
+ Thanks to [Ray Zane](https://github.com/rzane)
36
+
37
+ * Added support for matching top-level array in JSON request body.
38
+
39
+ E.g.
40
+
41
+ ````
42
+ stub_request(:post, 'www.example.com').with(body: [{a: 1}])
43
+ ````
44
+
45
+ Thanks to [Cedric Sohrauer](https://github.com/cedrics)
46
+
47
+ # 3.16.2
48
+
49
+ * Minimum required Ruby version is 2.0.
50
+
51
+ # 3.16.0 (yanked)
52
+
53
+ * Fix leaky file descriptors and reuse socket for persistent connections.
54
+
55
+ Thanks to [Ray Zane](https://github.com/rzane)
56
+
57
+ * Allow specifying for what URIs or hosts, Net::HTTP should connect on start.
58
+
59
+ Thanks to [Ray Zane](https://github.com/rzane)
60
+
61
+ # 3.15.2
62
+
63
+ * Minimum required Ruby version is 2.0.
64
+
65
+ # 3.15.0 (yanked)
66
+
67
+ * fixed async-http adapter on Windows
68
+
69
+ Thanks to [Pavel Rosický](https://github.com/ahorek)
70
+
71
+ * Support for http.rb >= 5.0.2
72
+
73
+ Thanks to [ojab](https://github.com/ojab)
74
+
75
+ * Curb adapter supports headers with `:` character in the header value
76
+
77
+ Thanks to [Giorgio Gambino](https://github.com/mrbuzz)
78
+
79
+ * Support for matching body of JSON or application/x-www-form-urlencoded requests with content type header including charset.
80
+
81
+ Thanks to [Timmitry](https://github.com/Timmitry)
82
+
83
+ * Prevent double-wrapping http.rb features on non-stubbed requests
84
+
85
+ Thanks to [Michael Fairley](https://github.com/michaelfairley)
86
+
87
+ # 3.14.0
88
+
89
+ * Bump Addressable from 2.3.6 to 2.8.0
90
+
91
+ Thanks to [Eduardo Hernandez](https://github.com/EduardoGHdez)
92
+
93
+ # 3.13.0
94
+
95
+ * Support http.rb 5.x
96
+
97
+ Thanks to [Will Storey](https://github.com/horgh)
98
+
99
+ # 3.12.2
100
+
101
+ * Fixed em-http-request adapter to avoid calling middleware twice.
102
+
103
+ Thanks to [Alex Vondrak](https://github.com/ajvondrak)
104
+
105
+ # 3.12.1
106
+
107
+ * Fixed handling of URIs with IPv6 addresses with square brackets when in Net::HTTP adapter.
108
+
109
+ Thanks to [Johanna Hartmann](https://github.com/JohannaHartmann)
110
+
111
+ # 3.12.0
112
+
113
+ * Added support for handling custom JSON and XML content types e.g. 'application/vnd.api+json'
114
+
115
+ # 3.11.3
116
+
117
+ * Fixed async-http adapter to only considered requests as real if they are real.
118
+
119
+ Thanks to Thanks to [Tony Schneider](https://github.com/tonywok) and [Samuel Williams](https://github.com/ioquatix)
120
+
121
+ # 3.11.2
122
+
123
+ * Fix for Manticore streaming mode
124
+
125
+ Thanks to [Oleksiy Kovyrin](https://github.com/kovyrin)
126
+
3
127
  # 3.11.1
4
128
 
5
129
  * Compatibility with async-http 0.54+
@@ -565,9 +689,9 @@
565
689
  * `WebMock.disable_net_connect` accepts `:allow` option with an object that responds to `#call`, receiving a `URI` object and returning a boolean:
566
690
 
567
691
 
568
- blacklist = ['google.com', 'facebook.com', 'apple.com']
692
+ denylist = ['google.com', 'facebook.com', 'apple.com']
569
693
  allowed_sites = lambda{|uri|
570
- blacklist.none?{|site| uri.host.include?(site) }
694
+ denylist.none?{|site| uri.host.include?(site) }
571
695
  }
572
696
  WebMock.disable_net_connect!(:allow => allowed_sites)
573
697
 
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,19 +24,19 @@ Features
24
24
  Supported HTTP libraries
25
25
  ------------------------
26
26
 
27
- * Async::HTTP::Client
28
- * Curb (currently only Curb::Easy)
29
- * EM-HTTP-Request
30
- * Excon
31
- * HTTPClient
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
32
  * [HTTP Gem (also known as http.rb)](https://github.com/httprb/http)
33
- * Manticore
34
- * Net::HTTP and other libraries based on Net::HTTP, e.g.:
35
- * HTTParty
36
- * REST Client
37
- * RightHttpConnection
38
- * Patron
39
- * Typhoeus (currently only Typhoeus::Hydra)
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)
40
40
 
41
41
  Supported Ruby Interpreters
42
42
  ---------------------------
@@ -550,9 +550,9 @@ RestClient.get('sample.org', '/bar') # ===> Failure
550
550
  With an object that responds to `#call`, receiving a `URI` object and returning a boolean:
551
551
 
552
552
  ```ruby
553
- blacklist = ['google.com', 'facebook.com', 'apple.com']
553
+ denylist = ['google.com', 'facebook.com', 'apple.com']
554
554
  allowed_sites = lambda{|uri|
555
- blacklist.none?{|site| uri.host.include?(site) }
555
+ denylist.none?{|site| uri.host.include?(site) }
556
556
  }
557
557
  WebMock.disable_net_connect!(allow: allowed_sites)
558
558
 
@@ -1153,13 +1153,30 @@ People who submitted patches and new features or suggested improvements. Many th
1153
1153
  * Marek Kasztelnik
1154
1154
  * ce07c3
1155
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
1164
+ * ojab
1165
+ * Giorgio Gambino
1166
+ * Timmitry
1167
+ * Michael Fairley
1168
+ * Ray Zane
1169
+ * Go Sueyoshi
1170
+ * Cedric Sohrauer
1171
+ * Akira Matsuda
1172
+ * Mark Spangler
1156
1173
 
1157
1174
  For a full list of contributors you can visit the
1158
1175
  [contributors](https://github.com/bblimke/webmock/contributors) page.
1159
1176
 
1160
1177
  ## Background
1161
1178
 
1162
- Thank you Fakeweb! This library was inspired by [FakeWeb](http://fakeweb.rubyforge.org).
1179
+ Thank you Fakeweb! This library was inspired by [FakeWeb](https://github.com/chrisk/fakeweb).
1163
1180
  I imported some solutions from that project to WebMock. I also copied some code i.e Net:HTTP adapter.
1164
1181
  Fakeweb architecture unfortunately didn't allow me to extend it easily with the features I needed.
1165
1182
  I also preferred some things to work differently i.e request stub precedence.
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
@@ -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
@@ -149,7 +151,12 @@ if defined?(Async::HTTP)
149
151
  private
150
152
 
151
153
  def create_connected_sockets
152
- Async::IO::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM).tap do |sockets|
154
+ pair = begin
155
+ Async::IO::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM)
156
+ rescue Errno::EAFNOSUPPORT
157
+ Async::IO::Socket.pair(Socket::AF_INET, Socket::SOCK_STREAM)
158
+ end
159
+ pair.tap do |sockets|
153
160
  sockets.each do |socket|
154
161
  socket.instance_variable_set :@alpn_protocol, nil
155
162
  socket.instance_eval do
@@ -5,7 +5,7 @@ rescue LoadError
5
5
  end
6
6
 
7
7
  if defined?(Curl)
8
- WebMock::VersionChecker.new('Curb', Curl::CURB_VERSION, '0.7.16', '0.9.1', ['0.8.7']).check_version!
8
+ WebMock::VersionChecker.new('Curb', Curl::CURB_VERSION, '0.7.16', '1.0.1', ['0.8.7']).check_version!
9
9
 
10
10
  module WebMock
11
11
  module HttpLibAdapters
@@ -128,7 +128,7 @@ if defined?(Curl)
128
128
  def headers_as_hash(headers)
129
129
  if headers.is_a?(Array)
130
130
  headers.inject({}) {|hash, header|
131
- name, value = header.split(":").map(&:strip)
131
+ name, value = header.split(":", 2).map(&:strip)
132
132
  hash[name] = value
133
133
  hash
134
134
  }
@@ -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
@@ -5,9 +5,7 @@ module HTTP
5
5
  def perform(request, options)
6
6
  return __perform__(request, options) unless webmock_enabled?
7
7
 
8
- response = WebMockPerform.new(request) { __perform__(request, options) }.exec
9
- options.features.each { |_name, feature| response = feature.wrap_response(response) }
10
- response
8
+ WebMockPerform.new(request, options) { __perform__(request, options) }.exec
11
9
  end
12
10
 
13
11
  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)
@@ -24,17 +24,31 @@ module HTTP
24
24
  elsif HTTP::VERSION < "3.0.0"
25
25
  Body.new(Streamer.new(webmock_response.body), webmock_response.body.encoding)
26
26
  else
27
- Body.new(Streamer.new(webmock_response.body), encoding: webmock_response.body.encoding)
27
+ Body.new(
28
+ Streamer.new(webmock_response.body, encoding: webmock_response.body.encoding),
29
+ encoding: webmock_response.body.encoding
30
+ )
28
31
  end
29
32
 
30
33
  return new(status, "1.1", headers, body, uri) if HTTP::VERSION < "1.0.0"
31
34
 
35
+ # 5.0.0 had a breaking change to require request instead of uri.
36
+ if HTTP::VERSION < '5.0.0'
37
+ return new({
38
+ status: status,
39
+ version: "1.1",
40
+ headers: headers,
41
+ body: body,
42
+ uri: uri
43
+ })
44
+ end
45
+
32
46
  new({
33
47
  status: status,
34
48
  version: "1.1",
35
49
  headers: headers,
36
50
  body: body,
37
- uri: uri
51
+ request: request,
38
52
  })
39
53
  end
40
54
 
@@ -1,8 +1,9 @@
1
1
  module HTTP
2
2
  class Response
3
3
  class Streamer
4
- def initialize(str)
4
+ def initialize(str, encoding: Encoding::BINARY)
5
5
  @io = StringIO.new str
6
+ @encoding = encoding
6
7
  end
7
8
 
8
9
  def readpartial(size = nil, outbuf = nil)
@@ -14,7 +15,8 @@ module HTTP
14
15
  end
15
16
  end
16
17
 
17
- @io.read size, outbuf
18
+ chunk = @io.read size, outbuf
19
+ chunk.force_encoding(@encoding) if chunk
18
20
  end
19
21
 
20
22
  def close
@@ -1,7 +1,8 @@
1
1
  module HTTP
2
2
  class WebMockPerform
3
- def initialize(request, &perform)
3
+ def initialize(request, options, &perform)
4
4
  @request = request
5
+ @options = options
5
6
  @perform = perform
6
7
  @request_signature = nil
7
8
  end
@@ -38,7 +39,10 @@ module HTTP
38
39
  webmock_response.raise_error_if_any
39
40
 
40
41
  invoke_callbacks(webmock_response, real_request: false)
41
- ::HTTP::Response.from_webmock webmock_response, request_signature
42
+ response = ::HTTP::Response.from_webmock @request, webmock_response, request_signature
43
+
44
+ @options.features.each { |_name, feature| response = feature.wrap_response(response) }
45
+ response
42
46
  end
43
47
 
44
48
  def raise_timeout_error
@@ -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