Skip to content

Commit

Permalink
Add support for on_data with faraday.
Browse files Browse the repository at this point in the history
Followed style of #656 for Typhoeus.
  • Loading branch information
zeisler committed Jun 15, 2020
1 parent 5c57aa5 commit 4ee2db3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
19 changes: 18 additions & 1 deletion lib/vcr/middleware/faraday.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ def initialize(app, env)
end

def handle
# Faraday must be exlusive here in case another library hook is being used.
# Faraday must be exclusive here in case another library hook is being used.
# We don't want double recording/double playback.
VCR.library_hooks.exclusive_hook = :faraday
collect_chunks if env.request.stream_response?

super
ensure
response = defined?(@vcr_response) ? @vcr_response : nil
Expand Down Expand Up @@ -111,6 +113,7 @@ def on_recordable_request
@has_on_complete_hook = true
response = app.call(env)
response.on_complete do
restore_body_from_chunks(env.request) if env.request.stream_response?
@vcr_response = response_for(response)
VCR.record_http_interaction(VCR::HTTPInteraction.new(vcr_request, @vcr_response))
invoke_after_request_hook(@vcr_response) if delay_finishing?
Expand All @@ -121,6 +124,20 @@ def invoke_after_request_hook(response)
super
VCR.library_hooks.exclusive_hook = nil
end

def collect_chunks
caller_on_data = env.request.on_data
chunks = ''
env.request.on_data = Proc.new do |chunk, overall_received_bytes|
chunks += chunk
env.request.instance_variable_set(:@chunked_body, chunks)
caller_on_data.call(chunk, overall_received_bytes)
end
end

def restore_body_from_chunks(request)
env[:body] = request.instance_variable_get(:@chunked_body)
end
end
end
end
Expand Down
29 changes: 29 additions & 0 deletions spec/lib/vcr/library_hooks/faraday_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,34 @@
VCR::Middleware::Faraday
])
end

context 'when using on_data callback' do
def make_request
VCR.use_cassette('no_body') do
conn = Faraday.new(:url => "http://localhost:#{VCR::SinatraApp.port}") do |builder|
builder.request :url_encoded
builder.response :logger
builder.adapter :net_http
end
conn.get("localhost_test") do |request|
request.options.on_data = Proc.new do |chunk, overall_received_bytes|
on_data_capture.push [chunk, overall_received_bytes]
end
end
end
end

let(:on_data_capture) { [] }

it 'records and replays correctly' do
expect(on_data_capture).to receive(:push).with(["Localhost response", 18])

recorded = make_request
played_back = make_request

expect(recorded.body).to eq('Localhost response')
expect(played_back.body).to eq(recorded.body)
end
end
end

0 comments on commit 4ee2db3

Please sign in to comment.