强制法拉第适配器 :typhoeus 对请求使用 HTTP/2
enforcing Faraday adapter :typhoeus to use HTTP/2 for requests
如何强制 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 不用于请求!
这里有两件事在起作用。首先是 remote API 在响应正文中对你撒谎。他们的文档说:
http2: Possible values are 0 (HTTP/2 was used) and 1 (HTTP/2 was not used).
尽管响应正文显示 '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 请求的方式。
如何强制 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 不用于请求!
这里有两件事在起作用。首先是 remote API 在响应正文中对你撒谎。他们的文档说:
http2: Possible values are 0 (HTTP/2 was used) and 1 (HTTP/2 was not used).
尽管响应正文显示 '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 请求的方式。