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