class HTTPX::Session

  1. lib/httpx/session.rb
Superclass: Object

Class implementing the APIs being used publicly.

HTTPX.get(..) #=> delegating to an internal HTTPX::Session object.
HTTPX.plugin(..).get(..) #=> creating an intermediate HTTPX::Session with plugin, then sending the GET request

Included modules

  1. Loggable
  2. Chainable

Public Instance Aliases

select_resolver -> select_connection

Attributes

Public Class methods

inherited(klass)
[show source]
    # File lib/httpx/session.rb
443 def inherited(klass)
444   super
445   klass.instance_variable_set(:@default_options, @default_options)
446   klass.instance_variable_set(:@plugins, @plugins.dup)
447   klass.instance_variable_set(:@callbacks, @callbacks.dup)
448 end
new(options = EMPTY_HASH, &blk)

initializes the session with a set of options, which will be shared by all requests sent from it.

When pass a block, it’ll yield itself to it, then closes after the block is evaluated.

[show source]
   # File lib/httpx/session.rb
16 def initialize(options = EMPTY_HASH, &blk)
17   @options = self.class.default_options.merge(options)
18   @responses = {}
19   @persistent = @options.persistent
20   @pool = @options.pool_class.new(@options.pool_options)
21   @wrapped = false
22   @closing = false
23   wrap(&blk) if blk
24 end
plugin(pl, options = nil, &block)

returns a new HTTPX::Session instance, with the plugin pointed by pl loaded.

session_with_retries = session.plugin(:retries)
session_with_custom = session.plugin(CustomPlugin)
[show source]
    # File lib/httpx/session.rb
455 def plugin(pl, options = nil, &block)
456   # raise Error, "Cannot add a plugin to a frozen config" if frozen?
457   pl = Plugins.load_plugin(pl) if pl.is_a?(Symbol)
458   if !@plugins.include?(pl)
459     @plugins << pl
460     pl.load_dependencies(self, &block) if pl.respond_to?(:load_dependencies)
461 
462     @default_options = @default_options.dup
463 
464     include(pl::InstanceMethods) if defined?(pl::InstanceMethods)
465     extend(pl::ClassMethods) if defined?(pl::ClassMethods)
466 
467     opts = @default_options
468     opts.extend_with_plugin_classes(pl)
469     if defined?(pl::OptionsMethods)
470 
471       (pl::OptionsMethods.instance_methods - Object.instance_methods).each do |meth|
472         opts.options_class.method_added(meth)
473       end
474       @default_options = opts.options_class.new(opts)
475     end
476 
477     @default_options = pl.extra_options(@default_options) if pl.respond_to?(:extra_options)
478     @default_options = @default_options.merge(options) if options
479 
480     pl.configure(self, &block) if pl.respond_to?(:configure)
481 
482     @default_options.freeze
483   elsif options
484     # this can happen when two plugins are loaded, an one of them calls the other under the hood,
485     # albeit changing some default.
486     @default_options = pl.extra_options(@default_options) if pl.respond_to?(:extra_options)
487     @default_options = @default_options.merge(options) if options
488 
489     @default_options.freeze
490   end
491   self
492 end

Public Instance methods

build_request(verb, uri, params = EMPTY_HASH, options = @options)

returns a HTTP::Request instance built from the HTTP verb, the request uri, and the optional set of request-specific options. This request must be sent through the same session it was built from.

req = session.build_request("GET", "https://server.com")
resp = session.request(req)
[show source]
    # File lib/httpx/session.rb
118 def build_request(verb, uri, params = EMPTY_HASH, options = @options)
119   rklass = options.request_class
120   request = rklass.new(verb, uri, options, params)
121   request.persistent = @persistent
122   set_request_callbacks(request)
123   request
124 end
close(selector = Selector.new)

closes all the active connections from the session.

when called directly without specifying selector, all available connections will be picked up from the connection pool and closed. Connections in use by other sessions, or same session in a different thread, will not be reaped.

[show source]
   # File lib/httpx/session.rb
64 def close(selector = Selector.new)
65   # throw resolvers away from the pool
66   @pool.reset_resolvers
67 
68   # preparing to throw away connections
69   while (connection = @pool.pop_connection)
70     next if connection.state == :closed
71 
72     select_connection(connection, selector)
73   end
74   begin
75     @closing = true
76     selector.terminate
77   ensure
78     @closing = false
79   end
80 end
deselect_connection(connection, selector, cloned = false)
[show source]
    # File lib/httpx/session.rb
