example/client.rb in http-2-0.6.1 vs example/client.rb in http-2-0.6.3

- old
+ new

@@ -1,46 +1,104 @@ require_relative 'helper' -Addrinfo.tcp("localhost", 8080).connect do |sock| - conn = HTTP2::Connection.new(:client) - conn.on(:frame) do |bytes| - puts "Sending bytes: #{bytes.inspect}" - sock.print bytes - sock.flush +options = {} +OptionParser.new do |opts| + opts.banner = "Usage: client.rb [options]" + + opts.on("-d", "--data [String]", "HTTP payload") do |v| + options[:payload] = v end +end.parse! - stream = conn.new_stream - log = Logger.new(stream.id) - stream.on(:close) do - log.info "stream closed" - sock.close - end +uri = URI.parse(ARGV[0] || 'http://localhost:8080/') +tcp = TCPSocket.new(uri.host, uri.port) +sock = nil - stream.on(:half_close) do - log.info "closing client-end of the stream" - end +if uri.scheme == 'https' + ctx = OpenSSL::SSL::SSLContext.new + ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE - stream.on(:headers) do |h| - log.info "response headers: #{h}" + ctx.npn_protocols = [DRAFT] + ctx.npn_select_cb = lambda do |protocols| + puts "NPN protocols supported by server: #{protocols}" + DRAFT if protocols.include? DRAFT end - stream.on(:data) do |d| - log.info "response data chunk: <<#{d}>>" + sock = OpenSSL::SSL::SSLSocket.new(tcp, ctx) + sock.sync_close = true + sock.hostname = uri.hostname + sock.connect + + if sock.npn_protocol != DRAFT + puts "Failed to negotiate #{DRAFT} via NPN" + exit end +else + sock = tcp +end - puts "Sending POST request" - stream.headers({ - ":method" => "post", - ":host" => "localhost", - ":path" => "/resource", - "accept" => "*/*" - }) +conn = HTTP2::Client.new +conn.on(:frame) do |bytes| + puts "Sending bytes: #{bytes.inspect}" + sock.print bytes + sock.flush +end - stream.data("woot!") +stream = conn.new_stream +log = Logger.new(stream.id) - while !sock.closed? && !sock.eof? - data = sock.readpartial(1024) - puts "Received bytes: #{data.inspect}" +conn.on(:promise) do |promise| + promise.on(:headers) do |h| + log.info "promise headers: #{h}" + end + + promise.on(:data) do |d| + log.info "promise data chunk: <<#{d.size}>>" + end +end + +stream.on(:close) do + log.info "stream closed" + sock.close +end + +stream.on(:half_close) do + log.info "closing client-end of the stream" +end + +stream.on(:headers) do |h| + log.info "response headers: #{h}" +end + + +stream.on(:data) do |d| + log.info "response data chunk: <<#{d}>>" +end + +head = { + ":scheme" => uri.scheme, + ":method" => (options[:payload].nil? ? "get" : "post"), + ":host" => [uri.host, uri.port].join(':'), + ":path" => uri.path, + "accept" => "*/*" +} + +puts "Sending HTTP 2.0 request" +if head[":method"] == "get" + stream.headers(head, end_stream: true) +else + stream.headers(head, end_stream: false) + stream.data(options[:payload]) +end + +while !sock.closed? && !sock.eof? + data = sock.read_nonblock(1024) + # puts "Received bytes: #{data.inspect}" + + begin conn << data + rescue Exception => e + puts "Exception: #{e}, #{e.message} - closing socket." + sock.close end end