在 Ruby 中发送 HTTP/2 POST 请求
Posted
技术标签:
【中文标题】在 Ruby 中发送 HTTP/2 POST 请求【英文标题】:Sending HTTP/2 POST request in Ruby 【发布时间】:2016-03-31 05:15:45 【问题描述】:我正在尝试使用基于HTTP/2 的新Apple Push Notification API。
我找到了 http-2 Ruby gem,但文档并不清楚如何作为客户端发出请求。
如何在 Ruby/Rails 中发出 HTTP/2 请求?
【问题讨论】:
你是我听说第一个尝试使用 HTTP2 的人,祝你好运,你会需要它 :D 【参考方案1】:这是使用async-http
的方法:
#!/usr/bin/env ruby
require 'async'
require 'async/logger'
require 'async/http/client'
require 'async/http/url_endpoint'
Async do
endpoint = Async::HTTP::URLEndpoint.parse("https://www.google.com")
client = Async::HTTP::Client.new(endpoint)
headers =
'accept' => 'text/html',
request = Async::HTTP::Request.new("www.google.com", "GET", "/search?q=cats", headers)
response = client.call(request)
body = response.read
end
这将根据需要协商 HTTP/1、HTTP/2 和 SSL。
【讨论】:
【参考方案2】:免责声明:我是下面列出的两颗宝石的作者。
如果你想发起 HTTP/2 调用,你可以考虑NetHttp2,一个 Ruby 的 HTTP/2 客户端。
同步调用的使用示例:
require 'net-http2'
# create a client
client = NetHttp2::Client.new("http://106.186.112.116")
# send request
response = client.call(:get, '/')
# read the response
response.ok? # => true
response.status # => '200'
response.headers # => ":status"=>"200"
response.body # => "A body"
# close the connection
client.close
除了自己编写 HTTP/2 调用之外,如果您想要一个 Apple Push Notification gem,它使用新的 HTTP/2 细节并且可以嵌入到 Rails 环境中,那么您还可以考虑Apnotic。
用法很简单:
require 'apnotic'
# create a persistent connection
connection = Apnotic::Connection.new(cert_path: "apns_certificate.pem", cert_pass: "pass")
# create a notification for a specific device token
token = "6c267f26b173cd9595ae2f6702b1ab560371a60e7c8a9e27419bd0fa4a42e58f"
notification = Apnotic::Notification.new(token)
notification.alert = "Notification from Apnotic!"
# send (this is a blocking call)
response = connection.push(notification)
# read the response
response.ok? # => true
response.status # => '200'
response.headers # => ":status"=>"200", "apns-id"=>"6f2cd350-bfad-4af0-a8bc-0d501e9e1799"
response.body # => ""
# close the connection
connection.close
【讨论】:
【参考方案3】:我一直在为此开发客户端实现:https://github.com/alloy/lowdown。
到目前为止,我一直在对其进行广泛的测试,但要到下周才能将其部署到生产环境中。我希望它能够获得更多测试、反馈等。
【讨论】:
【参考方案4】:this file 中有一个创建 HTTP/2 客户端的示例。它可以适应这样的 APN 请求:
require 'socket'
require 'http/2'
payload = '"foo":"bar"'
device_token = '00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0' # example
sock = TCPSocket.new('api.development.push.apple.com', 443)
conn = HTTP2::Client.new
conn.on(:frame) do |bytes|
puts "Sending bytes: #bytes.unpack("H*").first"
sock.print bytes
sock.flush
end
stream = conn.new_stream
stream.on(:close) do
sock.close
end
head =
':scheme' => 'https',
':method' => 'POST',
':path' => "/3/device/#device_token",
'apns-id' => '123e4567-e89b-12d3-a456-42665544000', # or you could omit this header
'content-length' => payload.bytesize.to_s # should be less than or equal to 4096 bytes
puts 'Sending HTTP 2.0 request'
stream.headers(head, end_stream: false)
stream.data(payload)
while !sock.closed? && !sock.eof?
data = sock.read_nonblock(1024)
puts "Received bytes: #data.unpack("H*").first"
begin
conn << data
rescue => e
puts "Exception: #e, #e.message - closing socket."
sock.close
end
end
【讨论】:
以上是关于在 Ruby 中发送 HTTP/2 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ruby-on-rails 应用程序上使用 Rack 发送 POST 模拟请求?