【问题标题】:enforcing Faraday adapter :typhoeus to use HTTP/2 for requests强制法拉第适配器 :typhoeus 使用 HTTP/2 请求
【发布时间】:2019-10-29 10:07:27
【问题描述】:

如何强制Faraday 适配器typhoeus 使用HTTP/2 对支持HTTP/2 的服务器的请求? 我已经通过服务https://http2.pro/doc/api 对此进行了测试,结果是这样的:

body="{\"http2\":1,\"protocol\":\"HTTP\\/2.0\",\"push\":0,\"user_agent\":\"Faraday v0.12.2\"}",

\"http2\":1, 什么意思 HTTP/2 不用于请求!

【问题讨论】:

    标签: ruby http2 faraday typhoeus


    【解决方案1】:

    这里有两件事在起作用。首先是远程 API 在响应正文中对您撒谎。他们的文件说:

    http2:可能的值为 0(使用 HTTP/2)和 1(未使用 HTTP/2)。

    即使响应正文显示 'http2': 1 表明未使用 HTTP2,它正在被使用。您可以使用 Chrome 的开发工具轻松确认这一点:

    所以一旦我们知道 API 位于响应正文中,我们如何独立确认 Typhoeus 使用的是 HTTP2?

    (此答案假设您使用 pry 作为您的 REPL,而不是 IRB)

    首先让我们确认 Typhoeus 将单独使用 HTTP2:

    require 'typhoeus'
    response = Typhoeus.get("https://http2.pro/api/v1", http_version: :httpv2_0)
    response.class
    => Typhoeus::Response < Object
    response.body
    => "{\"http2\":1,\"protocol\":\"HTTP\\/2.0\",\"push\":0,\"user_agent\":\"Typhoeus - https:\\/\\/github.com\\/typhoeus\\/typhoeus\"}" # this is the lying API response
    response.http_version
    => "2" # this is what Typhoeus tells us was actually used
    

    现在让我们在法拉第测试它:

    require 'faraday'
    require 'typhoeus'
    require 'typhoeus/adapters/faraday'
    
    conn = Faraday.new do |faraday|
      faraday.adapter :typhoeus, http_version: :httpv2_0
    end
    
    response = conn.get("https://http2.pro/api/v1")
    response.body
    => "{\"http2\":1,\"protocol\":\"HTTP\\/2.0\",\"push\":0,\"user_agent\":\"Faraday v0.17.0\"}" # again we get the lying API response
    

    但是我们如何确认它是 HTTP2 呢?这不起作用:

    response.http_version
    NoMethodError: undefined method `http_version' for #<Faraday::Response:0x00007f99935519a8>
    

    因为response 不是Typhoeus::Response 对象,所以它是法拉第对象:

    response.class
    => Faraday::Response < Object
    

    所以我们需要进入 gem 本身来确定它在哪里创建 Typhoeus::Response 对象,以便我们可以手动调用 .http_version 并确认它使用我们期望的协议。事实证明,那是right here

    让我们采取简单的方法,将 binding.pry 粘贴到我们的本地 gem 副本中(您需要重新启动 pry 以获取对 gem 的更改):

      def typhoeus_request(env)
        opts = {
          :method => env[:method],
          :body => env[:body],
          :headers => env[:request_headers]
        }.merge(@adapter_options)
        binding.pry
        ::Typhoeus::Request.new(env[:url].to_s, opts)
      end
    

    然后重新运行请求:

    require 'faraday'
    require 'typhoeus'
    require 'typhoeus/adapters/faraday'
    
    conn = Faraday.new do |faraday|
      faraday.adapter :typhoeus, http_version: :httpv2_0
    end
    
    response = conn.get("https://http2.pro/api/v1")
    

    你会看到:

    Frame number: 0/3
    
    From: /Users/foo/.rvm/gems/ruby-2.6.3/gems/typhoeus-1.3.1/lib/typhoeus/adapters/faraday.rb @ line 127 Faraday::Adapter::Typhoeus#typhoeus_request:
    
        120: def typhoeus_request(env)
        121:   opts = {
        122:     :method => env[:method],
        123:     :body => env[:body],
        124:     :headers => env[:request_headers]
        125:   }.merge(@adapter_options)
        126:   binding.pry
     => 127:   ::Typhoeus::Request.new(env[:url].to_s, opts)
        128: end
    

    现在输入:

    response = ::Typhoeus::Request.new(env[:url].to_s, opts).run
    

    并确认它是Typhoeus::Response 对象:

    response.class
    => Typhoeus::Response < Object
    

    并确认它使用的是 HTTP2:

    response.http_version
    => "2"
    

    并确认 API 响应体是一个肮脏的骗子:

    response.body
    => "{\"http2\":1,\"protocol\":\"HTTP\\/2.0\",\"push\":0,\"user_agent\":\"Faraday v0.17.0\"}"
    

    这就是您使用 Typhoeus 作为法拉第适配器来发出 HTTP2 请求的方式。

    【讨论】:

      猜你喜欢
      • 2016-06-01
      • 2020-12-02
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 2017-06-01
      • 2012-07-16
      相关资源
      最近更新 更多