# module Puppet::Network::HTTP::Handler

### Attributes

handler[R]
server[R]

### Public Instance Methods

accept_header(request) click to toggle source

Retrieve the accept header from the http request.

    # File lib/puppet/network/http/handler.rb, line 18
    def accept_header(request)
      raise NotImplementedError
    end

content_type_header(request) click to toggle source

Retrieve the Content-Type header from the http request.

    # File lib/puppet/network/http/handler.rb, line 23
    def content_type_header(request)
      raise NotImplementedError
    end

do_destroy(indirection_name, key, params, request, response) click to toggle source

Execute our destroy.

    # File lib/puppet/network/http/handler.rb, line 155
    def do_destroy(indirection_name, key, params, request, response)
      result = model(indirection_name).indirection.destroy(key, params)

      return_yaml_response(response, result)
    end

do_exception(response, exception, status=400) click to toggle source

    # File lib/puppet/network/http/handler.rb, line 90
    def do_exception(response, exception, status=400)
      if exception.is_a?(Puppet::Network::AuthorizationError)
        # make sure we return the correct status code
        # for authorization issues
        status = 403 if status == 400
      end
      if exception.is_a?(Exception)
        Puppet.log_exception(exception)
      end
      set_content_type(response, "text/plain")
      set_response(response, exception.to_s, status)
    end

do_find(indirection_name, key, params, request, response) click to toggle source

Execute our find.

    # File lib/puppet/network/http/handler.rb, line 109
    def do_find(indirection_name, key, params, request, response)
      unless result = model(indirection_name).indirection.find(key, params)
        Puppet.info("Could not find #{indirection_name} for '#{key}'")
        return do_exception(response, "Could not find #{indirection_name} #{key}", 404)
      end

      # The encoding of the result must include the format to use,
      # and it needs to be used for both the rendering and as
      # the content type.
      format = format_to_use(request)
      set_content_type(response, format)

      if result.respond_to?(:render)
        set_response(response, result.render(format))
      else
        set_response(response, result)
      end
    end

do_head(indirection_name, key, params, request, response) click to toggle source

Execute our head.

    # File lib/puppet/network/http/handler.rb, line 129
    def do_head(indirection_name, key, params, request, response)
      unless self.model(indirection_name).indirection.head(key, params)
        Puppet.info("Could not find #{indirection_name} for '#{key}'")
        return do_exception(response, "Could not find #{indirection_name} #{key}", 404)
      end

      # No need to set a response because no response is expected from a
      # HEAD request.  All we need to do is not die.
    end

do_save(indirection_name, key, params, request, response) click to toggle source

Execute our save.

    # File lib/puppet/network/http/handler.rb, line 162
    def do_save(indirection_name, key, params, request, response)
      data = body(request).to_s
      raise ArgumentError, "No data to save" if !data or data.empty?

      format = request_format(request)
      obj = model(indirection_name).convert_from(format, data)
      result = model(indirection_name).indirection.save(obj, key)
      return_yaml_response(response, result)
    end

do_search(indirection_name, key, params, request, response) click to toggle source

Execute our search.

    # File lib/puppet/network/http/handler.rb, line 140
    def do_search(indirection_name, key, params, request, response)
      model  = self.model(indirection_name)
      result = model.indirection.search(key, params)

      if result.nil?
        return do_exception(response, "Could not find instances in #{indirection_name} with '#{key}'", 404)
      end

      format = format_to_use(request)
      set_content_type(response, format)

      set_response(response, model.render_multiple(format, result))
    end

format_to_mime(format) click to toggle source

    # File lib/puppet/network/http/handler.rb, line 56
    def format_to_mime(format)
      format.is_a?(Puppet::Network::Format) ? format.mime : format
    end

format_to_use(request) click to toggle source

Which format to use when serializing our response or interpreting the request. IF the client provided a Content-Type use this, otherwise use the Accept header and just pick the first value.

    # File lib/puppet/network/http/handler.rb, line 30
    def format_to_use(request)
      unless header = accept_header(request)
        raise ArgumentError, "An Accept header must be provided to pick the right format"
      end

      format = nil
      header.split(/,\s*/).each do |name|
        next unless format = Puppet::Network::FormatHandler.format(name)
        next unless format.suitable?
        return format
      end

      raise "No specified acceptable formats (#{header}) are functional on this machine"
    end

initialize_for_puppet(server) click to toggle source

    # File lib/puppet/network/http/handler.rb, line 60
    def initialize_for_puppet(server)
      @server = server
    end

model(indirection_name) click to toggle source

    # File lib/puppet/network/http/handler.rb, line 103
    def model(indirection_name)
      raise ArgumentError, "Could not find indirection '#{indirection_name}'" unless indirection = Puppet::Indirector::Indirection.instance(indirection_name.to_sym)
      indirection.model
    end

process(request, response) click to toggle source

handle an HTTP request

    # File lib/puppet/network/http/handler.rb, line 65
    def process(request, response)
      indirection, method, key, params = uri2indirection(http_method(request), path(request), params(request))

      check_authorization(indirection, method, key, params)
      warn_if_near_expiration(client_cert(request))

      send("do_#{method}", indirection, key, params, request, response)
    rescue SystemExit,NoMemoryError
      raise
    rescue Exception => e
      return do_exception(response, e)
    ensure
      cleanup(request)
    end

request_format(request) click to toggle source

    # File lib/puppet/network/http/handler.rb, line 45
    def request_format(request)
      if header = content_type_header(request)
        header.gsub!(/\s*;.*$/,'') # strip any charset
        format = Puppet::Network::FormatHandler.mime(header)
        raise "Client sent a mime-type (#{header}) that doesn't correspond to a format we support" if format.nil?
        return format.name.to_s if format.suitable?
      end

      raise "No Content-Type header was received, it isn't possible to unserialize the request"
    end

resolve_node(result) click to toggle source

resolve node name from peer’s ip address this is used when the request is unauthenticated

    # File lib/puppet/network/http/handler.rb, line 174
    def resolve_node(result)
      begin
        return Resolv.getname(result[:ip])
      rescue => detail
        Puppet.err "Could not resolve #{result[:ip]}: #{detail}"
      end
      result[:ip]
    end

set_content_type(response, format) click to toggle source

Set the specified format as the content type of the response.

    # File lib/puppet/network/http/handler.rb, line 86
    def set_content_type(response, format)
      raise NotImplementedError
    end

set_response(response, body, status = 200) click to toggle source

Set the response up, with the body and status.

    # File lib/puppet/network/http/handler.rb, line 81
    def set_response(response, body, status = 200)
      raise NotImplementedError
    end