class Seahorse::Client::NetHttp::Handler

The default HTTP handler for Seahorse::Client. This is based on the Ruby's `Net::HTTP`.

Constants

DNS_ERROR_MESSAGE

@api private

NETWORK_ERRORS

Public Instance Methods

call(context) click to toggle source

@param [RequestContext] context @return [Response]

# File lib/seahorse/client/net_http/handler.rb, line 33
def call(context)
  transmit(context.config, context.http_request, context.http_response)
  Response.new(context: context)
end
pool_for(config) click to toggle source

@param [Configuration] config @return [ConnectionPool]

# File lib/seahorse/client/net_http/handler.rb, line 40
def pool_for(config)
  ConnectionPool.for(pool_options(config))
end

Private Instance Methods

build_net_request(request) click to toggle source

Constructs and returns a Net::HTTP::Request object from a {Http::Request}. @param [Http::Request] request @return [Net::HTTP::Request]

# File lib/seahorse/client/net_http/handler.rb, line 128
def build_net_request(request)
  request_class = net_http_request_class(request)
  req = request_class.new(request.endpoint.request_uri, headers(request))
  req.body_stream = request.body
  req
end
complete_response(req, resp, bytes_received) click to toggle source
# File lib/seahorse/client/net_http/handler.rb, line 85
def complete_response(req, resp, bytes_received)
  if should_verify_bytes?(req, resp)
    verify_bytes_received(resp, bytes_received)
  else
    resp.signal_done
  end
end
error_message(req, error) click to toggle source
# File lib/seahorse/client/net_http/handler.rb, line 46
def error_message(req, error)
  if error.is_a?(SocketError) && error.message == DNS_ERROR_MESSAGE
    host = req.endpoint.host
    "unable to connect to `#{host}`; SocketError: #{error.message}"
  else
    error.message
  end
end
extract_headers(response) click to toggle source

@param [Net::HTTP::Response] response @return [Hash<String, String>]

# File lib/seahorse/client/net_http/handler.rb, line 160
def extract_headers(response)
  response.to_hash.inject({}) do |headers, (k, v)|
    headers[k] = v.first
    headers
  end
end
headers(request) click to toggle source

@param [Http::Request] request @return [Hash] Returns a vanilla hash of headers to send with the

HTTP request.
# File lib/seahorse/client/net_http/handler.rb, line 149
def headers(request)
  # setting these to stop net/http from providing defaults
  headers = { 'content-type' => '', 'accept-encoding' => '' }
  request.headers.each_pair do |key, value|
    headers[key] = value
  end
  headers
end
net_http_request_class(request) click to toggle source

@param [Http::Request] request @raise [InvalidHttpVerbError] @return Returns a base `Net::HTTP::Request` class, e.g.,

`Net::HTTP::Get`, `Net::HTTP::Post`, etc.
# File lib/seahorse/client/net_http/handler.rb, line 139
def net_http_request_class(request)
  Net::HTTP.const_get(request.http_method.capitalize)
rescue NameError
  msg = "`#{request.http_method}` is not a valid http verb"
  raise InvalidHttpVerbError, msg
end
pool_options(config) click to toggle source

Extracts the {ConnectionPool} configuration options. @param [Configuration] config @return [Hash]

# File lib/seahorse/client/net_http/handler.rb, line 117
def pool_options(config)
  ConnectionPool::OPTIONS.keys.inject({}) do |opts,opt|
    opts[opt] = config.send(opt)
    opts
  end
end
session(config, req) { |http| ... } click to toggle source
# File lib/seahorse/client/net_http/handler.rb, line 107
def session(config, req, &block)
  pool_for(config).session_for(req.endpoint) do |http|
    http.read_timeout = config.http_read_timeout
    yield(http)
  end
end
should_verify_bytes?(req, resp) click to toggle source
# File lib/seahorse/client/net_http/handler.rb, line 93
def should_verify_bytes?(req, resp)
  req.http_method != 'HEAD' && resp.headers['content-length']
end
transmit(config, req, resp) click to toggle source

@param [Configuration] config @param [Http::Request] req @param [Http::Response] resp @return [void]

# File lib/seahorse/client/net_http/handler.rb, line 59
def transmit(config, req, resp)
  session(config, req) do |http|
    http.request(build_net_request(req)) do |net_resp|

      status_code = net_resp.code.to_i
      headers = extract_headers(net_resp)

      bytes_received = 0
      resp.signal_headers(status_code, headers)
      net_resp.read_body do |chunk|
        bytes_received += chunk.bytesize
        resp.signal_data(chunk)
      end
      complete_response(req, resp, bytes_received)

    end
  end
rescue *NETWORK_ERRORS => error
  # these are retryable
  error = NetworkingError.new(error, error_message(req, error))
  resp.signal_error(error)
rescue => error
  # not retryable
  resp.signal_error(error)
end
verify_bytes_received(resp, bytes_received) click to toggle source
# File lib/seahorse/client/net_http/handler.rb, line 97
def verify_bytes_received(resp, bytes_received)
  bytes_expected = resp.headers['content-length'].to_i
  if bytes_expected == bytes_received
    resp.signal_done
  else
    error = TruncatedBodyError.new(bytes_expected, bytes_received)
    resp.signal_error(NetworkingError.new(error, error.message))
  end
end