2016-09-20 4 views
2

Ruby gem http-2을 사용하여 Google에 GET 요청을 보내려고합니다.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 방식을 참고) https://google.com에 연결해야합니다 동안

당신은 http://google.com에 연결하려고합니다.

이렇게하려면 http-2이 도움이되지 않으면 TLS (예 : here 참조)를 사용하여 TCP 소켓을 포장해야 할 수도 있습니다.

또한 HTTP/2에는 강력한 TLS 암호와 ALPN이 필요하므로 OpenSSL (1.0.2 이상)의 업데이트 된 버전이 있는지 확인하십시오.

http-2의 저자가 강한 HTTP/2 후원자임을 감안할 때, 나는 당신의 유일한 문제는 당신이 https보다는 일반 텍스트 http을 시도한다는 사실은 추측하고있다, 나는 TLS 암호화 강도와 ALPN을 취하는 것으로 기대 라이브러리 http-2에 의해 관리됩니다.

+0

훌륭합니다. 감사합니다. 예, 라이브러리와 위의 예와 연결된 코드의 경우에도 암호화에 필요한 코드가 있습니다. 나는 그들이 언제나 필요하다는 것을 몰랐다. 그냥 다른 사람을 위해서 : http 헤더에 내가 위의 예제 코드에서 잘못 제거했다고 다시 추가해야했습니다 (': authority'=> [uri.host, uri.port] .join (':'), 'accept'=> '*/*'). –