Warning: session_start(): Session cannot be started after headers have already been sent in /home/tvrreohg/public_html/manga.php on line 13
# frozen_string_literal: true
require_relative '../../../puppet/http'
# This will be raised if too many redirects happen for a given HTTP request
class Puppet::Network::HTTP::RedirectionLimitExceededException < Puppet::Error; end
# 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:
#
# * Any HTTPS requests made using this class will use Puppet's SSL
# certificate configuration for their authentication, and
# * Provides some useful error handling for any SSL errors that occur
# during a request.
#
# @deprecated Use {Puppet.runtime[:http]}
# @api public
class Puppet::Network::HTTP::Connection
include Puppet::HTTP::ResponseConverter
OPTION_DEFAULTS = {
:use_ssl => true,
:verifier => nil,
:redirect_limit => 10,
}
# 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
def initialize(host, port, options = {})
unknown_options = options.keys - OPTION_DEFAULTS.keys
raise Puppet::Error, _("Unrecognized option(s): %{opts}") % { opts: unknown_options.map(&:inspect).sort.join(', ') } unless unknown_options.empty?
options = OPTION_DEFAULTS.merge(options)
@use_ssl = options[:use_ssl]
if @use_ssl
unless options[:verifier].is_a?(Puppet::SSL::Verifier)
raise ArgumentError, _("Expected an instance of Puppet::SSL::Verifier but was passed a %{klass}") % { klass: options[:verifier].class }
end
@verifier = options[:verifier]
end
@redirect_limit = options[:redirect_limit]
@site = Puppet::HTTP::Site.new(@use_ssl ? 'https' : 'http', host, port)
@client = Puppet.runtime[:http]
end
# The address to connect to.
def address
@site.host
end
# The port to connect to.
def port
@site.port
end
# Whether to use ssl
def use_ssl?
@site.use_ssl?
end
# @api private
def verifier
@verifier
end
# @!macro [new] common_options
# @param options [Hash] options influencing the request made. Any
# options not recognized by this class will be ignored - no error will
# be thrown.
# @option options [Hash{Symbol => String}] :basic_auth The basic auth
# :username and :password to use for the request, :metric_id Ignored
# by this class - used by Puppet Server only. The metric id by which
# to track metrics on requests.
# @param path [String]
# @param headers [Hash{String => String}]
# @!macro common_options
# @api public
def get(path, headers = {}, options = {})
headers ||= {}
options[:ssl_context] ||= resolve_ssl_context
options[:redirect_limit] ||= @redirect_limit
with_error_handling do
to_ruby_response(@client.get(to_url(path), headers: headers, options: options))
end
end
# @param path [String]
# @param data [String]
# @param headers [Hash{String => String}]
# @!macro common_options
# @api public
def post(path, data, headers = nil, options = {})
headers ||= {}
headers['Content-Type'] ||= "application/x-www-form-urlencoded"
data ||= ''
options[:ssl_context] ||= resolve_ssl_context
options[:redirect_limit] ||= @redirect_limit
with_error_handling do
to_ruby_response(@client.post(to_url(path), data, headers: headers, options: options))
end
end
# @param path [String]
# @param headers [Hash{String => String}]
# @!macro common_options
# @api public
def head(path, headers = {}, options = {})
headers ||= {}
options[:ssl_context] ||= resolve_ssl_context
options[:redirect_limit] ||= @redirect_limit
with_error_handling do
to_ruby_response(@client.head(to_url(path), headers: headers, options: options))
end
end
# @param path [String]
# @param headers [Hash{String => String}]
# @!macro common_options
# @api public
def delete(path, headers = { 'Depth' => 'Infinity' }, options = {})
headers ||= {}
options[:ssl_context] ||= resolve_ssl_context
options[:redirect_limit] ||= @redirect_limit
with_error_handling do
to_ruby_response(@client.delete(to_url(path), headers: headers, options: options))
end
end
# @param path [String]
# @param data [String]
# @param headers [Hash{String => String}]
# @!macro common_options
# @api public
def put(path, data, headers = nil, options = {})
headers ||= {}
headers['Content-Type'] ||= "application/x-www-form-urlencoded"
data ||= ''
options[:ssl_context] ||= resolve_ssl_context
options[:redirect_limit] ||= @redirect_limit
with_error_handling do
to_ruby_response(@client.put(to_url(path), data, headers: headers, options: options))
end
end
def request_get(*args, &block)
path, headers = *args
headers ||= {}
options = {
ssl_context: resolve_ssl_context,
redirect_limit: @redirect_limit
}
ruby_response = nil
@client.get(to_url(path), headers: headers, options: options) do |response|
ruby_response = to_ruby_response(response)
yield ruby_response if block_given?
end
ruby_response
end
def request_head(*args, &block)
path, headers = *args
headers ||= {}
options = {
ssl_context: resolve_ssl_context,
redirect_limit: @redirect_limit
}
response = @client.head(to_url(path), headers: headers, options: options)
ruby_response = to_ruby_response(response)
yield ruby_response if block_given?
ruby_response
end
def request_post(*args, &block)
path, data, headers = *args
headers ||= {}
headers['Content-Type'] ||= "application/x-www-form-urlencoded"
options = {
ssl_context: resolve_ssl_context,
redirect_limit: @redirect_limit
}
ruby_response = nil
@client.post(to_url(path), data, headers: headers, options: options) do |response|
ruby_response = to_ruby_response(response)
yield ruby_response if block_given?
end
ruby_response
end
private
# 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`.
def resolve_ssl_context
# don't need an ssl context for http connections
return nil unless @site.use_ssl?
# if our verifier has an ssl_context, use that
ctx = @verifier.ssl_context
return ctx if ctx
# load available certs
cert = Puppet::X509::CertProvider.new
ssl = Puppet::SSL::SSLProvider.new
begin
password = cert.load_private_key_password
ssl.load_context(certname: Puppet[:certname], password: password)
rescue Puppet::SSL::SSLError => e
Puppet.log_exception(e)
# if we don't have cacerts, then create a root context that doesn't
# trust anything. The old code used to fallback to VERIFY_NONE,
# which we don't want to emulate.
ssl.create_root_context(cacerts: [])
end
end
def to_url(path)
if path =~ %r{^https?://}
# The old Connection class accepts a URL as the request path, and sends
# it in "absolute-form" in the request line, e.g. GET https://puppet:8140/.
# See https://httpwg.org/specs/rfc7230.html#absolute-form. It just so happens
# to work because HTTP 1.1 servers are required to accept absolute-form even
# though clients are only supposed to send them to proxies, so the proxy knows
# what upstream server to CONNECT to. This method creates a URL using the
# scheme/host/port that the connection was created with, and appends the path
# and query portions of the absolute-form. The resulting request will use "origin-form"
# as it should have done all along.
abs_form = URI(path)
url = URI("#{@site.addr}/#{normalize_path(abs_form.path)}")
url.query = abs_form.query if abs_form.query
url
else
URI("#{@site.addr}/#{normalize_path(path)}")
end
end
def normalize_path(path)
if path[0] == '/'
path[1..]
else
path
end
end
def with_error_handling(&block)
yield
rescue Puppet::HTTP::TooManyRedirects => e
raise Puppet::Network::HTTP::RedirectionLimitExceededException.new(_("Too many HTTP redirections for %{host}:%{port}") % { host: @host, port: @port }, e)
rescue Puppet::HTTP::HTTPError => e
Puppet.log_exception(e, e.message)
case e.cause
when Net::OpenTimeout, Net::ReadTimeout, Net::HTTPError, EOFError
raise e.cause
else
raise e
end
end
end