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
Methods
Public Class
Public Instance
Public Instance Aliases
select_resolver | -> | select_connection |
Public Class methods
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.
# 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
Public Instance methods
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)
# File lib/httpx/session.rb 120 def build_request(verb, uri, params = EMPTY_HASH, options = @options) 121 rklass = options.request_class 122 request = rklass.new(verb, uri, options, params) 123 request.persistent = @persistent 124 set_request_callbacks(request) 125 request 126 end
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.
# 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 connection.current_session = self 73 connection.current_selector = selector 74 select_connection(connection, selector) 75 end 76 begin 77 @closing = true 78 selector.terminate 79 ensure 80 @closing = false 81 end 82 end
# File lib/httpx/session.rb 134 def deselect_connection(connection, selector, cloned = false) 135 selector.deregister(connection) 136 137 # when connections coalesce 138 return if connection.state == :idle 139 140 return if cloned 141 142 return if @closing && connection.state == :closed 143 144 @pool.checkin_connection(connection) 145 end
# File lib/httpx/session.rb 147 def deselect_resolver(resolver, selector) 148 selector.deregister(resolver) 149 150 return if @closing && resolver.closed? 151 152 @pool.checkin_resolver(resolver) 153 end
returns the HTTPX::Connection
through which the request
should be sent through.
# File lib/httpx/session.rb 199 def find_connection(request_uri, selector, options) 200 if (connection = selector.find_connection(request_uri, options)) 201 return connection 202 end 203 204 connection = @pool.checkout_connection(request_uri, options) 205 206 connection.current_session = self 207 connection.current_selector = selector 208 209 case connection.state 210 when :idle 211 do_init_connection(connection, selector) 212 when :open 213 select_connection(connection, selector) if options.io 214 when :closed 215 connection.idling 216 select_connection(connection, selector) 217 when :closing 218 connection.once(:close) do 219 connection.idling 220 select_connection(connection, selector) 221 end 222 end 223 224 connection 225 end
performs one, or multple requests; it accepts:
-
one or multiple
HTTPX::Request
objects; -
an HTTP verb, then a sequence of URIs or URI/options tuples;
-
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" })
# File lib/httpx/session.rb 104 def request(*args, **params) 105 raise ArgumentError, "must perform at least one request" if args.empty? 106 107 requests = args.first.is_a?(Request) ? args : build_requests(*args, params) 108 responses = send_requests(*requests) 109 return responses.first if responses.size == 1 110 111 responses 112 end
# File lib/httpx/session.rb 128 def select_connection(connection, selector) 129 selector.register(connection) 130 end
# File lib/httpx/session.rb 155 def try_clone_connection(connection, selector, family) 156 connection.family ||= family 157 158 return connection if connection.family == family 159 160 new_connection = connection.class.new(connection.origin, connection.options) 161 162 new_connection.family = family 163 new_connection.current_session = self 164 new_connection.current_selector = selector 165 166 connection.once(:tcp_open) { new_connection.force_reset(true) } 167 connection.once(:connect_error) do |err| 168 if new_connection.connecting? 169 new_connection.merge(connection) 170 connection.emit(:cloned, new_connection) 171 connection.force_reset(true) 172 else 173 connection.__send__(:handle_error, err) 174 end 175 end 176 177 new_connection.once(:tcp_open) do |new_conn| 178 if new_conn != connection 179 new_conn.merge(connection) 180 connection.force_reset(true) 181 end 182 end 183 new_connection.once(:connect_error) do |err| 184 if connection.connecting? 185 # main connection has the requests 186 connection.merge(new_connection) 187 new_connection.emit(:cloned, connection) 188 new_connection.force_reset(true) 189 else 190 new_connection.__send__(:handle_error, err) 191 end 192 end 193 194 do_init_connection(new_connection, selector) 195 new_connection 196 end
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
# 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