class HTTPClient::SessionManager
Manages sessions for a HTTPClient instance.
Attributes
agent_name[RW]
Name of this client. Used for 'User-Agent' header in HTTP request.
chunk_size[RW]
Chunk size for chunked request
connect_retry[RW]
Maximum retry count. 0 for infinite.
connect_timeout[RW]
debug_dev[RW]
Device for dumping log for debugging
from[RW]
Owner of this client. Used for 'From' header in HTTP request.
keep_alive_timeout[RW]
protocol_retry_count[RW]
protocol_version[RW]
Requested protocol version
read_block_size[RW]
receive_timeout[RW]
send_timeout[RW]
socket_local[RW]
Local address to bind local side of the socket to
socket_sync[RW]
Boolean value for Socket#sync
ssl_config[RW]
test_loopback_http_response[R]
transparent_gzip_decompression[RW]
Public Class Methods
new(client)
click to toggle source
# File lib/httpclient/session.rb, line 127 def initialize(client) @client = client @proxy = client.proxy @agent_name = nil @from = nil @protocol_version = nil @debug_dev = client.debug_dev @socket_sync = true @chunk_size = ::HTTP::Message::Body::DEFAULT_CHUNK_SIZE @connect_timeout = 60 @connect_retry = 1 @send_timeout = 120 @receive_timeout = 60 # For each read_block_size bytes @keep_alive_timeout = 15 # '15' is from Apache 2 default @read_block_size = 1024 * 16 # follows net/http change in 1.8.7 @protocol_retry_count = 5 @ssl_config = nil @test_loopback_http_response = [] @transparent_gzip_decompression = false @socket_local = Site.new @sess_pool = {} @sess_pool_mutex = Mutex.new @sess_pool_last_checked = Time.now end
Public Instance Methods
keep(sess)
click to toggle source
assert: sess.last_used must not be nil
# File lib/httpclient/session.rb, line 188 def keep(sess) add_cached_session(sess) end
proxy=(proxy)
click to toggle source
# File lib/httpclient/session.rb, line 158 def proxy=(proxy) if proxy.nil? @proxy = nil else @proxy = Site.new(proxy) end end
query(req, via_proxy)
click to toggle source
# File lib/httpclient/session.rb, line 166 def query(req, via_proxy) req.http_body.chunk_size = @chunk_size if req.http_body sess = get_session(req, via_proxy) begin sess.query(req) rescue sess.close raise end sess end
reset(uri)
click to toggle source
# File lib/httpclient/session.rb, line 178 def reset(uri) site = Site.new(uri) close(site) end
reset_all()
click to toggle source
# File lib/httpclient/session.rb, line 183 def reset_all close_all end
Private Instance Methods
add_cached_session(sess)
click to toggle source
# File lib/httpclient/session.rb, line 289 def add_cached_session(sess) @sess_pool_mutex.synchronize do (@sess_pool[sess.dest] ||= []).unshift(sess) end end
close(dest)
click to toggle source
This method might not work as you expected…
# File lib/httpclient/session.rb, line 242 def close(dest) if cached = get_cached_session(Site.new(dest)) cached.close true else false end end
close_all()
click to toggle source
# File lib/httpclient/session.rb, line 230 def close_all @sess_pool_mutex.synchronize do @sess_pool.each do |site, pool| pool.each do |sess| sess.close end end end @sess_pool.clear end
get_cached_session(site)
click to toggle source
# File lib/httpclient/session.rb, line 251 def get_cached_session(site) if Thread.current[:HTTPClient_AcquireNewConnection] return nil end @sess_pool_mutex.synchronize do now = Time.now if now > @sess_pool_last_checked + @keep_alive_timeout scrub_cached_session(now) @sess_pool_last_checked = now end if pool = @sess_pool[site] pool.each_with_index do |sess, idx| if valid_session?(sess, now) return pool.slice!(idx) end end end end nil end
get_session(req, via_proxy = false)
click to toggle source
TODO: create PR for webmock's httpclient adapter to use #get_session instead of open so that we can remove duplicated Site creation for each session.
# File lib/httpclient/session.rb, line 197 def get_session(req, via_proxy = false) uri = req.header.request_uri if uri.scheme.nil? raise ArgumentError.new("Request URI must have schema. Possibly add 'http://' to the request URI?") end site = Site.new(uri) if cached = get_cached_session(site) cached else open(uri, via_proxy) end end
open(uri, via_proxy = false)
click to toggle source
# File lib/httpclient/session.rb, line 210 def open(uri, via_proxy = false) site = Site.new(uri) sess = Session.new(@client, site, @agent_name, @from) sess.proxy = via_proxy ? @proxy : nil sess.socket_sync = @socket_sync sess.requested_version = @protocol_version if @protocol_version sess.connect_timeout = @connect_timeout sess.connect_retry = @connect_retry sess.send_timeout = @send_timeout sess.receive_timeout = @receive_timeout sess.read_block_size = @read_block_size sess.protocol_retry_count = @protocol_retry_count sess.ssl_config = @ssl_config sess.debug_dev = @debug_dev sess.socket_local = @socket_local sess.test_loopback_http_response = @test_loopback_http_response sess.transparent_gzip_decompression = @transparent_gzip_decompression sess end
scrub_cached_session(now)
click to toggle source
# File lib/httpclient/session.rb, line 272 def scrub_cached_session(now) @sess_pool.each do |site, pool| pool.replace(pool.select { |sess| if valid_session?(sess, now) true else sess.close # close & remove from the pool false end }) end end
valid_session?(sess, now)
click to toggle source
# File lib/httpclient/session.rb, line 285 def valid_session?(sess, now) (now <= sess.last_used + @keep_alive_timeout) end