class HTTPX::Connection

  1. lib/httpx/connection.rb
  2. lib/httpx/connection/http1.rb
  3. lib/httpx/connection/http2.rb
  4. show all
Superclass: Object

The Connection can be watched for IO events.

It contains the io object to read/write from, and knows what to do when it can.

It defers connecting until absolutely necessary. Connection should be triggered from the IO selector (until then, any request will be queued).

A connection boots up its parser after connection is established. All pending requests will be redirected there after connection.

A connection can be prevented from closing by the parser, that is, if there are pending requests. This will signal that the connection was prematurely closed, due to a possible number of conditions:

  • Remote peer closed the connection (“Connection: close”);

  • Remote peer doesn't support pipelining;

A connection may also route requests for a different host for which the io was connected to, provided that the IP is the same and the port and scheme as well. This will allow to share the same socket to send HTTP/2 requests to different hosts.

Included modules

  1. Registry
  2. Loggable
  3. Callbacks

Constants

BUFFER_SIZE = 1 << 14  

Attributes

options [R]
origin [R]
pending [R]
state [R]

Public Class methods

new (type, uri, options)
[show source]
   # File lib/httpx/connection.rb
49 def initialize(type, uri, options)
50   @type = type
51   @origins = [uri.origin]
52   @origin = URI(uri.origin)
53   @options = Options.new(options)
54   @window_size = @options.window_size
55   @read_buffer = Buffer.new(BUFFER_SIZE)
56   @write_buffer = Buffer.new(BUFFER_SIZE)
57   @pending = []
58   on(:error, &method(:on_error))
59   if @options.io
60     # if there's an already open IO, get its
61     # peer address, and force-initiate the parser
62     transition(:already_open)
63     @io = IO.registry(@type).new(@origin, nil, @options)
64     parser
65   else
66     transition(:idle)
67   end
68 end

Public Instance methods

addresses ()
[show source]
   # File lib/httpx/connection.rb
76 def addresses
77   @io && @io.addresses
78 end
addresses= (addrs)

this is a semi-private method, to be used by the resolver to initiate the io object.

[show source]
   # File lib/httpx/connection.rb
72 def addresses=(addrs)
73   @io ||= IO.registry(@type).new(@origin, addrs, @options) # rubocop:disable Naming/MemoizedInstanceVariableName
74 end
call ()
[show source]
    # File lib/httpx/connection.rb
180 def call
181   case @state
182   when :closed
183     return
184   when :closing
185     dwrite
186     transition(:closed)
187     emit(:close)
188   when :open
189     consume
190   end
191   nil
192 end
close ()
[show source]
    # File lib/httpx/connection.rb
160 def close
161   @parser.close if @parser
162   transition(:closing)
163 end
coalescable? (connection)

coalescable connections need to be mergeable! but internally, mergeable? is called before coalescable?

[show source]
    # File lib/httpx/connection.rb
 94 def coalescable?(connection)
 95   if @io.protocol == "h2" && @origin.scheme == "https"
 96     @io.verify_hostname(connection.origin.host)
 97   else
 98     @origin == connection.origin
 99   end
100 end
connecting? ()
[show source]
    # File lib/httpx/connection.rb
138 def connecting?
139   @state == :idle
140 end
inflight? ()
[show source]
    # File lib/httpx/connection.rb
142 def inflight?
143   @parser && !@parser.empty? && !@write_buffer.empty?
144 end
interests ()
[show source]
    # File lib/httpx/connection.rb
146 def interests
147   return :w if @state == :idle
148 
149   :rw
150 end
match? (uri, options)
[show source]
   # File lib/httpx/connection.rb
80 def match?(uri, options)
81   return false if @state == :closing || @state == :closed
82 
83   (@origins.include?(uri.origin) || match_altsvcs?(uri)) && @options == options
84 end
match_altsvcs? (uri)

checks if this is connection is an alternative service of uri

[show source]
    # File lib/httpx/connection.rb
131 def match_altsvcs?(uri)
132   AltSvc.cached_altsvc(@origin).any? do |altsvc|
133     origin = altsvc["origin"]
134     origin.altsvc_match?(uri.origin)
135   end
136 end
merge (connection)
[show source]
    # File lib/httpx/connection.rb
102 def merge(connection)
103   @origins += connection.instance_variable_get(:@origins)
104   pending = connection.instance_variable_get(:@pending)
105   pending.each do |req, args|
106     send(req, args)
107   end
108 end
mergeable? (connection)
[show source]
   # File lib/httpx/connection.rb
86 def mergeable?(connection)
87   return false if @state == :closing || @state == :closed || !@io
88 
89   !(@io.addresses & connection.addresses).empty? && @options == connection.options
90 end
purge_pending ()
[show source]
    # File lib/httpx/connection.rb
121 def purge_pending
122   [@parser.pending, @pending].each do |pending|
123     pending.reject! do |request, *args|
124       yield(request, args)
125     end
126   end
127 end
reset ()
[show source]
    # File lib/httpx/connection.rb
165 def reset
166   transition(:closing)
167   transition(:closed)
168   emit(:close)
169 end
send (request)
[show source]
    # File lib/httpx/connection.rb
171 def send(request)
172   if @parser && !@write_buffer.full?
173     request.headers["alt-used"] = @origin.authority if match_altsvcs?(request.uri)
174     parser.send(request)
175   else
176     @pending << request
177   end
178 end
timeout ()
[show source]
    # File lib/httpx/connection.rb
194 def timeout
195   return @timeout if defined?(@timeout)
196 
197   return @options.timeout.connect_timeout if @state == :idle
198 
199   @options.timeout.operation_timeout
200 end
to_io ()
[show source]
    # File lib/httpx/connection.rb
152 def to_io
153   case @state
154   when :idle
155     transition(:open)
156   end
157   @io.to_io
158 end
unmerge (connection)
[show source]
    # File lib/httpx/connection.rb
110 def unmerge(connection)
111   @origins -= connection.instance_variable_get(:@origins)
112   purge_pending do |request|
113     request.uri.origin == connection.origin && begin
114       request.transition(:idle)
115       connection.send(request)
116       true
117     end
118   end
119 end