summaryrefslogtreecommitdiff
path: root/jni/ruby/lib/rubygems/request
diff options
context:
space:
mode:
Diffstat (limited to 'jni/ruby/lib/rubygems/request')
-rw-r--r--jni/ruby/lib/rubygems/request/connection_pools.rb83
-rw-r--r--jni/ruby/lib/rubygems/request/http_pool.rb47
-rw-r--r--jni/ruby/lib/rubygems/request/https_pool.rb10
3 files changed, 140 insertions, 0 deletions
diff --git a/jni/ruby/lib/rubygems/request/connection_pools.rb b/jni/ruby/lib/rubygems/request/connection_pools.rb
new file mode 100644
index 0000000..7a0a6e6
--- /dev/null
+++ b/jni/ruby/lib/rubygems/request/connection_pools.rb
@@ -0,0 +1,83 @@
+require 'thread'
+
+class Gem::Request::ConnectionPools # :nodoc:
+
+ @client = Net::HTTP
+
+ class << self
+ attr_accessor :client
+ end
+
+ def initialize proxy_uri, cert_files
+ @proxy_uri = proxy_uri
+ @cert_files = cert_files
+ @pools = {}
+ @pool_mutex = Mutex.new
+ end
+
+ def pool_for uri
+ http_args = net_http_args(uri, @proxy_uri)
+ key = http_args + [https?(uri)]
+ @pool_mutex.synchronize do
+ @pools[key] ||=
+ if https? uri then
+ Gem::Request::HTTPSPool.new(http_args, @cert_files, @proxy_uri)
+ else
+ Gem::Request::HTTPPool.new(http_args, @cert_files, @proxy_uri)
+ end
+ end
+ end
+
+ def close_all
+ @pools.each_value {|pool| pool.close_all}
+ end
+
+ private
+
+ ##
+ # Returns list of no_proxy entries (if any) from the environment
+
+ def get_no_proxy_from_env
+ env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
+
+ return [] if env_no_proxy.nil? or env_no_proxy.empty?
+
+ env_no_proxy.split(/\s*,\s*/)
+ end
+
+ def https? uri
+ uri.scheme.downcase == 'https'
+ end
+
+ def no_proxy? host, env_no_proxy
+ host = host.downcase
+
+ env_no_proxy.any? do |pattern|
+ pattern = pattern.downcase
+
+ host[-pattern.length, pattern.length] == pattern or
+ (pattern.start_with? '.' and pattern[1..-1] == host)
+ end
+ end
+
+ def net_http_args uri, proxy_uri
+ net_http_args = [uri.host, uri.port]
+
+ no_proxy = get_no_proxy_from_env
+
+ if proxy_uri and not no_proxy?(uri.host, no_proxy) then
+ net_http_args + [
+ proxy_uri.host,
+ proxy_uri.port,
+ Gem::UriFormatter.new(proxy_uri.user).unescape,
+ Gem::UriFormatter.new(proxy_uri.password).unescape,
+ ]
+ elsif no_proxy? uri.host, no_proxy then
+ net_http_args + [nil, nil]
+ else
+ net_http_args
+ end
+ end
+
+end
+
diff --git a/jni/ruby/lib/rubygems/request/http_pool.rb b/jni/ruby/lib/rubygems/request/http_pool.rb
new file mode 100644
index 0000000..c9a1858
--- /dev/null
+++ b/jni/ruby/lib/rubygems/request/http_pool.rb
@@ -0,0 +1,47 @@
+##
+# A connection "pool" that only manages one connection for now. Provides
+# thread safe `checkout` and `checkin` methods. The pool consists of one
+# connection that corresponds to `http_args`. This class is private, do not
+# use it.
+
+class Gem::Request::HTTPPool # :nodoc:
+ attr_reader :cert_files, :proxy_uri
+
+ def initialize http_args, cert_files, proxy_uri
+ @http_args = http_args
+ @cert_files = cert_files
+ @proxy_uri = proxy_uri
+ @queue = SizedQueue.new 1
+ @queue << nil
+ end
+
+ def checkout
+ @queue.pop || make_connection
+ end
+
+ def checkin connection
+ @queue.push connection
+ end
+
+ def close_all
+ until @queue.empty?
+ if connection = @queue.pop(true) and connection.started?
+ connection.finish
+ end
+ end
+ @queue.push(nil)
+ end
+
+ private
+
+ def make_connection
+ setup_connection Gem::Request::ConnectionPools.client.new(*@http_args)
+ end
+
+ def setup_connection connection
+ connection.start
+ connection
+ end
+
+end
+
diff --git a/jni/ruby/lib/rubygems/request/https_pool.rb b/jni/ruby/lib/rubygems/request/https_pool.rb
new file mode 100644
index 0000000..2e3da0a
--- /dev/null
+++ b/jni/ruby/lib/rubygems/request/https_pool.rb
@@ -0,0 +1,10 @@
+class Gem::Request::HTTPSPool < Gem::Request::HTTPPool # :nodoc:
+ private
+
+ def setup_connection connection
+ Gem::Request.configure_connection_for_https(connection, @cert_files)
+ super
+ end
+end
+
+