Class: HTTPX::Session

Inherits:
Object
  • Object
show all
Includes:
Callbacks, Chainable, Loggable
Defined in:
lib/httpx/session.rb,
lib/httpx/session2.rb

Overview

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

Constant Summary collapse

EMPTY_HASH =
{}.freeze

Constants included from Loggable

Loggable::COLORS

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Callbacks

#callbacks_for?, #emit, #on, #once, #only

Methods included from Chainable

#accept, #plugin, #with

Methods included from Loggable

#log, #log_exception

Constructor Details

#initialize(options = EMPTY_HASH, &blk) ⇒ Session

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.



19
20
21
22
23
24
# File 'lib/httpx/session.rb', line 19

def initialize(options = EMPTY_HASH, &blk)
  @options = self.class.default_options.merge(options)
  @responses = {}
  @persistent = @options.persistent
  wrap(&blk) if blk
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class HTTPX::Chainable

Class Attribute Details

.default_optionsObject (readonly)

Returns the value of attribute default_options.



339
340
341
# File 'lib/httpx/session.rb', line 339

def default_options
  @default_options
end

Class Method Details

.inherited(klass) ⇒ Object



341
342
343
344
345
346
# File 'lib/httpx/session.rb', line 341

def inherited(klass)
  super
  klass.instance_variable_set(:@default_options, @default_options)
  klass.instance_variable_set(:@plugins, @plugins.dup)
  klass.instance_variable_set(:@callbacks, @callbacks.dup)
end

.plugin(pl, options = nil, &block) ⇒ Object

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)


353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/httpx/session.rb', line 353

def plugin(pl, options = nil, &block)
  # raise Error, "Cannot add a plugin to a frozen config" if frozen?
  pl = Plugins.load_plugin(pl) if pl.is_a?(Symbol)
  if !@plugins.include?(pl)
    @plugins << pl
    pl.load_dependencies(self, &block) if pl.respond_to?(:load_dependencies)

    @default_options = @default_options.dup

    include(pl::InstanceMethods) if defined?(pl::InstanceMethods)
    extend(pl::ClassMethods) if defined?(pl::ClassMethods)

    opts = @default_options
    opts.request_class.__send__(:include, pl::RequestMethods) if defined?(pl::RequestMethods)
    opts.request_class.extend(pl::RequestClassMethods) if defined?(pl::RequestClassMethods)
    opts.response_class.__send__(:include, pl::ResponseMethods) if defined?(pl::ResponseMethods)
    opts.response_class.extend(pl::ResponseClassMethods) if defined?(pl::ResponseClassMethods)
    opts.headers_class.__send__(:include, pl::HeadersMethods) if defined?(pl::HeadersMethods)
    opts.headers_class.extend(pl::HeadersClassMethods) if defined?(pl::HeadersClassMethods)
    opts.request_body_class.__send__(:include, pl::RequestBodyMethods) if defined?(pl::RequestBodyMethods)
    opts.request_body_class.extend(pl::RequestBodyClassMethods) if defined?(pl::RequestBodyClassMethods)
    opts.response_body_class.__send__(:include, pl::ResponseBodyMethods) if defined?(pl::ResponseBodyMethods)
    opts.response_body_class.extend(pl::ResponseBodyClassMethods) if defined?(pl::ResponseBodyClassMethods)
    opts.connection_class.__send__(:include, pl::ConnectionMethods) if defined?(pl::ConnectionMethods)
    if defined?(pl::OptionsMethods)
      opts.options_class.__send__(:include, pl::OptionsMethods)

      (pl::OptionsMethods.instance_methods - Object.instance_methods).each do |meth|
        opts.options_class.method_added(meth)
      end
      @default_options = opts.options_class.new(opts)
    end

    @default_options = pl.extra_options(@default_options) if pl.respond_to?(:extra_options)
    @default_options = @default_options.merge(options) if options

    pl.configure(self, &block) if pl.respond_to?(:configure)

    @default_options.freeze
  elsif options
    # this can happen when two plugins are loaded, an one of them calls the other under the hood,
    # albeit changing some default.
    @default_options = pl.extra_options(@default_options) if pl.respond_to?(:extra_options)
    @default_options = @default_options.merge(options) if options

    @default_options.freeze
  end
  self
end

Instance Method Details

#build_request(verb, uri, options = EMPTY_HASH) ⇒ Object

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)


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/httpx/session.rb', line 83

def build_request(verb, uri, options = EMPTY_HASH)
  rklass = @options.request_class
  options = @options.merge(options) unless options.is_a?(Options)
  request = rklass.new(verb, uri, options)
  request.persistent = @persistent
  request.on(:response, &method(:on_response).curry(2)[request])
  request.on(:promise, &method(:on_promise))

  request.on(:headers) do
    emit(:request_started, request)
  end
  request.on(:body_chunk) do |chunk|
    emit(:request_body_chunk, request, chunk)
  end
  request.on(:done) do
    emit(:request_completed, request)
  end

  request.on(:response_started) do |res|
    if res.is_a?(Response)
      emit(:response_started, request, res)
      res.on(:chunk_received) do |chunk|
        emit(:response_body_chunk, request, res, chunk)
      end
    else
      emit(:request_error, request, res.error)
    end
  end
  request.on(:response) do |res|
    emit(:response_completed, request, res)
  end

  request
end

#close(*args) ⇒ Object

closes all the active connections from the session



43
44
45
# File 'lib/httpx/session.rb', line 43

def close(*args)
  pool.close(*args)
end

#request(*args, **options) ⇒ Object

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&quot;) resp1, resp2 = session.request("GET", ["https://server.org/a&quot;, "https://server.org/b&quot;]) resp1, resp2 = session.request(["GET", "https://server.org/a&quot;], ["GET", "https://server.org/b&quot;]) resp1 = session.request("POST", "https://server.org/a&quot;, form: { "foo" => "bar" }) resp1, resp2 = session.request(["POST", "https://server.org/a&quot;, form: { "foo" => "bar" }], ["GET", "https://server.org/b&quot;]) resp1, resp2 = session.request("GET", ["https://server.org/a&quot;, "https://server.org/b&quot;], headers: { "x-api-token" => "TOKEN" })

Raises:

  • (ArgumentError)


67
68
69
70
71
72
73
74
75
# File 'lib/httpx/session.rb', line 67

def request(*args, **options)
  raise ArgumentError, "must perform at least one request" if args.empty?

  requests = args.first.is_a?(Request) ? args : build_requests(*args, options)
  responses = send_requests(*requests)
  return responses.first if responses.size == 1

  responses
end

#wrapObject

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


31
32
33
34
35
36
37
38
39
40
# File 'lib/httpx/session.rb', line 31

def wrap
  begin
    prev_persistent = @persistent
    @persistent = true
    yield self
  ensure
    @persistent = prev_persistent
    close unless @persistent
  end
end