vcr 2.4.0 → 2.5.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.
- checksums.yaml +15 -0
- data/.gitignore +3 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +31 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +63 -46
- data/README.md +5 -2
- data/features/cassettes/allow_unused_http_interactions.feature +1 -1
- data/features/cassettes/automatic_re_recording.feature +1 -1
- data/features/cassettes/decompress.feature +3 -3
- data/features/cassettes/dynamic_erb.feature +2 -2
- data/features/cassettes/exclusive.feature +1 -1
- data/features/cassettes/naming.feature +1 -1
- data/features/cassettes/no_cassette.feature +6 -3
- data/features/cassettes/persistence.feature +1 -1
- data/features/cassettes/update_content_length_header.feature +1 -1
- data/features/configuration/allow_http_connections_when_no_cassette.feature +1 -1
- data/features/configuration/cassette_library_dir.feature +1 -1
- data/features/configuration/debug_logging.feature +5 -5
- data/features/configuration/filter_sensitive_data.feature +2 -2
- data/features/configuration/hook_into.feature +4 -7
- data/features/getting_started.md +2 -2
- data/features/hooks/before_playback.feature +5 -5
- data/features/hooks/before_record.feature +5 -5
- data/features/middleware/rack.feature +2 -2
- data/features/record_modes/all.feature +1 -1
- data/features/record_modes/new_episodes.feature +1 -1
- data/features/record_modes/none.feature +1 -1
- data/features/record_modes/once.feature +1 -1
- data/features/request_matching/custom_matcher.feature +1 -1
- data/features/request_matching/headers.feature +0 -2
- data/features/request_matching/playback_repeats.feature +1 -1
- data/features/request_matching/uri_without_param.feature +1 -1
- data/features/support/env.rb +1 -0
- data/features/test_frameworks/cucumber.feature +8 -8
- data/features/test_frameworks/rspec_macro.feature +2 -2
- data/features/test_frameworks/rspec_metadata.feature +1 -1
- data/gemfiles/typhoeus_old.gemfile +1 -1
- data/gemfiles/typhoeus_old.gemfile.lock +31 -57
- data/lib/vcr/cassette/migrator.rb +8 -1
- data/lib/vcr/configuration.rb +9 -2
- data/lib/vcr/library_hooks/excon.rb +2 -184
- data/lib/vcr/library_hooks/typhoeus.rb +1 -1
- data/lib/vcr/library_hooks/typhoeus_0.4.rb +4 -0
- data/lib/vcr/library_hooks/webmock.rb +1 -1
- data/lib/vcr/middleware/excon.rb +226 -0
- data/lib/vcr/version.rb +1 -1
- data/spec/acceptance/threading_spec.rb +28 -0
- data/spec/monkey_patches.rb +3 -7
- data/spec/quality_spec.rb +1 -1
- data/spec/spec_helper.rb +7 -4
- data/spec/support/http_library_adapters.rb +4 -3
- data/spec/support/shared_example_groups/excon.rb +22 -0
- data/spec/support/shared_example_groups/hook_into_http_library.rb +46 -46
- data/spec/support/shared_example_groups/request_hooks.rb +8 -8
- data/spec/vcr/cassette/erb_renderer_spec.rb +5 -5
- data/spec/vcr/cassette/http_interaction_list_spec.rb +52 -40
- data/spec/vcr/cassette/migrator_spec.rb +11 -11
- data/spec/vcr/cassette/persisters/file_system_spec.rb +11 -11
- data/spec/vcr/cassette/persisters_spec.rb +2 -2
- data/spec/vcr/cassette/serializers_spec.rb +13 -12
- data/spec/vcr/cassette_spec.rb +58 -58
- data/spec/vcr/configuration_spec.rb +43 -31
- data/spec/vcr/deprecations_spec.rb +3 -3
- data/spec/vcr/errors_spec.rb +25 -25
- data/spec/vcr/extensions/net_http_response_spec.rb +7 -7
- data/spec/vcr/library_hooks/excon_spec.rb +7 -85
- data/spec/vcr/library_hooks/fakeweb_spec.rb +15 -13
- data/spec/vcr/library_hooks/faraday_spec.rb +4 -4
- data/spec/vcr/library_hooks/typhoeus_0.4_spec.rb +5 -0
- data/spec/vcr/library_hooks/typhoeus_spec.rb +3 -3
- data/spec/vcr/library_hooks/webmock_spec.rb +13 -5
- data/spec/vcr/library_hooks_spec.rb +9 -9
- data/spec/vcr/middleware/faraday_spec.rb +10 -10
- data/spec/vcr/middleware/rack_spec.rb +20 -15
- data/spec/vcr/request_ignorer_spec.rb +3 -3
- data/spec/vcr/request_matcher_registry_spec.rb +88 -61
- data/spec/vcr/structs_spec.rb +85 -85
- data/spec/vcr/test_frameworks/cucumber_spec.rb +7 -7
- data/spec/vcr/test_frameworks/rspec_spec.rb +10 -10
- data/spec/vcr/util/hooks_spec.rb +20 -20
- data/spec/vcr/util/internet_connection_spec.rb +2 -2
- data/spec/vcr_spec.rb +50 -48
- data/vcr.gemspec +4 -4
- metadata +308 -372
@@ -101,9 +101,16 @@ module VCR
|
|
101
101
|
join('-')
|
102
102
|
end
|
103
103
|
|
104
|
+
EMPTY_STRING = if String.method_defined?(:force_encoding)
|
105
|
+
''.force_encoding("US-ASCII")
|
106
|
+
else
|
107
|
+
''
|
108
|
+
end
|
109
|
+
|
104
110
|
def normalize_body(object)
|
105
|
-
object.body =
|
111
|
+
object.body = EMPTY_STRING if object.body.nil?
|
106
112
|
end
|
113
|
+
|
107
114
|
end
|
108
115
|
end
|
109
116
|
end
|
data/lib/vcr/configuration.rb
CHANGED
@@ -392,13 +392,16 @@ module VCR
|
|
392
392
|
"VCR::Configuration#around_http_request requires fibers, " +
|
393
393
|
"which are not available on your ruby intepreter."
|
394
394
|
else
|
395
|
-
|
395
|
+
fibers = {}
|
396
|
+
hook_allowed, hook_decaration = false, caller.first
|
396
397
|
before_http_request(*filters) do |request|
|
397
398
|
hook_allowed = true
|
398
399
|
fiber = start_new_fiber_for(request, block)
|
400
|
+
fibers[Thread.current] = fiber
|
399
401
|
end
|
400
402
|
|
401
403
|
after_http_request(lambda { hook_allowed }) do |request, response|
|
404
|
+
fiber = fibers.delete(Thread.current)
|
402
405
|
resume_fiber(fiber, response, hook_decaration)
|
403
406
|
end
|
404
407
|
end
|
@@ -406,7 +409,10 @@ module VCR
|
|
406
409
|
# Configures RSpec to use a VCR cassette for any example
|
407
410
|
# tagged with `:vcr`.
|
408
411
|
def configure_rspec_metadata!
|
409
|
-
|
412
|
+
unless @rspec_metadata_configured
|
413
|
+
VCR::RSpec::Metadata.configure!
|
414
|
+
@rspec_metadata_configured = true
|
415
|
+
end
|
410
416
|
end
|
411
417
|
|
412
418
|
# An object to log debug output to.
|
@@ -462,6 +468,7 @@ module VCR
|
|
462
468
|
|
463
469
|
def initialize
|
464
470
|
@allow_http_connections_when_no_cassette = nil
|
471
|
+
@rspec_metadata_configured = false
|
465
472
|
@default_cassette_options = {
|
466
473
|
:record => :once,
|
467
474
|
:match_requests_on => RequestMatcherRegistry::DEFAULT_MATCHERS,
|
@@ -1,188 +1,6 @@
|
|
1
|
-
require 'vcr/
|
2
|
-
require 'vcr/request_handler'
|
3
|
-
require 'excon'
|
1
|
+
require 'vcr/middleware/excon'
|
4
2
|
|
5
|
-
VCR::
|
6
|
-
|
7
|
-
module VCR
|
8
|
-
class LibraryHooks
|
9
|
-
# @private
|
10
|
-
module Excon
|
11
|
-
class RequestHandler < ::VCR::RequestHandler
|
12
|
-
attr_reader :params
|
13
|
-
def initialize(params)
|
14
|
-
@vcr_response = nil
|
15
|
-
@params = params
|
16
|
-
end
|
17
|
-
|
18
|
-
def handle
|
19
|
-
super
|
20
|
-
ensure
|
21
|
-
invoke_after_request_hook(@vcr_response)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def on_stubbed_by_vcr_request
|
27
|
-
@vcr_response = stubbed_response
|
28
|
-
{
|
29
|
-
:body => stubbed_response.body,
|
30
|
-
:headers => normalized_headers(stubbed_response.headers || {}),
|
31
|
-
:status => stubbed_response.status.code
|
32
|
-
}
|
33
|
-
end
|
34
|
-
|
35
|
-
def on_ignored_request
|
36
|
-
perform_real_request
|
37
|
-
end
|
38
|
-
|
39
|
-
def response_from_excon_error(error)
|
40
|
-
if error.respond_to?(:response)
|
41
|
-
error.response
|
42
|
-
elsif error.respond_to?(:socket_error)
|
43
|
-
response_from_excon_error(error.socket_error)
|
44
|
-
else
|
45
|
-
warn "WARNING: VCR could not extract a response from Excon error (#{error.inspect})"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
PARAMS_TO_DELETE = [:expects, :idempotent,
|
50
|
-
:instrumentor_name, :instrumentor,
|
51
|
-
:response_block, :request_block]
|
52
|
-
|
53
|
-
def real_request_params
|
54
|
-
# Excon supports a variety of options that affect how it handles failure
|
55
|
-
# and retry; we don't want to use any options here--we just want to get
|
56
|
-
# a raw response, and then the main request (with :mock => true) can
|
57
|
-
# handle failure/retry on its own with its set options.
|
58
|
-
scrub_params_from params.merge(:mock => false, :retry_limit => 0)
|
59
|
-
end
|
60
|
-
|
61
|
-
def new_connection
|
62
|
-
# Ensure the connection is constructed with the exact same args
|
63
|
-
# that the orginal connection was constructed with.
|
64
|
-
args, options = params.fetch(:__construction_args)
|
65
|
-
options = scrub_params_from(options) if options.is_a?(Hash)
|
66
|
-
::Excon::Connection.new(*[args, options].compact)
|
67
|
-
end
|
68
|
-
|
69
|
-
def scrub_params_from(hash)
|
70
|
-
hash = hash.dup
|
71
|
-
PARAMS_TO_DELETE.each { |key| hash.delete(key) }
|
72
|
-
hash
|
73
|
-
end
|
74
|
-
|
75
|
-
def perform_real_request
|
76
|
-
begin
|
77
|
-
response = new_connection.request(real_request_params)
|
78
|
-
rescue ::Excon::Errors::Error => excon_error
|
79
|
-
response = response_from_excon_error(excon_error)
|
80
|
-
end
|
81
|
-
|
82
|
-
@vcr_response = vcr_response_from(response)
|
83
|
-
yield response if block_given?
|
84
|
-
raise excon_error if excon_error
|
85
|
-
|
86
|
-
response.attributes
|
87
|
-
end
|
88
|
-
|
89
|
-
def on_recordable_request
|
90
|
-
perform_real_request do |response|
|
91
|
-
http_interaction = http_interaction_for(response)
|
92
|
-
VCR.record_http_interaction(http_interaction)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def uri
|
97
|
-
@uri ||= "#{params[:scheme]}://#{params[:host]}:#{params[:port]}#{params[:path]}#{query}"
|
98
|
-
end
|
99
|
-
|
100
|
-
# based on:
|
101
|
-
# https://github.com/geemus/excon/blob/v0.7.8/lib/excon/connection.rb#L117-132
|
102
|
-
def query
|
103
|
-
@query ||= case params[:query]
|
104
|
-
when String
|
105
|
-
"?#{params[:query]}"
|
106
|
-
when Hash
|
107
|
-
qry = '?'
|
108
|
-
for key, values in params[:query]
|
109
|
-
if values.nil?
|
110
|
-
qry << key.to_s << '&'
|
111
|
-
else
|
112
|
-
for value in [*values]
|
113
|
-
qry << key.to_s << '=' << CGI.escape(value.to_s) << '&'
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
qry.chop! # remove trailing '&'
|
118
|
-
else
|
119
|
-
''
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def http_interaction_for(response)
|
124
|
-
VCR::HTTPInteraction.new \
|
125
|
-
vcr_request,
|
126
|
-
vcr_response_from(response)
|
127
|
-
end
|
128
|
-
|
129
|
-
def vcr_request
|
130
|
-
@vcr_request ||= begin
|
131
|
-
headers = params[:headers].dup
|
132
|
-
headers.delete("Host")
|
133
|
-
|
134
|
-
VCR::Request.new \
|
135
|
-
params[:method],
|
136
|
-
uri,
|
137
|
-
params[:body],
|
138
|
-
headers
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def vcr_response_from(response)
|
143
|
-
VCR::Response.new \
|
144
|
-
VCR::ResponseStatus.new(response.status, nil),
|
145
|
-
response.headers,
|
146
|
-
response.body,
|
147
|
-
nil
|
148
|
-
end
|
149
|
-
|
150
|
-
def normalized_headers(headers)
|
151
|
-
normalized = {}
|
152
|
-
headers.each do |k, v|
|
153
|
-
v = v.join(', ') if v.respond_to?(:join)
|
154
|
-
normalized[k] = v
|
155
|
-
end
|
156
|
-
normalized
|
157
|
-
end
|
158
|
-
|
159
|
-
::Excon.stub({}) do |params|
|
160
|
-
self.new(params).handle
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
::Excon.defaults[:mock] = true
|
169
|
-
|
170
|
-
# We want to get at the Excon::Connection class but WebMock does
|
171
|
-
# some constant-replacing stuff to it, so we need to take that into
|
172
|
-
# account.
|
173
|
-
excon_connection = if defined?(::WebMock::HttpLibAdapters::ExconConnection)
|
174
|
-
::WebMock::HttpLibAdapters::ExconConnection.superclass
|
175
|
-
else
|
176
|
-
::Excon::Connection
|
177
|
-
end
|
178
|
-
|
179
|
-
excon_connection.class_eval do
|
180
|
-
def self.new(*args)
|
181
|
-
super.tap do |instance|
|
182
|
-
instance.connection[:__construction_args] = args
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
3
|
+
Excon.defaults[:middlewares] << VCR::Middleware::Excon
|
186
4
|
|
187
5
|
VCR.configuration.after_library_hooks_loaded do
|
188
6
|
# ensure WebMock's Excon adapter does not conflict with us here
|
@@ -5,7 +5,7 @@ require 'typhoeus'
|
|
5
5
|
if Float(Typhoeus::VERSION[/^\d+\.\d+/]) < 0.5
|
6
6
|
require 'vcr/library_hooks/typhoeus_0.4'
|
7
7
|
else
|
8
|
-
VCR::VersionChecker.new('Typhoeus', Typhoeus::VERSION, '0.5.0', '0.
|
8
|
+
VCR::VersionChecker.new('Typhoeus', Typhoeus::VERSION, '0.5.0', '0.6').check_version!
|
9
9
|
|
10
10
|
module VCR
|
11
11
|
class LibraryHooks
|
@@ -2,7 +2,7 @@ require 'vcr/util/version_checker'
|
|
2
2
|
require 'vcr/request_handler'
|
3
3
|
require 'webmock'
|
4
4
|
|
5
|
-
VCR::VersionChecker.new('WebMock', WebMock.version, '1.8.0', '1.
|
5
|
+
VCR::VersionChecker.new('WebMock', WebMock.version, '1.8.0', '1.11').check_version!
|
6
6
|
|
7
7
|
module VCR
|
8
8
|
class LibraryHooks
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'vcr/request_handler'
|
3
|
+
require 'vcr/util/version_checker'
|
4
|
+
|
5
|
+
VCR::VersionChecker.new('Excon', Excon::VERSION, '0.22.0', '0.22').check_version!
|
6
|
+
|
7
|
+
module VCR
|
8
|
+
# Contains middlewares for use with different libraries.
|
9
|
+
module Middleware
|
10
|
+
# Excon middleware that uses VCR to record and replay HTTP requests made
|
11
|
+
# through Excon.
|
12
|
+
#
|
13
|
+
# @note You can either add this to the middleware stack of an Excon connection
|
14
|
+
# yourself, or configure {VCR::Configuration#hook_into} to hook into `:excon`.
|
15
|
+
# Setting the config option will add this middleware to Excon's default
|
16
|
+
# middleware stack.
|
17
|
+
class Excon < ::Excon::Middleware::Base
|
18
|
+
# @private
|
19
|
+
def initialize(*args)
|
20
|
+
# Excon appears to create a new instance of this middleware for each
|
21
|
+
# request, which means it should be safe to store per-request state
|
22
|
+
# like this request_handler object on the middleware instance.
|
23
|
+
# I'm not 100% sure about this yet and should verify with @geemus.
|
24
|
+
@request_handler = RequestHandler.new
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
# @private
|
29
|
+
def request_call(params)
|
30
|
+
@request_handler.before_request(params)
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
# @private
|
35
|
+
def response_call(params)
|
36
|
+
@request_handler.after_request(params)
|
37
|
+
super
|
38
|
+
end
|
39
|
+
|
40
|
+
# @private
|
41
|
+
def error_call(params)
|
42
|
+
@request_handler.after_request(params)
|
43
|
+
super
|
44
|
+
end
|
45
|
+
|
46
|
+
# Handles a single Excon request.
|
47
|
+
#
|
48
|
+
# @private
|
49
|
+
class RequestHandler < ::VCR::RequestHandler
|
50
|
+
def initialize
|
51
|
+
@request_params = nil
|
52
|
+
@response_params = nil
|
53
|
+
@response_body_reader = nil
|
54
|
+
@should_record = false
|
55
|
+
end
|
56
|
+
|
57
|
+
# Performs before_request processing based on the provided
|
58
|
+
# request_params.
|
59
|
+
#
|
60
|
+
# @private
|
61
|
+
def before_request(request_params)
|
62
|
+
@request_params = request_params
|
63
|
+
@response_body_reader = create_response_body_reader
|
64
|
+
handle
|
65
|
+
end
|
66
|
+
|
67
|
+
# Performs after_request processing based on the provided
|
68
|
+
# response_params.
|
69
|
+
#
|
70
|
+
# @private
|
71
|
+
def after_request(response_params)
|
72
|
+
# If @response_params is already set, it indicates we've already run the
|
73
|
+
# after_request logic. This can happen when if the response triggers an error,
|
74
|
+
# whch would then trigger the error_call middleware callback, leading to this
|
75
|
+
# being called a second time.
|
76
|
+
return if @response_params
|
77
|
+
|
78
|
+
@response_params = response_params
|
79
|
+
|
80
|
+
if should_record?
|
81
|
+
VCR.record_http_interaction(VCR::HTTPInteraction.new(vcr_request, vcr_response))
|
82
|
+
end
|
83
|
+
|
84
|
+
invoke_after_request_hook(vcr_response)
|
85
|
+
end
|
86
|
+
|
87
|
+
attr_reader :request_params, :response_params, :response_body_reader
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def should_record?
|
92
|
+
@should_record
|
93
|
+
end
|
94
|
+
|
95
|
+
def on_stubbed_by_vcr_request
|
96
|
+
request_params[:response] = {
|
97
|
+
:body => stubbed_response.body,
|
98
|
+
:headers => normalized_headers(stubbed_response.headers || {}),
|
99
|
+
:status => stubbed_response.status.code
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def on_recordable_request
|
104
|
+
@should_record = true
|
105
|
+
end
|
106
|
+
|
107
|
+
def create_response_body_reader
|
108
|
+
block = request_params[:response_block]
|
109
|
+
return NonStreamingResponseBodyReader unless block
|
110
|
+
|
111
|
+
StreamingResponseBodyReader.new(block).tap do |response_block_wrapper|
|
112
|
+
request_params[:response_block] = response_block_wrapper
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def vcr_request
|
117
|
+
@vcr_request ||= begin
|
118
|
+
headers = request_params[:headers].dup
|
119
|
+
headers.delete("Host")
|
120
|
+
|
121
|
+
VCR::Request.new \
|
122
|
+
request_params[:method],
|
123
|
+
uri,
|
124
|
+
request_params[:body],
|
125
|
+
headers
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def vcr_response
|
130
|
+
return @vcr_response if defined?(@vcr_response)
|
131
|
+
|
132
|
+
if should_record? || response_params.has_key?(:response)
|
133
|
+
response = response_params.fetch(:response)
|
134
|
+
|
135
|
+
@vcr_response = VCR::Response.new(
|
136
|
+
VCR::ResponseStatus.new(response.fetch(:status), nil),
|
137
|
+
response.fetch(:headers),
|
138
|
+
response_body_reader.read_body_from(response),
|
139
|
+
nil
|
140
|
+
)
|
141
|
+
else
|
142
|
+
@vcr_response = nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def normalized_headers(headers)
|
147
|
+
normalized = {}
|
148
|
+
headers.each do |k, v|
|
149
|
+
v = v.join(', ') if v.respond_to?(:join)
|
150
|
+
normalized[k] = v
|
151
|
+
end
|
152
|
+
normalized
|
153
|
+
end
|
154
|
+
|
155
|
+
def uri
|
156
|
+
@uri ||= "#{request_params[:scheme]}://#{request_params[:host]}:#{request_params[:port]}#{request_params[:path]}#{query}"
|
157
|
+
end
|
158
|
+
|
159
|
+
# based on:
|
160
|
+
# https://github.com/geemus/excon/blob/v0.7.8/lib/excon/connection.rb#L117-132
|
161
|
+
def query
|
162
|
+
@query ||= case request_params[:query]
|
163
|
+
when String
|
164
|
+
"?#{request_params[:query]}"
|
165
|
+
when Hash
|
166
|
+
qry = '?'
|
167
|
+
for key, values in request_params[:query]
|
168
|
+
if values.nil?
|
169
|
+
qry << key.to_s << '&'
|
170
|
+
else
|
171
|
+
for value in [*values]
|
172
|
+
qry << key.to_s << '=' << CGI.escape(value.to_s) << '&'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
qry.chop! # remove trailing '&'
|
177
|
+
else
|
178
|
+
''
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Wraps an Excon streaming `:response_block`, so that we can
|
184
|
+
# accumulate the response as it streams back from the real HTTP
|
185
|
+
# server in order to record it.
|
186
|
+
#
|
187
|
+
# @private
|
188
|
+
class StreamingResponseBodyReader
|
189
|
+
def initialize(response_block)
|
190
|
+
@response_block = response_block
|
191
|
+
@chunks = []
|
192
|
+
end
|
193
|
+
|
194
|
+
# @private
|
195
|
+
def call(chunk, remaining_bytes, total_bytes)
|
196
|
+
@chunks << chunk
|
197
|
+
@response_block.call(chunk, remaining_bytes, total_bytes)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Provides a duck-typed interface that matches that of
|
201
|
+
# `NonStreamingResponseBodyReader`. The request handler
|
202
|
+
# will use this to get the response body.
|
203
|
+
#
|
204
|
+
# @private
|
205
|
+
def read_body_from(response_params)
|
206
|
+
@chunks.join('')
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Reads the body when no streaming is done.
|
211
|
+
#
|
212
|
+
# @private
|
213
|
+
class NonStreamingResponseBodyReader
|
214
|
+
# Provides a duck-typed interface that matches that of
|
215
|
+
# `StreamingResponseBodyReader`. The request handler
|
216
|
+
# will use this to get the response body.
|
217
|
+
#
|
218
|
+
# @private
|
219
|
+
def self.read_body_from(response_params)
|
220
|
+
response_params.fetch(:body)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|