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