class Gems::Connection
Manages HTTP connections to the RubyGems API
The connection of a client is its own, and cannot be given to it or read from it, so this class can change within 3.x as the rest of the internals can. Its settings are options of {Client} and of the {Gems} module, such as ‘open_timeout` and `proxy_url`, which is where they are configured.
@api private
Constants
- DEFAULT_KEEP_ALIVE_TIMEOUT
- DEFAULT_OPEN_TIMEOUT
-
Default timeout for opening connections in seconds
- DEFAULT_READ_TIMEOUT
- DEFAULT_WRITE_TIMEOUT
Attributes
The IO object for debug output
The credentials requests and responses carry are redacted from what is written to it (see {RedactedOutput}).
@api private @return [IO, nil] the IO object for debug output @example Get or set the debug output
connection.debug_output = $stderr
The parsed proxy URI @api private @return [URI::Generic, nil] the parsed proxy URI @example Get the proxy URI
connection.proxy_uri
The proxy URL for requests @api private @return [String, nil] the proxy URL for requests @example Get the proxy URL
connection.proxy_url
Public Class Methods
Initialize a new connection
@api private @param open_timeout [Numeric] the timeout for opening connections in seconds @param read_timeout [Numeric] the timeout for reading responses in seconds @param write_timeout [Numeric] the timeout for writing requests in seconds @param debug_output [IO, nil] the IO object for debug output @param proxy_url [String, nil] the proxy URL for requests @param keep_alive_timeout [Numeric] the seconds an idle connection is kept open for another request @param ca_file [String, nil] the path of a file of certificates TLS is verified with @param ca_path [String, nil] the path of a directory of certificates TLS is verified with @param cert_store [OpenSSL::X509::Store, nil] the store of certificates TLS is verified with @param client_cert [OpenSSL::X509::Certificate, nil] the certificate presented to a host that asks for one @param client_key [OpenSSL::PKey::PKey, nil] the private key of the client certificate @return [Connection] a new connection instance @raise [ArgumentError] if the proxy URL is invalid, or a certificate path names nothing @example Create a connection with default settings
connection = Gems::Connection.new
@example Create a connection with custom timeouts
connection = Gems::Connection.new(open_timeout: 30, read_timeout: 30)
@example Create a connection that trusts a certificate of its own
connection = Gems::Connection.new(ca_file: "/etc/ssl/certs/internal.pem")
# File lib/gems/connection.rb, line 160 def initialize(open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT, write_timeout: DEFAULT_WRITE_TIMEOUT, debug_output: nil, proxy_url: nil, keep_alive_timeout: DEFAULT_KEEP_ALIVE_TIMEOUT, ca_file: nil, ca_path: nil, cert_store: nil, client_cert: nil, client_key: nil) self.open_timeout = open_timeout self.read_timeout = read_timeout self.write_timeout = write_timeout @debug_output = debug_output self.keep_alive_timeout = keep_alive_timeout @pool = ConnectionPool.new self.proxy_url = proxy_url initialize_certificates(ca_file:, ca_path:, cert_store:, client_cert:, client_key:) end
Public Instance Methods
Close the connections kept open for the next request
The connections are opened again as they are needed, so a connection that is closed while it is being used is not interrupted, and requests can still be made afterwards.
@api private @return [Connection] the connection @example Close the connections a client keeps open
connection.close
# File lib/gems/connection.rb, line 205 def close pool.close self end
Summarize the connection for the console
@api private @return [String] the summary, which includes the proxy URL without its user and password @example Inspect a connection
connection.inspect # => #<Gems::Connection proxy_url=nil open_timeout=60 read_timeout=60 write_timeout=60 keep_alive_timeout=2>
# File lib/gems/connection.rb, line 133 def inspect "#<#{self.class} proxy_url=#{redact(proxy_url).inspect} open_timeout=#{open_timeout} " \ "read_timeout=#{read_timeout} write_timeout=#{write_timeout} keep_alive_timeout=#{keep_alive_timeout}>" end
Perform an HTTP request
The request is sent on the connection kept open for its host, when there is one it can be sent on, and that connection is kept open for the next request (see {#keep_alive_timeout}).
The settings are read once, before the connection is taken, and a connection that has to be opened is opened with them and kept under them, so that a setting changed while the request is being sent, from another thread, closes the connection when the next request is sent rather than keeping it as though it had been opened with the setting as it is now, and a connection is never opened with one setting and kept under another.
@api private @param request [Net::HTTPRequest] the HTTP request to perform @return [Net::HTTPResponse] the HTTP response @raise [NetworkError] if a network error occurs @example Perform a request
response = connection.perform(request: request)
# File lib/gems/connection.rb, line 190 def perform(request:) send_request(request, settings_for(request.uri)) rescue *NetworkError::WRAPPED => e raise NetworkError, "Network error: #{e}" end
Set the proxy URL for requests
@api private @param proxy_url [String, nil] the proxy URL, or nil to read proxies from the environment again @return [void] @raise [ArgumentError] if the proxy URL is invalid, in which case the proxy is left as it was @example Set the proxy URL
connection.proxy_url = "http://proxy.example.com:8080"
@example Clear the proxy URL
connection.proxy_url = nil
# File lib/gems/connection.rb, line 220 def proxy_url=(proxy_url) proxy_uri = proxy_url && parse_proxy_uri(proxy_url) @proxy_url = proxy_url @proxy_uri = proxy_uri end