首页 > 解决方案 > 如何使用适配器防止法拉第更改大写标题

问题描述

我正在使用 Faraday 创建一个将与 API 交互的 SDK,我需要发送两个标头 API_SIGNATURE 和 API_REQUEST_TIME,这就是我创建的:

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_SIGNATUREApi-Signature和。API_REQUEST_TIMEApi-Request-Time

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

  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>'

谢谢你。

=======更新==========

问题减少了:

headers = { API_SIGNATURE: '', API_REQUEST_TIME: '' }

conn = Faraday.new('https://api.test.io', headers: headers) do |f|
  f.adapter :patron
end

puts conn.headers

标签: rubyadapterfaraday

解决方案


发生此错误是因为 Faraday 默认使用 Net::HTTP 并且Net::HTTP 更改了标头键的大小写您可以在此相关问题中阅读有关此问题的更多信息。

您可以通过使用https://lostisland.github.io/faraday/adapters/中列出的其他可用适配器之一来解决此问题:

或需要其他 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"}

与:

# stringified
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"}

乍一看,您的原始示例似乎是字符串化的,但不是(这就是我没有抓住它的原因):

{
  'API_SIGNATURE': '',
  'API_REQUEST_TIME': ''
}
=> {
       :API_SIGNATURE => "",
    :API_REQUEST_TIME => ""
}

在 Ruby 中使用冒号作为哈希键会自动使其成为符号,即使它是带引号的字符串。您需要对字符串化键使用哈希火箭语法。


推荐阅读