class LookerSDK::Client::StreamingClient

Since Faraday currently won't do streaming for us, we use Net::HTTP. Still, we go to the trouble to go through the Sawyer/Faraday codepath so that we can leverage all the header and param processing they do in order to be as consistent as we can with the normal non-streaming codepath. This class replaces the default Faraday 'builder' that Faraday uses to do the actual request after all the setup is done.

Public Class Methods

new(client, &block) click to toggle source
# File lib/looker-sdk/client.rb, line 361
def initialize(client, &block)
  @client, @block = client, block
end

Public Instance Methods

build_response(connection, request) click to toggle source

This is the method that faraday calls on a builder to do the actual request and build a response.

# File lib/looker-sdk/client.rb, line 366
def build_response(connection, request)
  full_path = connection.build_exclusive_url(request.path, request.params,
                                             request.options.params_encoder).to_s
  uri = URI(full_path)
  path_with_query = uri.query ? "#{uri.path}?#{uri.query}" : uri.path

  http_request = (
    case request.method
    when :get     then Net::HTTP::Get
    when :post    then Net::HTTP::Post
    when :put     then Net::HTTP::Put
    when :patch   then Net::HTTP::Patch
    else raise "Stream to block not supported for '#{request.method}'"
    end
  ).new(path_with_query, request.headers)

  http_request.body = request.body

  connect_opts = {
    :use_ssl => !!connection.ssl,
    :verify_mode => (connection.ssl.verify rescue true) ?
      OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE,
  }

  # TODO: figure out how/if to support proxies
  # TODO: figure out how to test this comprehensively

  progress = nil
  Net::HTTP.start(uri.host, uri.port, connect_opts) do |http|
    http.open_timeout = connection.options.open_timeout rescue 30
    http.read_timeout = connection.options.timeout rescue 60

    http.request(http_request) do |response|
      progress = Progress.new(response)
      if response.code == "200"
        response.read_body do |chunk|
          next unless chunk.length > 0
          progress.add_chunk(chunk)
          @block.call(chunk, progress)
          return OpenStruct.new(status:"0", headers:{}, env:nil, body:nil) if progress.stopped?
        end
      end
    end
  end

  return OpenStruct.new(status:"500", headers:{}, env:nil, body:nil) unless progress

  OpenStruct.new(status:progress.response.code, headers:progress.response, env:nil, body:nil)
end