class NetHttp2::Client
Attributes
Public Class Methods
Source
# File lib/net-http2/client.rb, line 19 def initialize(url, options={}) @uri = URI.parse(url) @connect_timeout = options[:connect_timeout] || 60 @ssl_context = add_npn_to_context(options[:ssl_context] || OpenSSL::SSL::SSLContext.new) PROXY_SETTINGS_KEYS.each do |key| instance_variable_set("@#{key}", options[key]) if options[key] end @is_ssl = (@uri.scheme == 'https') @mutex = Mutex.new init_vars end
Public Instance Methods
Source
# File lib/net-http2/client.rb, line 34 def call(method, path, options={}) request = prepare_request(method, path, options) ensure_open new_stream.call_with request end
Source
# File lib/net-http2/client.rb, line 40 def call_async(request) ensure_open stream = new_monitored_stream_for request stream.async_call_with request end
Source
# File lib/net-http2/client.rb, line 54 def close exit_thread(@socket_thread) init_vars end
Source
# File lib/net-http2/client.rb, line 59 def join(timeout: nil) starting_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) while !@streams.empty? do raise AsyncRequestTimeout if timeout && Process.clock_gettime(Process::CLOCK_MONOTONIC) - starting_time > timeout sleep 0.05 end end
Source
# File lib/net-http2/client.rb, line 46 def prepare_request(method, path, options={}) NetHttp2::Request.new(method, @uri, path, options) end
Source
# File lib/net-http2/client.rb, line 67 def remote_settings h2.remote_settings end
Private Instance Methods
Source
# File lib/net-http2/client.rb, line 184 def add_npn_to_context(ctx) ctx.npn_protocols = [DRAFT] ctx.npn_select_cb = lambda do |protocols| DRAFT if protocols.include?(DRAFT) end ctx end
Source
# File lib/net-http2/client.rb, line 130 def callback_or_raise(exception) if callback_events.keys.include?(:error) emit(:error, exception) else raise exception end end
Source
# File lib/net-http2/client.rb, line 105 def ensure_open @mutex.synchronize do return if @socket_thread @socket = new_socket @socket_thread = Thread.new do begin socket_loop rescue EOFError # socket closed init_vars callback_or_raise SocketError.new('Socket was remotely closed') rescue Exception => e # error on socket init_vars callback_or_raise e end end.tap { |t| t.abort_on_exception = true } end end
Source
# File lib/net-http2/client.rb, line 165 def ensure_sent_before_receiving while !@first_data_sent sleep 0.01 end end
Source
# File lib/net-http2/client.rb, line 192 def exit_thread(thread) return unless thread thread.exit thread.join end
Source
# File lib/net-http2/client.rb, line 171 def h2 @h2 ||= HTTP2::Client.new.tap do |h2| h2.on(:frame) do |bytes| @mutex.synchronize do @socket.write(bytes) @socket.flush @first_data_sent = true end end end end
Source
# File lib/net-http2/client.rb, line 77 def init_vars @mutex.synchronize do @socket.close if @socket && !@socket.closed? @h2 = nil @socket = nil @socket_thread = nil @first_data_sent = false @streams = {} end end
Source
# File lib/net-http2/client.rb, line 96 def new_monitored_stream_for(request) stream = new_stream @streams[stream.id] = true request.on(:close) { @streams.delete(stream.id) } stream end
Source
# File lib/net-http2/client.rb, line 157 def new_socket options = { ssl: ssl?, ssl_context: @ssl_context, connect_timeout: @connect_timeout } PROXY_SETTINGS_KEYS.each { |k| options[k] = instance_variable_get("@#{k}") } NetHttp2::Socket.create(@uri, options) end
Source
# File lib/net-http2/client.rb, line 89 def new_stream @mutex.synchronize { NetHttp2::Stream.new(h2_stream: h2.new_stream) } rescue StandardError => e close raise e end
Source
# File lib/net-http2/client.rb, line 138 def socket_loop ensure_sent_before_receiving loop do begin data_received = @socket.read_nonblock(1024) h2 << data_received rescue IO::WaitReadable IO.select([@socket]) retry rescue IO::WaitWritable IO.select(nil, [@socket]) retry end end end