Skip to content

limiting bindings of default_proc #64

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lib/net/http/persistent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,16 @@ def self.detect_idle_timeout uri, max = 10
return sleep_time unless $!
end

##
# Returns a new nested hash
#
# Using a class method to limit the bindings referenced by the
# hash's default_proc

def self.new_nested_hash
Hash.new { |h,k| h[k] = {} }
end

##
# This client's OpenSSL::X509::Certificate

Expand Down Expand Up @@ -586,8 +596,8 @@ def cleanup(generation, thread = Thread.current,
# Creates a new connection for +uri+

def connection_for uri
Thread.current[@generation_key] ||= Hash.new { |h,k| h[k] = {} }
Thread.current[@ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
Thread.current[@generation_key] ||= Net::HTTP::Persistent.new_nested_hash
Thread.current[@ssl_generation_key] ||= Net::HTTP::Persistent.new_nested_hash
Thread.current[@request_key] ||= Hash.new 0
Thread.current[@timeout_key] ||= Hash.new EPOCH

Expand Down
38 changes: 37 additions & 1 deletion test/test_net_http_persistent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ class BasicConnection
attr_accessor :started, :finished, :address, :port,
:read_timeout, :open_timeout
attr_reader :req, :debug_output
def initialize
def initialize(*args) # swallowing args so that it can be used
# as Net::HTTP::Persistent's http_class
@started, @finished = 0, 0
@address, @port = 'example.com', 80
end
Expand Down Expand Up @@ -1423,6 +1424,41 @@ def test_retry_change_requests_equals
assert @http.can_retry?(post)
end

def test_cleanup
http = Net::HTTP::Persistent.new 'name'
def http.http_class; BasicConnection end
uri = URI.parse 'http://example/'

# lets make sure that the thread's local storage will get
# initialized by 'connection_for'
Thread.current[http.generation_key] = nil
Thread.current[http.ssl_generation_key] = nil

c1_object_id = http.connection_for(uri).object_id

# Reconnect
http.reconnect
http.connection_for uri

# Cleanup
http.cleanup(http.generation)

# Verify that the old connection object is not lingering around
ObjectSpace.garbage_collect

c1_cleaned_up = true
ObjectSpace.each_object do |o|
if c1_object_id == o.object_id
c1_cleaned_up = false
end
end

assert c1_cleaned_up, "connection not cleaned up"
assert_empty conns
assert_empty ssl_conns
end


def test_shutdown
ssl_conns
c = connection
Expand Down