Class: HTTPX::Connection::HTTP2

Inherits:
Object
  • Object
show all
Includes:
HTTPX::Callbacks, Loggable
Defined in:
lib/httpx/connection/http2.rb

Direct Known Subclasses

Plugins::H2C::H2CParser

Constant Summary collapse

MAX_CONCURRENT_REQUESTS =
HTTP2Next::DEFAULT_MAX_CONCURRENT_STREAMS
Error =
Class.new(Error) do
  def initialize(id, code)
    super("stream #{id} closed with error: #{code}")
  end
end

Constants included from Loggable

Loggable::COLORS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Loggable

#log, #log_exception

Methods included from HTTPX::Callbacks

#emit, #on, #once

Constructor Details

#initialize(buffer, options) ⇒ HTTP2

Returns a new instance of HTTP2.



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/httpx/connection/http2.rb', line 21

def initialize(buffer, options)
  @options = Options.new(options)
  @max_concurrent_requests = @options.max_concurrent_requests || MAX_CONCURRENT_REQUESTS
  @max_requests = @options.max_requests || 0
  @pending = []
  @streams = {}
  @drains  = {}
  @buffer = buffer
  @handshake_completed = false
  init_connection
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &blk) ⇒ Object (private)



311
312
313
314
315
316
317
# File 'lib/httpx/connection/http2.rb', line 311

def method_missing(meth, *args, &blk)
  if @connection.respond_to?(meth)
    @connection.__send__(meth, *args, &blk)
  else
    super
  end
end

Instance Attribute Details

#pendingObject (readonly)

Returns the value of attribute pending.



19
20
21
# File 'lib/httpx/connection/http2.rb', line 19

def pending
  @pending
end

#streamsObject (readonly)

Returns the value of attribute streams.



19
20
21
# File 'lib/httpx/connection/http2.rb', line 19

def streams
  @streams
end

Instance Method Details

#<<(data) ⇒ Object



69
70
71
# File 'lib/httpx/connection/http2.rb', line 69

def <<(data)
  @connection << data
end

#closeObject



54
55
56
57
# File 'lib/httpx/connection/http2.rb', line 54

def close
  @connection.goaway unless @connection.state == :closed
  emit(:close)
end

#consumeObject



93
94
95
96
97
98
99
# File 'lib/httpx/connection/http2.rb', line 93

def consume
  @streams.each do |request, stream|
    next if request.state == :done

    handle(request, stream)
  end
end

#empty?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/httpx/connection/http2.rb', line 59

def empty?
  @connection.state == :closed || @streams.empty?
end

#exhausted?Boolean

Returns:

  • (Boolean)


63
64
65
66
67
# File 'lib/httpx/connection/http2.rb', line 63

def exhausted?
  return false if @max_requests.zero? && @connection.active_stream_count.zero?

  @connection.active_stream_count >= @max_requests
end

#handle_error(ex) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/httpx/connection/http2.rb', line 101

def handle_error(ex)
  @streams.each_key do |request|
    emit(:error, request, ex)
  end
  @pending.each do |request|
    emit(:error, request, ex)
  end
end

#interestsObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/httpx/connection/http2.rb', line 33

def interests
  # waiting for WINDOW_UPDATE frames
  return :r if @buffer.full?

  return :w if @connection.state == :closed

  return :r unless (@connection.state == :connected && @handshake_completed)

  return :w unless @pending.empty?

  return :w if @streams.each_key.any? { |r| r.interests == :w }

  return :r if @buffer.empty?

  :rw
end

#resetObject



50
51
52
# File 'lib/httpx/connection/http2.rb', line 50

def reset
  init_connection
end

#send(request) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/httpx/connection/http2.rb', line 73

def send(request)
  if !@handshake_completed ||
     @streams.size >= @max_concurrent_requests ||
     @streams.size >= @max_requests
    @pending << request
    return
  end
  unless (stream = @streams[request])
    stream = @connection.new_stream
    handle_stream(stream, request)
    @streams[request] = stream
    @max_requests -= 1
  end
  handle(request, stream)
  true
rescue HTTP2Next::Error::StreamLimitExceeded
  @pending.unshift(request)
  emit(:exhausted)
end