Class: HTTP::Session
- Inherits:
-
Object
- Object
- HTTP::Session
- Extended by:
- Forwardable
- Includes:
- Chainable
- Defined in:
- lib/http/session.rb,
sig/http.rbs
Overview
Thread-safe options builder for configuring HTTP requests.
Session objects are returned by all chainable configuration methods (e.g., Chainable#headers, Chainable#timeout, Chainable#cookies). They hold an immutable Options object and create a new Client for each request, making them safe to share across threads.
When configured for persistent connections (via Chainable#persistent), the session maintains a pool of Client instances keyed by origin, enabling connection reuse within the same origin and transparent cross-origin redirect handling.
Constant Summary
Constants included from Chainable
Instance Method Summary collapse
-
#apply_cookies(jar, request) ⇒ void
private
Apply cookies from the jar to the request's Cookie header.
-
#branch(options) ⇒ HTTP::Session
private
Create a new session with the given options.
-
#client_for_origin(origin) ⇒ HTTP::Client
private
Return a pooled persistent Client for the given origin.
-
#close ⇒ void
Close all persistent connections held by this session.
-
#initialize(default_options = nil, clients: nil) ⇒ HTTP::Session
constructor
Initialize a new Session.
-
#load_cookies(jar, request) ⇒ void
private
Load cookies from the request's Cookie header into the jar.
-
#options_for_origin(origin) ⇒ HTTP::Options
private
Build Options for a persistent client targeting the given origin.
-
#perform_redirects(jar, client, req, res, opts) ⇒ HTTP::Response
private
Follow redirects with cookie management.
-
#perform_request(client, verb, uri, merged) ⇒ HTTP::Response
private
Execute a request with cookie management.
-
#persistent? ⇒ Boolean
Indicate whether the session has persistent connection options.
-
#redirect_client(client, request) ⇒ HTTP::Client
private
Return the appropriate client for a redirect hop.
-
#request(verb, uri, headers: nil, params: nil, form: nil, json: nil, body: nil, response: nil, encoding: nil, follow: nil, ssl: nil, ssl_context: nil, proxy: nil, nodelay: nil, features: nil, retriable: nil, socket_class: nil, ssl_socket_class: nil, timeout_class: nil, timeout_options: nil, keep_alive_timeout: nil, base_uri: nil, persistent: nil) {|response| ... } ⇒ HTTP::Response, Object
Make an HTTP request.
-
#store_cookies(jar, response) ⇒ void
private
Store cookies from the response's Set-Cookie headers into the jar.
Methods included from Chainable
#accept, #auth, #base_uri, #basic_auth, #build_proxy_hash, #cookies, #default_options, #default_options=, #digest_auth, #encoding, #follow, #headers, #make_client, #nodelay, #persistent, #resolve_global_only, #resolve_timeout_hash, #retriable, #timeout, #use, #via
Methods included from Chainable::Verbs
#connect, #delete, #get, #head, #options, #patch, #post, #put, #trace
Methods included from Base64
Constructor Details
#initialize(default_options = nil, clients: nil) ⇒ HTTP::Session
Initialize a new Session
63 64 65 66 |
# File 'lib/http/session.rb', line 63 def initialize( = nil, clients: nil, **) @default_options = HTTP::Options.new(, **) @clients = clients || {} end |
Instance Method Details
#apply_cookies(jar, request) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Apply cookies from the jar to the request's Cookie header
272 273 274 275 276 277 278 |
# File 'lib/http/session.rb', line 272 def (jar, request) if jar.empty? request.headers.delete(Headers::COOKIE) else request.headers.set(Headers::COOKIE, jar.map { |c| "#{c.name}=#{c.value}" }.join("; ")) end end |
#branch(options) ⇒ HTTP::Session
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Create a new session with the given options
When the current session is persistent, the child session shares the same connection pool so that chaining methods like Chainable#headers or Chainable#auth do not break connection reuse.
143 144 145 146 147 148 149 |
# File 'lib/http/session.rb', line 143 def branch() if persistent? self.class.new(, clients: @clients) else self.class.new() end end |
#client_for_origin(origin) ⇒ HTTP::Client
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return a pooled persistent Client for the given origin
Creates a new Client if one does not already exist for this origin. For the session's primary persistent origin, the default options are used directly. For other origins (e.g. redirect targets), the persistent origin is overridden and base_uri is cleared.
220 221 222 |
# File 'lib/http/session.rb', line 220 def client_for_origin(origin) @clients[origin] ||= make_client((origin)) end |
#close ⇒ void
This method returns an undefined value.
Close all persistent connections held by this session
When the session is persistent, this closes every pooled Client and clears the pool. Safe to call on non-persistent sessions (no-op).
80 81 82 83 |
# File 'lib/http/session.rb', line 80 def close @clients.each_value(&:close) @clients.clear end |
#load_cookies(jar, request) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Load cookies from the request's Cookie header into the jar
241 242 243 244 245 246 247 248 |
# File 'lib/http/session.rb', line 241 def (jar, request) header = request.headers[Headers::COOKIE] = HTTP::Cookie.(header.to_s) .each do |name, value| jar.add(HTTP::Cookie.new(name, value, path: request.uri.path, domain: request.host)) end end |
#options_for_origin(origin) ⇒ HTTP::Options
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Build Options for a persistent client targeting the given origin
229 230 231 232 233 |
# File 'lib/http/session.rb', line 229 def (origin) return if origin == .persistent .merge(persistent: origin, base_uri: nil) end |
#perform_redirects(jar, client, req, res, opts) ⇒ HTTP::Response
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Follow redirects with cookie management
For persistent sessions, each redirect hop may target a different origin. The session looks up (or creates) a pooled Client for the redirect target's origin, allowing cross-origin redirects without raising HTTP::StateError.
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/http/session.rb', line 187 def perform_redirects(jar, client, req, res, opts) builder = Request::Builder.new(opts) follow = opts.follow || {} #: Hash[untyped, untyped] Redirector.new(**follow).perform(req, res) do |redirect_req| wrapped = builder.wrap(redirect_req) (jar, wrapped) (jar, redirect_req) response = redirect_client(client, wrapped).perform(wrapped, opts) (jar, response) response end end |
#perform_request(client, verb, uri, merged) ⇒ HTTP::Response
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Execute a request with cookie management
159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/http/session.rb', line 159 def perform_request(client, verb, uri, merged) = CookieJar.new builder = Request::Builder.new(merged) req = builder.build(verb, uri) client ||= client_for_origin(req.uri.origin) (, req) res = client.perform(req, merged) (, res) return res unless merged.follow perform_redirects(, client, req, res, merged) end |
#persistent? ⇒ Boolean
Indicate whether the session has persistent connection options
51 |
# File 'lib/http/session.rb', line 51 def_delegator :default_options, :persistent? |
#redirect_client(client, request) ⇒ HTTP::Client
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Return the appropriate client for a redirect hop
206 207 208 |
# File 'lib/http/session.rb', line 206 def redirect_client(client, request) persistent? ? client_for_origin(request.uri.origin) : client end |
#request(verb, uri, headers: nil, params: nil, form: nil, json: nil, body: nil, response: nil, encoding: nil, follow: nil, ssl: nil, ssl_context: nil, proxy: nil, nodelay: nil, features: nil, retriable: nil, socket_class: nil, ssl_socket_class: nil, timeout_class: nil, timeout_options: nil, keep_alive_timeout: nil, base_uri: nil, persistent: nil) {|response| ... } ⇒ HTTP::Response, Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/http/session.rb', line 106 def request(verb, uri, headers: nil, params: nil, form: nil, json: nil, body: nil, response: nil, encoding: nil, follow: nil, ssl: nil, ssl_context: nil, proxy: nil, nodelay: nil, features: nil, retriable: nil, socket_class: nil, ssl_socket_class: nil, timeout_class: nil, timeout_options: nil, keep_alive_timeout: nil, base_uri: nil, persistent: nil, &block) merged = .merge( { headers: headers, params: params, form: form, json: json, body: body, response: response, encoding: encoding, follow: follow, ssl: ssl, ssl_context: ssl_context, proxy: proxy, nodelay: nodelay, features: features, retriable: retriable, socket_class: socket_class, ssl_socket_class: ssl_socket_class, timeout_class: timeout_class, timeout_options: , keep_alive_timeout: keep_alive_timeout, base_uri: base_uri, persistent: persistent }.compact ) client = persistent? ? nil : make_client() res = perform_request(client, verb, uri, merged) return res unless block yield res ensure if block persistent? ? close : client&.close end end |
#store_cookies(jar, response) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Store cookies from the response's Set-Cookie headers into the jar
256 257 258 259 260 261 262 263 264 |
# File 'lib/http/session.rb', line 256 def (jar, response) response..each do || if .value == "" jar.delete() else jar.add() end end end |