def http_request(action, data, method = 'POST', binary_key = nil)
      data = flatten_nested_hash(data, false)

      uri = "#{@api_uri}/#{action}"
      if method != 'POST'
        uri += "?" + data.map{ |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}" }.join("&")
      end

      req = nil
      headers = {"User-Agent" => "Sailthru API Ruby Client #{Sailthru::VERSION}"}

      _uri  = URI.parse(uri)

      if method == 'POST'
        req = set_up_post_request(
          _uri, data, headers, binary_key
        )

      else
        request_uri = "#{_uri.path}?#{_uri.query}"
        if method == 'DELETE'
          req = Net::HTTP::Delete.new(request_uri, headers)
        else
          req = Net::HTTP::Get.new(request_uri, headers)
        end
      end

      begin
        http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(_uri.host, _uri.port)

        if _uri.scheme == 'https'
          http.ssl_version = :TLSv1
          http.use_ssl = true
          http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify_ssl != true  # some openSSL client doesn't work without doing this
          http.ssl_timeout = @opts[:http_ssl_timeout] || 5
        end
        http.open_timeout = @opts[:http_open_timeout] || 5
        http.read_timeout = @opts[:http_read_timeout] || 10
        http.close_on_empty_response = @opts[:http_close_on_empty_response] || true

        response = http.start do
          http.request(req)
        end

      rescue Timeout::Error, Errno::ETIMEDOUT => e
        raise UnavailableError, "Timed out: #{_uri}"
      rescue => e
        raise ClientError, "Unable to open stream to #{_uri}: #{e.message}"
      end

      save_rate_limit_info(action, method, response)

      response.body || raise(ClientError, "No response received from stream: #{_uri}")
    end
def http_request(action, data, method = 'POST', binary_key = nil)
      data = flatten_nested_hash(data, false)

      uri = "#{@api_uri}/#{action}"
      if method != 'POST'
        uri += "?" + data.map{ |key, value| "#{CGI::escape(key.to_s)}=#{CGI::escape(value.to_s)}" }.join("&")
      end

      req = nil
      headers = {"User-Agent" => "Sailthru API Ruby Client #{Sailthru::VERSION}"}

      _uri  = URI.parse(uri)

      if method == 'POST'
        req = set_up_post_request(
          _uri, data, headers, binary_key
        )

      else
        request_uri = "#{_uri.path}?#{_uri.query}"
        if method == 'DELETE'
          req = Net::HTTP::Delete.new(request_uri, headers)
        else
          req = Net::HTTP::Get.new(request_uri, headers)
        end
      end

      begin
        http = Net::HTTP::Proxy(@proxy_host, @proxy_port).new(_uri.host, _uri.port)

        if _uri.scheme == 'https'
          http.ssl_version = :TLSv1
          http.use_ssl = true
          http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @verify_ssl != true  # some openSSL client doesn't work without doing this
          http.ssl_timeout = @opts[:http_ssl_timeout] || 5
        end
        http.open_timeout = @opts[:http_open_timeout] || 5
        http.read_timeout = @opts[:http_read_timeout] || 10
        http.close_on_empty_response = @opts[:http_close_on_empty_response] || true

        response = http.start do
          http.request(req)
        end

      rescue Timeout::Error, Errno::ETIMEDOUT => e
        raise UnavailableError, "Timed out: #{_uri}"
      rescue => e
        raise ClientError, "Unable to open stream to #{_uri}: #{e.message}"
      end

      save_rate_limit_info(action, method, response)

      response.body || raise(ClientError, "No response received from stream: #{_uri}")
    end
params:
   uri, String
   data, Hash
   method, String "GET" or "POST"
 returns:
   String, body of response