class Puppet::Network::HTTP::Connection

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:

@deprecated Use {Puppet.runtime} @api public

Constants

OPTION_DEFAULTS

Public Class Methods

new(host, port, options = {}) click to toggle source

Creates a new HTTP client connection to `host`:`port`. @param host [String] the host to which this client will connect to @param port [Integer] the port to which this client will connect to @param options [Hash] options influencing the properties of the created

connection,

@option options [Boolean] :use_ssl true to connect with SSL, false

otherwise, defaults to true

@option options [Puppet::SSL::Verifier] :verifier An object that will configure

any verification to do on the connection

@option options [Integer] :redirect_limit the number of allowed

redirections, defaults to 10 passing any other option in the options
hash results in a Puppet::Error exception

@note the HTTP connection itself happens lazily only when {#request}, or

one of the {#get}, {#post}, {#delete}, {#head} or {#put} is called

@note The correct way to obtain a connection is to use one of the factory

methods on {Puppet::Network::HttpPool}

@api private

   # File lib/puppet/network/http/connection.rb
45 def initialize(host, port, options = {})
46   unknown_options = options.keys - OPTION_DEFAULTS.keys
47   raise Puppet::Error, _("Unrecognized option(s): %{opts}") % { opts: unknown_options.map(&:inspect).sort.join(', ') } unless unknown_options.empty?
48 
49   options = OPTION_DEFAULTS.merge(options)
50   @use_ssl = options[:use_ssl]
51   if @use_ssl
52     unless options[:verifier].is_a?(Puppet::SSL::Verifier)
53       raise ArgumentError, _("Expected an instance of Puppet::SSL::Verifier but was passed a %{klass}") % { klass: options[:verifier].class }
54     end
55 
56     @verifier = options[:verifier]
57   end
58   @redirect_limit = options[:redirect_limit]
59   @site = Puppet::HTTP::Site.new(@use_ssl ? 'https' : 'http', host, port)
60   @client = Puppet.runtime[:http]
61 end

Public Instance Methods

address() click to toggle source

The address to connect to.

   # File lib/puppet/network/http/connection.rb
64 def address
65   @site.host
66 end
delete(path, headers = {'Depth' => 'Infinity'}, options = {}) click to toggle source

@param path [String] @param headers [Hash{String => String}] @!macro common_options @api public

    # File lib/puppet/network/http/connection.rb
141 def delete(path, headers = {'Depth' => 'Infinity'}, options = {})
142   headers ||= {}
143   options[:ssl_context] ||= resolve_ssl_context
144   options[:redirect_limit] ||= @redirect_limit
145 
146   with_error_handling do
147     to_ruby_response(@client.delete(to_url(path), headers: headers, options: options))
148   end
149 end
get(path, headers = {}, options = {}) click to toggle source

@param path [String] @param headers [Hash{String => String}] @!macro common_options @api public

    # File lib/puppet/network/http/connection.rb
 96 def get(path, headers = {}, options = {})
 97   headers ||= {}
 98   options[:ssl_context] ||= resolve_ssl_context
 99   options[:redirect_limit] ||= @redirect_limit
100 
101   with_error_handling do
102     to_ruby_response(@client.get(to_url(path), headers: headers, options: options))
103   end
104 end
head(path, headers = {}, options = {}) click to toggle source

@param path [String] @param headers [Hash{String => String}] @!macro common_options @api public

    # File lib/puppet/network/http/connection.rb
127 def head(path, headers = {}, options = {})
128   headers ||= {}
129   options[:ssl_context] ||= resolve_ssl_context
130   options[:redirect_limit] ||= @redirect_limit
131 
132   with_error_handling do
133     to_ruby_response(@client.head(to_url(path), headers: headers, options: options))
134   end
135 end
port() click to toggle source

The port to connect to.

   # File lib/puppet/network/http/connection.rb
69 def port
70   @site.port
71 end
post(path, data, headers = nil, options = {}) click to toggle source

@param path [String] @param data [String] @param headers [Hash{String => String}] @!macro common_options @api public

    # File lib/puppet/network/http/connection.rb
111 def post(path, data, headers = nil, options = {})
112   headers ||= {}
113   headers['Content-Type'] ||= "application/x-www-form-urlencoded"
114   data ||= ''
115   options[:ssl_context] ||= resolve_ssl_context
116   options[:redirect_limit] ||= @redirect_limit
117 
118   with_error_handling do
119     to_ruby_response(@client.post(to_url(path), data, headers: headers, options: options))
120   end
121 end
put(path, data, headers = nil, options = {}) click to toggle source

@param path [String] @param data [String] @param headers [Hash{String => String}] @!macro common_options @api public

    # File lib/puppet/network/http/connection.rb
156 def put(path, data, headers = nil, options = {})
157   headers ||= {}
158   headers['Content-Type'] ||= "application/x-www-form-urlencoded"
159   data ||= ''
160   options[:ssl_context] ||= resolve_ssl_context
161   options[:redirect_limit] ||= @redirect_limit
162 
163   with_error_handling do
164     to_ruby_response(@client.put(to_url(path), data, headers: headers, options: options))
165   end
166 end
request_get(*args) { |ruby_response| ... } click to toggle source
    # File lib/puppet/network/http/connection.rb
168 def request_get(*args, &block)
169   path, headers = *args
170   headers ||= {}
171   options = {
172     ssl_context: resolve_ssl_context,
173     redirect_limit: @redirect_limit
174   }
175 
176   ruby_response = nil
177   @client.get(to_url(path), headers: headers, options: options) do |response|
178     ruby_response = to_ruby_response(response)
179     yield ruby_response if block_given?
180   end
181   ruby_response
182 end
request_head(*args) { |ruby_response| ... } click to toggle source
    # File lib/puppet/network/http/connection.rb
184 def request_head(*args, &block)
185   path, headers = *args
186   headers ||= {}
187   options = {
188     ssl_context: resolve_ssl_context,
189     redirect_limit: @redirect_limit
190   }
191 
192   response = @client.head(to_url(path), headers: headers, options: options)
193   ruby_response = to_ruby_response(response)
194   yield ruby_response if block_given?
195   ruby_response
196 end
request_post(*args) { |ruby_response| ... } click to toggle source
    # File lib/puppet/network/http/connection.rb
198 def request_post(*args, &block)
199   path, data, headers = *args
200   headers ||= {}
201   headers['Content-Type'] ||= "application/x-www-form-urlencoded"
202   options = {
203     ssl_context: resolve_ssl_context,
204     redirect_limit: @redirect_limit
205   }
206 
207   ruby_response = nil
208   @client.post(to_url(path), data, headers: headers, options: options) do |response|
209     ruby_response = to_ruby_response(response)
210     yield ruby_response if block_given?
211   end
212   ruby_response
213 end
use_ssl?() click to toggle source

Whether to use ssl

   # File lib/puppet/network/http/connection.rb
74 def use_ssl?
75   @site.use_ssl?
76 end
verifier() click to toggle source

@api private

   # File lib/puppet/network/http/connection.rb
79 def verifier
80   @verifier
81 end

Private Instance Methods

normalize_path(path) click to toggle source
    # File lib/puppet/network/http/connection.rb
265 def normalize_path(path)
266   if path[0] == '/'
267     path[1..-1]
268   else
269     path
270   end
271 end
resolve_ssl_context() click to toggle source

Resolve the ssl_context based on the verifier associated with this connection or load the available set of certs and key on disk. Don't try to bootstrap the agent, as we only want that to be triggered when running `puppet ssl` or `puppet agent`.

    # File lib/puppet/network/http/connection.rb
221 def resolve_ssl_context
222   # don't need an ssl context for http connections
223   return nil unless @site.use_ssl?
224 
225   # if our verifier has an ssl_context, use that
226   ctx = @verifier.ssl_context
227   return ctx if ctx
228 
229   # load available certs
230   cert = Puppet::X509::CertProvider.new
231   ssl = Puppet::SSL::SSLProvider.new
232   begin
233     password = cert.load_private_key_password
234     ssl.load_context(certname: Puppet[:certname], password: password)
235   rescue Puppet::SSL::SSLError => e
236     Puppet.log_exception(e)
237 
238     # if we don't have cacerts, then create a root context that doesn't
239     # trust anything. The old code used to fallback to VERIFY_NONE,
240     # which we don't want to emulate.
241     ssl.create_root_context(cacerts: [])
242   end
243 end
to_url(path) click to toggle source
    # File lib/puppet/network/http/connection.rb
245 def to_url(path)
246   if path =~ /^https?:\/\//
247     # The old Connection class accepts a URL as the request path, and sends
248     # it in "absolute-form" in the request line, e.g. GET https://puppet:8140/.
249     # See https://httpwg.org/specs/rfc7230.html#absolute-form. It just so happens
250     # to work because HTTP 1.1 servers are required to accept absolute-form even
251     # though clients are only supposed to send them to proxies, so the proxy knows
252     # what upstream server to CONNECT to. This method creates a URL using the
253     # scheme/host/port that the connection was created with, and appends the path
254     # and query portions of the absolute-form. The resulting request will use "origin-form"
255     # as it should have done all along.
256     abs_form = URI(path)
257     url = URI("#{@site.addr}/#{normalize_path(abs_form.path)}")
258     url.query = abs_form.query if abs_form.query
259     url
260   else
261     URI("#{@site.addr}/#{normalize_path(path)}")
262   end
263 end
with_error_handling() { || ... } click to toggle source
    # File lib/puppet/network/http/connection.rb
273 def with_error_handling(&block)
274   yield
275 rescue Puppet::HTTP::TooManyRedirects => e
276   raise Puppet::Network::HTTP::RedirectionLimitExceededException.new(_("Too many HTTP redirections for %{host}:%{port}") % { host: @host, port: @port }, e)
277 rescue Puppet::HTTP::HTTPError => e
278   Puppet.log_exception(e, e.message)
279   case e.cause
280   when Net::OpenTimeout, Net::ReadTimeout, Net::HTTPError, EOFError
281     raise e.cause
282   else
283     raise e
284   end
285 end