Manages sessions for a HTTPClient instance.
Name of this client. Used for 'User-Agent' header in HTTP request.
Chunk size for chunked request
Maximum retry count. 0 for infinite.
Device for dumping log for debugging
Owner of this client. Used for 'From' header in HTTP request.
Requested protocol version
Local address to bind local side of the socket to
Boolean value for Socket#sync
# File lib/httpclient/session.rb, line 121 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
# File lib/httpclient/session.rb, line 186 def invalidate(site) @sess_pool_mutex.synchronize do if pool = @sess_pool[site] pool.each do |sess| sess.invalidate end end end end
assert: sess.last_used must not be nil
# File lib/httpclient/session.rb, line 182 def keep(sess) add_cached_session(sess) end
# File lib/httpclient/session.rb, line 152 def proxy=(proxy) if proxy.nil? @proxy = nil else @proxy = Site.new(proxy) end end
# File lib/httpclient/session.rb, line 160 def query(req, via_proxy) req.http_body.chunk_size = @chunk_size sess = open(req.header.request_uri, via_proxy) begin sess.query(req) rescue sess.close raise end sess end
# File lib/httpclient/session.rb, line 172 def reset(uri) site = Site.new(uri) close(site) end
# File lib/httpclient/session.rb, line 177 def reset_all close_all end
# File lib/httpclient/session.rb, line 279 def add_cached_session(sess) @sess_pool_mutex.synchronize do (@sess_pool[sess.dest] ||= []).unshift(sess) end end
This method might not work as you expected…
# File lib/httpclient/session.rb, line 235 def close(dest) if cached = get_cached_session(Site.new(dest)) cached.close true else false end end
# File lib/httpclient/session.rb, line 223 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
# File lib/httpclient/session.rb, line 244 def get_cached_session(site) @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
# File lib/httpclient/session.rb, line 198 def open(uri, via_proxy = false) site = Site.new(uri) sess = nil if cached = get_cached_session(site) sess = cached else 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 end sess end
# File lib/httpclient/session.rb, line 262 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
# File lib/httpclient/session.rb, line 275 def valid_session?(sess, now) !sess.invalidated? and (now <= sess.last_used + @keep_alive_timeout) end