class VCR::Middleware::Faraday::RequestHandler
@private
def collect_chunks
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 delay_finishing?
def delay_finishing? !!env[:parallel_manager] && @has_on_complete_hook end
def handle
def handle # 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 invoke_after_request_hook(response) unless delay_finishing? end
def initialize(app, env)
def initialize(app, env) @app, @env = app, env @has_on_complete_hook = false end
def invoke_after_request_hook(response)
def invoke_after_request_hook(response) super VCR.library_hooks.exclusive_hook = nil end
def on_ignored_request
def on_ignored_request response = app.call(env) @vcr_response = response_for(response) response end
def on_recordable_request
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? end end
def on_stubbed_by_vcr_request
def on_stubbed_by_vcr_request headers = env[:response_headers] ||= ::Faraday::Utils::Headers.new headers.update stubbed_response.headers if stubbed_response.headers env.update :status => stubbed_response.status.code, :body => stubbed_response.body @vcr_response = stubbed_response faraday_response = ::Faraday::Response.new env.request.on_data.call(stubbed_response.body, stubbed_response.body.length) if env.request.stream_response? faraday_response.finish(env) env[:response] = faraday_response end
def raw_body_from(body)
def raw_body_from(body) return body unless body.respond_to?(:read) body.read.tap do |b| body.rewind if body.respond_to?(:rewind) end end
def response_for(response)
def response_for(response) # reason_phrase is a new addition to Faraday::Response, # so maintain backward compatibility reason = response.respond_to?(:reason_phrase) ? response.reason_phrase : nil VCR::Response.new( VCR::ResponseStatus.new(response.status, reason), response.headers, raw_body_from(response.body), nil ) end
def restore_body_from_chunks(request)
def restore_body_from_chunks(request) env[:body] = request.instance_variable_get(:@chunked_body) end
def vcr_request
def vcr_request @vcr_request ||= VCR::Request.new \ env[:method], env[:url].to_s, raw_body_from(env[:body]), env[:request_headers] end