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

Public Instance Methods

address() click to toggle source

The address to connect to.

   # File lib/puppet/network/http/connection.rb
65 def address
66   @site.host
67 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
142 def delete(path, headers = {'Depth' => 'Infinity'}, options = {})
143   headers ||= {}
144   options[:ssl_context] ||= resolve_ssl_context
145   options[:redirect_limit] ||= @redirect_limit
146 
147   with_error_handling do
148     to_ruby_response(@client.delete(to_url(path), headers: headers, options: options))
149   end
150 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
 97 def get(path, headers = {}, options = {})
 98   headers ||= {}
 99   options[:ssl_context] ||= resolve_ssl_context
100   options[:redirect_limit] ||= @redirect_limit
101 
102   with_error_handling do
103     to_ruby_response(@client.get(to_url(path), headers: headers, options: options))
104   end
105 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
128 def head(path, headers = {}, options = {})
129   headers ||= {}
130   options[:ssl_context] ||= resolve_ssl_context
131   options[:redirect_limit] ||= @redirect_limit
132 
133   with_error_handling do
134     to_ruby_response(@client.head(to_url(path), headers: headers, options: options))
135   end
136 end
port() click to toggle source

The port to connect to.

   # File lib/puppet/network/http/connection.rb
70 def port
71   @site.port
72 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
112 def post(path, data, headers = nil, options = {})
113   headers ||= {}
114   headers['Content-Type'] ||= "application/x-www-form-urlencoded"
115   data ||= ''
116   options[:ssl_context] ||= resolve_ssl_context
117   options[:redirect_limit] ||= @redirect_limit
118 
119   with_error_handling do
120     to_ruby_response(@client.post(to_url(path), data, headers: headers, options: options))
121   end
122 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
157 def put(path, data, headers = nil, options = {})
158   headers ||= {}
159   headers['Content-Type'] ||= "application/x-www-form-urlencoded"
160   data ||= ''
161   options[:ssl_context] ||= resolve_ssl_context
162   options[:redirect_limit] ||= @redirect_limit
163 
164   with_error_handling do
165     to_ruby_response(@client.put(to_url(path), data, headers: headers, options: options))
166   end
167 end
request_get(*args) { |ruby_response| ... } click to toggle source
    # File lib/puppet/network/http/connection.rb
169 def request_get(*args, &block)
170   path, headers = *args
171   headers ||= {}
172   options = {
173     ssl_context: resolve_ssl_context,
174     redirect_limit: @redirect_limit
175   }
176 
177   ruby_response = nil
178   @client.get(to_url(path), headers: headers, options: options) do |response|
179     ruby_response = to_ruby_response(response)
180     yield ruby_response if block_given?
181   end
182   ruby_response
183 end
request_head(*args) { |ruby_response| ... } click to toggle source
    # File lib/puppet/network/http/connection.rb
185 def request_head(*args, &block)
186   path, headers = *args
187   headers ||= {}
188   options = {
189     ssl_context: resolve_ssl_context,
190     redirect_limit: @redirect_limit
191   }
192 
193   response = @client.head(to_url(path), headers: headers, options: options)
194   ruby_response = to_ruby_response(response)
195   yield ruby_response if block_given?
196   ruby_response
197 end
request_post(*args) { |ruby_response| ... } click to toggle source
    # File lib/puppet/network/http/connection.rb
199 def request_post(*args, &block)
200   path, data, headers = *args
201   headers ||= {}
202   headers['Content-Type'] ||= "application/x-www-form-urlencoded"
203   options = {
204     ssl_context: resolve_ssl_context,
205     redirect_limit: @redirect_limit
206   }
207 
208   ruby_response = nil
209   @client.post(to_url(path), data, headers: headers, options: options) do |response|
210     ruby_response = to_ruby_response(response)
211     yield ruby_response if block_given?
212   end
213   ruby_response
214 end
use_ssl?() click to toggle source

Whether to use ssl

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

@api private

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

Private Instance Methods

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