Ruby 如何使用适配器防止法拉第更改大写标题

Ruby 如何使用适配器防止法拉第更改大写标题,ruby,adapter,faraday,Ruby,Adapter,Faraday,我正在使用法拉第创建一个SDK,它将与API交互,我需要发送两个标题API_签名和API_请求_时间,所以我创建了: class APIClient def initialize(api_key) @api_key = api_key end def get_users request.post('/users') end private def request Faraday.new(@@BASE_API_URL, headers: hea

我正在使用法拉第创建一个SDK,它将与API交互,我需要发送两个标题API_签名和API_请求_时间,所以我创建了:

class APIClient
  def initialize(api_key)
    @api_key = api_key
  end

  def get_users
    request.post('/users')
  end

  private

  def request
    Faraday.new(@@BASE_API_URL, headers: headers)
  end

  def headers
    timestamp = Time.now.to_i.to_s
    return {
      'API_SIGNATURE': Digest::MD5.hexdigest(@api_key + timestamp),
      'API_REQUEST_TIME': timestamp
    }
  end
end
出于某种原因,法拉第正在将
API\u签名
更改为
API签名
API\u请求时间
更改为
API请求时间

我想阻止这种情况发生。有人建议使用赞助人:

  def request
    Faraday.new(@@BASE_API_URL, headers: headers) do |faraday|
      faraday.adapter :patron
    end
  end
但这不起作用。出现以下错误:

/Users/me/.rvm/gems/ruby-2.4.9/gems/patron-0.13.3/lib/patron/session.rb:330:in `handle_request': Operation timed out after 1004 milliseconds with 0 out of 0 bytes received (Faraday::TimeoutError)
        from /Users/me/.rvm/gems/ruby-2.4.9/gems/patron-0.13.3/lib/patron/session.rb:330:in `request'
        from /Users/me/.rvm/gems/ruby-2.4.9/gems/faraday-0.17.0/lib/faraday/adapter/patron.rb:29:in `call'
        from /Users/me/.rvm/gems/ruby-2.4.9/gems/faraday-0.17.0/lib/faraday/rack_builder.rb:143:in `build_response'
        from /Users/me/.rvm/gems/ruby-2.4.9/gems/faraday-0.17.0/lib/faraday/connection.rb:387:in `run_request'
        from /Users/me/.rvm/gems/ruby-2.4.9/gems/faraday-0.17.0/lib/faraday/connection.rb:175:in `post'
        from api.rb:32:in `analyze_text'
        from api.rb:38:in `full_analysis'
        from api.rb:65:in `<main>'

发生此错误的原因是法拉第在默认情况下使用Net::HTTP,并且。有关此问题的更多信息,请访问

您可以使用下列其他可用适配器之一解决此问题:

或需要其他gem的外部适配器:

您的特定Patron实现看起来是正确的,因此请尝试使用其他适配器之一,看看您是否有更好的运气

更新

我加载了您更新的示例,并亲自进行了测试。解决方案是使用字符串化键。您正在使用符号化键

# symbolized
headers = { API_SIGNATURE: '', API_REQUEST_TIME: '' }
=> {
       :API_SIGNATURE => "",
    :API_REQUEST_TIME => ""
}
这将返回:

puts conn.headers
{"Api-Signature"=>"", "Api-Request-Time"=>"", "User-Agent"=>"Faraday v0.17.0"}
vs:

现在您可以得到正确的值:

puts conn.headers
{"API_SIGNATURE"=>"", "API_REQUEST_TIME"=>"", "User-Agent"=>"Faraday v0.17.0"}
乍一看,您最初的示例似乎是字符串化的,但不是(这就是为什么我没有理解它的原因):


在Ruby中使用冒号作为散列键会自动使它成为一个符号,即使它是一个带引号的字符串。您需要对字符串化键使用hash rocket语法。

解决方案是使用rocket赋值,而不是冒号。像这样:

headers = {
      'Content-Type': 'application/json',
      'x-api-key': '0000'
    }
...
conn.headers
=> {"Content-type"=>"application/json", "X-api-key"=>"0000", "User-Agent"=>"Faraday v0.17.3"}
VS


请注意,x是如何用冒号大写的,而不是它是如何不使用火箭的。

这太奇怪了,它们都不起作用。你认为它可能是我正在使用的Ruby版本吗?(2.5.3随rvm安装)。减少示例,使您不使用类,只使用一个简单的
Faraday。新(…)do | f |
块,将所有数据硬编码到其中,然后重试。在Ruby中非常简单。您想要一个符号化的字符串作为键吗?使用冒号。(
{foo:'bar'}
)是否要对密钥使用任何对象而不更改它?使用散列火箭。(
{1=>'bar'}
{[]=>'bar'}
{Faraday.new=>'bar'}
{'foo'=>'bar'}
甚至
{foo=>'bar'}
puts conn.headers
{"API_SIGNATURE"=>"", "API_REQUEST_TIME"=>"", "User-Agent"=>"Faraday v0.17.0"}
{
  'API_SIGNATURE': '',
  'API_REQUEST_TIME': ''
}
=> {
       :API_SIGNATURE => "",
    :API_REQUEST_TIME => ""
}
headers = {
      'Content-Type': 'application/json',
      'x-api-key': '0000'
    }
...
conn.headers
=> {"Content-type"=>"application/json", "X-api-key"=>"0000", "User-Agent"=>"Faraday v0.17.3"}
headers = {
      'Content-Type' => 'application/json',
      'x-api-key' => '0000'
    }
conn.headers
=> {"Content-Type"=>"application/json", "x-api-key"=>"0000", "User-Agent"=>"Faraday v0.17.3"}