138 def deselect_connection(connection, selector, cloned = false)
139   selector.deregister(connection)
140 
141   # when connections coalesce
142   return if connection.state == :idle
143 
144   return if cloned
145 
146   return if @closing && connection.state == :closed
147 
148   @pool.checkin_connection(connection)
149 end
deselect_resolver(resolver, selector)
[show source]
    # File lib/httpx/session.rb
151 def deselect_resolver(resolver, selector)
152   selector.deregister(resolver)
153 
154   return if @closing && resolver.closed?
155 
156   @pool.checkin_resolver(resolver)
157 end
find_connection(request_uri, selector, options)

returns the HTTPX::Connection through which the request should be sent through.

[show source]
    # File lib/httpx/session.rb
175 def find_connection(request_uri, selector, options)
176   if (connection = selector.find_connection(request_uri, options))
177     return connection
178   end
179 
180   connection = @pool.checkout_connection(request_uri, options)
181 
182   case connection.state
183   when :idle
184     do_init_connection(connection, selector)
185   when :open
186     if options.io
187       select_connection(connection, selector)
188     else
189       pin_connection(connection, selector)
190     end
191   when :closed
192     connection.idling
193     select_connection(connection, selector)
194   when :closing
195     connection.once(:close) do
196       connection.idling
197       select_connection(connection, selector)
198     end
199   else
200     pin_connection(connection, selector)
201   end
202 
203   connection
204 end
pin_connection(connection, selector)
[show source]
    # File lib/httpx/session.rb
131 def pin_connection(connection, selector)
132   connection.current_session = self
133   connection.current_selector = selector
134 end
request(*args, **params)

performs one, or multple requests; it accepts:

  1. one or multiple HTTPX::Request objects;

  2. an HTTP verb, then a sequence of URIs or URI/options tuples;

  3. one or multiple HTTP verb / uri / (optional) options tuples;

when present, the set of options kwargs is applied to all of the sent requests.

respectively returns a single HTTPX::Response response, or all of them in an Array, in the same order.

resp1 = session.request(req1)
resp1, resp2 = session.request(req1, req2)
resp1 = session.request("GET", "https://server.org/a")
resp1, resp2 = session.request("GET", ["https://server.org/a", "https://server.org/b"])
resp1, resp2 = session.request(["GET", "https://server.org/a"], ["GET", "https://server.org/b"])
resp1 = session.request("POST", "https://server.org/a", form: { "foo" => "bar" })
resp1, resp2 = session.request(["POST", "https://server.org/a", form: { "foo" => "bar" }], ["GET", "https://server.org/b"])
resp1, resp2 = session.request("GET", ["https://server.org/a", "https://server.org/b"], headers: { "x-api-token" => "TOKEN" })
[show source]
    # File lib/httpx/session.rb
102 def request(*args, **params)
103   raise ArgumentError, "must perform at least one request" if args.empty?
104 
105   requests = args.first.is_a?(Request) ? args : build_requests(*args, params)
106   responses = send_requests(*requests)
107   return responses.first if responses.size == 1
108 
109   responses
110 end
select_connection(connection, selector)
[show source]
    # File lib/httpx/session.rb
126 def select_connection(connection, selector)
127   pin_connection(connection, selector)
128   selector.register(connection)
129 end
try_clone_connection(connection, selector, family)
[show source]
    # File lib/httpx/session.rb
159 def try_clone_connection(connection, selector, family)
160   connection.family ||= family
161 
162   return connection if connection.family == family
163 
164   new_connection = connection.class.new(connection.origin, connection.options)
165 
166   new_connection.family = family
167 
168   connection.sibling = new_connection
169 
170   do_init_connection(new_connection, selector)
171   new_connection
172 end
wrap()

Yields itself the block, then closes it after the block is evaluated.

session.wrap do |http|
  http.get("https://wikipedia.com")
end # wikipedia connection closes here
[show source]
   # File lib/httpx/session.rb
31 def wrap
32   prev_wrapped = @wrapped
33   @wrapped = true
34   was_initialized = false
35   current_selector = get_current_selector do
36     selector = Selector.new
37 
38     set_current_selector(selector)
39 
40     was_initialized = true
41 
42     selector
43   end
44   begin
45     yield self
46   ensure
47     unless prev_wrapped
48       if @persistent
49         deactivate(current_selector)
50       else
51         close(current_selector)
52       end
53     end
54     @wrapped = prev_wrapped
55     set_current_selector(nil) if was_initialized
56   end
57 end