2016-09-20 14 views
2

私はRuby gem http-2を使ってGETリクエストをGoogleに送信しようとしています。Ruby HTTP2 GETリクエスト

私はexampleから直接コードを持ち上げて、少しそれを単純化してきました:

require 'http/2' 
require 'socket' 
require 'openssl' 
require 'uri' 

uri = URI.parse('http://www.google.com/') 
tcp = TCPSocket.new(uri.host, uri.port) 
sock = tcp 

conn = HTTP2::Client.new 
conn.on(:frame) do |bytes| 
    # puts "Sending bytes: #{bytes.unpack("H*").first}" 
    sock.print bytes 
    sock.flush 
end 
conn.on(:frame_sent) do |frame| 
    puts "Sent frame: #{frame.inspect}" 
end 
conn.on(:frame_received) do |frame| 
    puts "Received frame: #{frame.inspect}" 
end 

stream = conn.new_stream 

stream.on(:close) do 
    puts 'stream closed' 
    sock.close 
end 

stream.on(:half_close) do 
    puts 'closing client-end of the stream' 
end 

stream.on(:headers) do |h| 
    puts "response headers: #{h}" 
end 

stream.on(:data) do |d| 
    puts "response data chunk: <<#{d}>>" 
end 

head = { 
    ':scheme' => uri.scheme, 
    ':method' => 'GET', 
    ':path' => uri.path 
} 

puts 'Sending HTTP 2.0 request' 
stream.headers(head, end_stream: true) 

while !sock.closed? && !sock.eof? 
    data = sock.read_nonblock(1024) 
    # puts "Received bytes: #{data.unpack("H*").first}" 

    begin 
    conn << data 
    rescue => e 
    puts "#{e.class} exception: #{e.message} - closing socket." 
    e.backtrace.each { |l| puts "\t" + l } 
    sock.close 
    end 
end 

出力は次のとおりです。

Sending HTTP 2.0 request 
Sent frame: {:type=>:settings, :stream=>0, :payload=>[[:settings_max_concurrent_streams, 100]]} 
Sent frame: {:type=>:headers, :flags=>[:end_headers, :end_stream], :payload=>[[":scheme", "http"], [":method", "GET"], [":path", "/"]], :stream=>1} 
closing client-end of the stream 

(注意:あなたがすることによって、上記のようにほとんど同じ出力を得ますruby client.rb http://www.google.com/

応答データが表示されないのはなぜですか?

答えて

5

google.comなどのパブリックサーバーは、HTTP/2をクリアテキストでサポートしていません。 に接続しようとしていますが、実際にhttps://google.comに接続する必要があります(httpsスキームに注意してください)。

これを行うには、http-2があなたに適していない場合は、TLSを使用してTCPソケットをラップする必要があります(例:hereを参照)。

また、HTTP/2には強力なTLS暗号とALPNが必要であることに注意してください。更新されたバージョンのOpenSSL(少なくとも1.0.2)がインストールされていることを確認してください。 http-2の著者が強いHTTP/2サポーターであることを、私はあなたの唯一の問題は、あなたがクリアテキストhttpではなく、httpsをしようとしたという事実であると推測しています、と私はTLS暗号強度とALPNが取られていることを期待して考えると

http-2ライブラリによるケア

+0

賢い、ありがとう。はい、ライブラリと上記の例にリンクしていても、暗号化に必要なコードがあります。私は彼らがいつも必要であることを知らなかった。 他の誰かの読書のためだけです:私は間違って上記のリンクのサンプルコードから削除したhttpヘッダーに追加する必要がありました( ':authority' => [uri.host、uri.port] .join ( ':')、 'accept' => '*/*'、)。 –