# frozen_string_literal: true # This class is effectively public API, because a Request object is passed as a # parameter to the current Handler subclass. Puppetserver implements its own # Handler # https://github.com/puppetlabs/puppetserver/blob/8.3.0/src/ruby/puppetserver-lib/puppet/server/network/http/handler.rb#L9 # and the Request object is passed to its Handler#body method # https://github.com/puppetlabs/puppetserver/blob/8.3.0/src/ruby/puppetserver-lib/puppet/server/network/http/handler.rb#L36 Puppet::Network::HTTP::Request = Struct.new(:headers, :params, :method, :path, :routing_path, :client_cert, :body) do # rubocop:disable Lint/StructNewOverride def self.from_hash(hash) symbol_members = members.collect(&:intern) unknown = hash.keys - symbol_members if unknown.empty? new(hash[:headers] || {}, hash[:params] || {}, hash[:method] || "GET", hash[:path], hash[:routing_path] || hash[:path], hash[:client_cert], hash[:body]) else raise ArgumentError, _("Unknown arguments: %{args}") % { args: unknown.collect(&:inspect).join(', ') } end end def route_into(prefix) self.class.new(headers, params, method, path, routing_path.sub(prefix, ''), client_cert, body) end def formatter header = headers['content-type'] if header header.gsub!(/\s*;.*$/,'') # strip any charset format = Puppet::Network::FormatHandler.mime(header) return format if valid_network_format?(format) # TRANSLATORS "mime-type" is a keyword and should not be translated raise Puppet::Network::HTTP::Error::HTTPUnsupportedMediaTypeError.new( _("Client sent a mime-type (%{header}) that doesn't correspond to a format we support") % { header: headers['content-type'] }, Puppet::Network::HTTP::Issues::UNSUPPORTED_MEDIA_TYPE) end raise Puppet::Network::HTTP::Error::HTTPBadRequestError.new( _("No Content-Type header was received, it isn't possible to unserialize the request"), Puppet::Network::HTTP::Issues::MISSING_HEADER_FIELD) end def response_formatters_for(supported_formats, default_accepted_formats = nil) accepted_formats = headers['accept'] || default_accepted_formats if accepted_formats.nil? raise Puppet::Network::HTTP::Error::HTTPBadRequestError.new(_("Missing required Accept header"), Puppet::Network::HTTP::Issues::MISSING_HEADER_FIELD) end formats = Puppet::Network::FormatHandler.most_suitable_formats_for( accepted_formats.split(/\s*,\s*/), supported_formats) formats.find_all do |format| # we are only passed supported_formats that are suitable # and whose klass implements the required_methods valid_network_format?(format) end return formats unless formats.empty? raise Puppet::Network::HTTP::Error::HTTPNotAcceptableError.new( _("No supported formats are acceptable (Accept: %{accepted_formats})") % { accepted_formats: accepted_formats }, Puppet::Network::HTTP::Issues::UNSUPPORTED_FORMAT) end private def valid_network_format?(format) # YAML in network requests is not supported. See http://links.puppet.com/deprecate_yaml_on_network format != nil && format.name != :yaml && format.name != :b64_zlib_yaml end end