This class provides simple methods for issuing various types of HTTP requests. It’s interface is intended to mirror Ruby’s Net::HTTP object, but it provides a few important bits of additional functionality. Notably:
# File lib/puppet/network/http/connection.rb, line 20 def initialize(host, port, use_ssl = true) @host = host @port = port @use_ssl = use_ssl end
end of Net::HTTP#request_* proxies
# File lib/puppet/network/http/connection.rb, line 109 def address connection.address end
# File lib/puppet/network/http/connection.rb, line 38 def delete(*args) request(:delete, *args) end
# File lib/puppet/network/http/connection.rb, line 26 def get(*args) request(:get, *args) end
# File lib/puppet/network/http/connection.rb, line 34 def head(*args) request(:head, *args) end
# File lib/puppet/network/http/connection.rb, line 113 def port connection.port end
# File lib/puppet/network/http/connection.rb, line 30 def post(*args) request(:post, *args) end
# File lib/puppet/network/http/connection.rb, line 42 def put(*args) request(:put, *args) end
# File lib/puppet/network/http/connection.rb, line 46 def request(method, *args) peer_certs = [] verify_errors = [] connection.verify_callback = proc do |preverify_ok, ssl_context| # We use the callback to collect the certificates for use in # constructing the error message if the verification failed. # This is necessary since we don't have direct access to the # cert that we expected the connection to use otherwise. peer_certs << Puppet::SSL::Certificate.from_instance(ssl_context.current_cert) # And also keep the detailed verification error if such an error occurs if ssl_context.error_string and not preverify_ok verify_errors << "#{ssl_context.error_string} for #{ssl_context.current_cert.subject}" end preverify_ok end response = connection.send(method, *args) # Now that the request completed successfully, lets check the involved # certificates for approaching expiration dates warn_if_near_expiration(*peer_certs) response rescue OpenSSL::SSL::SSLError => error if error.message.include? "certificate verify failed" msg = error.message msg << ": [" + verify_errors.join('; ') + "]" raise Puppet::Error, msg elsif error.message =~ /hostname (was )?not match/ raise unless cert = peer_certs.find { |c| c.name !~ /^puppet ca/ } valid_certnames = [cert.name, *cert.subject_alt_names].uniq msg = valid_certnames.length > 1 ? "one of #{valid_certnames.join(', ')}" : valid_certnames.first raise Puppet::Error, "Server hostname '#{connection.address}' did not match server certificate; expected #{msg}" else raise end end
TODO: These are proxies for the Net::HTTP#request_* methods, which are almost the same as the “get”, “post”, etc. methods that we’ve ported above, but they are able to accept a code block and will yield to it. For now we’re not funneling these proxy implementations through our request method above, so they will not inherit the same error handling. In the future we may want to refactor these so that they are funneled through that method and do inherit the error handling.
# File lib/puppet/network/http/connection.rb, line 95 def request_get(*args, &block) connection.request_get(*args, &block) end
# File lib/puppet/network/http/connection.rb, line 99 def request_head(*args, &block) connection.request_head(*args, &block) end
# File lib/puppet/network/http/connection.rb, line 103 def request_post(*args, &block) connection.request_post(*args, &block) end
# File lib/puppet/network/http/connection.rb, line 117 def use_ssl? connection.use_ssl? end