summaryrefslogtreecommitdiffstats
path: root/lib/puppet/network/http/handler.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/network/http/handler.rb')
-rw-r--r--lib/puppet/network/http/handler.rb388
1 files changed, 194 insertions, 194 deletions
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index 9f467372c..03d24b3fe 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -7,223 +7,223 @@ require 'puppet/network/rights'
require 'resolv'
module Puppet::Network::HTTP::Handler
- include Puppet::Network::HTTP::API::V1
- include Puppet::Network::RestAuthorization
+ include Puppet::Network::HTTP::API::V1
+ include Puppet::Network::RestAuthorization
- attr_reader :server, :handler
+ attr_reader :server, :handler
- # Retrieve the accept header from the http request.
- def accept_header(request)
- raise NotImplementedError
- end
-
- # Retrieve the Content-Type header from the http request.
- def content_type_header(request)
- raise NotImplementedError
- end
-
- # 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.
- 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
-
- 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
-
- def format_to_mime(format)
- format.is_a?(Puppet::Network::Format) ? format.mime : format
- end
-
- def initialize_for_puppet(server)
- @server = server
- end
-
- # handle an HTTP request
- def process(request, response)
- indirection_request = uri2indirection(http_method(request), path(request), params(request))
-
- check_authorization(indirection_request)
-
- send("do_#{indirection_request.method}", indirection_request, request, response)
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => e
- return do_exception(response, e)
- end
-
- # Set the response up, with the body and status.
- def set_response(response, body, status = 200)
- raise NotImplementedError
- end
-
- # Set the specified format as the content type of the response.
- def set_content_type(response, format)
- raise NotImplementedError
- end
+ # Retrieve the accept header from the http request.
+ def accept_header(request)
+ raise NotImplementedError
+ end
- 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)
- puts exception.backtrace if Puppet[:trace]
- Puppet.err(exception)
- end
- set_content_type(response, "text/plain")
- set_response(response, exception.to_s, status)
- end
-
- # Execute our find.
- def do_find(indirection_request, request, response)
- unless result = indirection_request.model.find(indirection_request.key, indirection_request.to_hash)
- Puppet.info("Could not find #{indirection_request.indirection_name} for '#{indirection_request.key}'")
- return do_exception(response, "Could not find #{indirection_request.indirection_name} #{indirection_request.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)
-
- set_response(response, result.render(format))
- end
+ # Retrieve the Content-Type header from the http request.
+ def content_type_header(request)
+ raise NotImplementedError
+ end
- # Execute our search.
- def do_search(indirection_request, request, response)
- result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash)
-
- if result.nil? or (result.is_a?(Array) and result.empty?)
- return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.to_hash.inspect}'", 404)
- end
-
- format = format_to_use(request)
- set_content_type(response, format)
-
- set_response(response, indirection_request.model.render_multiple(format, result))
+ # 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.
+ def format_to_use(request)
+ unless header = accept_header(request)
+ raise ArgumentError, "An Accept header must be provided to pick the right format"
end
- # Execute our destroy.
- def do_destroy(indirection_request, request, response)
- result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash)
-
- return_yaml_response(response, result)
+ format = nil
+ header.split(/,\s*/).each do |name|
+ next unless format = Puppet::Network::FormatHandler.format(name)
+ next unless format.suitable?
+ return format
end
- # Execute our save.
- def do_save(indirection_request, request, response)
- data = body(request).to_s
- raise ArgumentError, "No data to save" if !data or data.empty?
-
- format = request_format(request)
- obj = indirection_request.model.convert_from(format, data)
- result = save_object(indirection_request, obj)
- return_yaml_response(response, result)
- end
+ raise "No specified acceptable formats (#{header}) are functional on this machine"
+ end
- # resolve node name from peer's ip address
- # this is used when the request is unauthenticated
- def resolve_node(result)
- begin
- return Resolv.getname(result[:ip])
- rescue => detail
- Puppet.err "Could not resolve #{result[:ip]}: #{detail}"
- end
- result[:ip]
+ 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
- private
+ raise "No Content-Type header was received, it isn't possible to unserialize the request"
+ end
+
+ def format_to_mime(format)
+ format.is_a?(Puppet::Network::Format) ? format.mime : format
+ end
- def return_yaml_response(response, body)
- set_content_type(response, Puppet::Network::FormatHandler.format("yaml"))
- set_response(response, body.to_yaml)
- end
+ def initialize_for_puppet(server)
+ @server = server
+ end
- # LAK:NOTE This has to be here for testing; it's a stub-point so
- # we keep infinite recursion from happening.
- def save_object(ind_request, object)
- object.save(ind_request.key)
- end
+ # handle an HTTP request
+ def process(request, response)
+ indirection_request = uri2indirection(http_method(request), path(request), params(request))
- def get?(request)
- http_method(request) == 'GET'
- end
+ check_authorization(indirection_request)
- def put?(request)
- http_method(request) == 'PUT'
- end
+ send("do_#{indirection_request.method}", indirection_request, request, response)
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => e
+ return do_exception(response, e)
+ end
- def delete?(request)
- http_method(request) == 'DELETE'
- end
+ # Set the response up, with the body and status.
+ def set_response(response, body, status = 200)
+ raise NotImplementedError
+ end
- # methods to be overridden by the including web server class
+ # Set the specified format as the content type of the response.
+ def set_content_type(response, format)
+ raise NotImplementedError
+ end
- def http_method(request)
- raise NotImplementedError
+ 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
-
- def path(request)
- raise NotImplementedError
+ if exception.is_a?(Exception)
+ puts exception.backtrace if Puppet[:trace]
+ Puppet.err(exception)
end
+ set_content_type(response, "text/plain")
+ set_response(response, exception.to_s, status)
+ end
- def request_key(request)
- raise NotImplementedError
+ # Execute our find.
+ def do_find(indirection_request, request, response)
+ unless result = indirection_request.model.find(indirection_request.key, indirection_request.to_hash)
+ Puppet.info("Could not find #{indirection_request.indirection_name} for '#{indirection_request.key}'")
+ return do_exception(response, "Could not find #{indirection_request.indirection_name} #{indirection_request.key}", 404)
end
- def body(request)
- raise NotImplementedError
- 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)
- def params(request)
- raise NotImplementedError
- end
+ set_response(response, result.render(format))
+ end
- def decode_params(params)
- params.inject({}) do |result, ary|
- param, value = ary
- next result if param.nil? || param.empty?
-
- param = param.to_sym
-
- # These shouldn't be allowed to be set by clients
- # in the query string, for security reasons.
- next result if param == :node
- next result if param == :ip
- value = CGI.unescape(value)
- if value =~ /^---/
- value = YAML.load(value)
- else
- value = true if value == "true"
- value = false if value == "false"
- value = Integer(value) if value =~ /^\d+$/
- value = value.to_f if value =~ /^\d+\.\d+$/
- end
- result[param] = value
- result
- end
- end
+ # Execute our search.
+ def do_search(indirection_request, request, response)
+ result = indirection_request.model.search(indirection_request.key, indirection_request.to_hash)
+
+ if result.nil? or (result.is_a?(Array) and result.empty?)
+ return do_exception(response, "Could not find instances in #{indirection_request.indirection_name} with '#{indirection_request.to_hash.inspect}'", 404)
+ end
+
+ format = format_to_use(request)
+ set_content_type(response, format)
+
+ set_response(response, indirection_request.model.render_multiple(format, result))
+ end
+
+ # Execute our destroy.
+ def do_destroy(indirection_request, request, response)
+ result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash)
+
+ return_yaml_response(response, result)
+ end
+
+ # Execute our save.
+ def do_save(indirection_request, request, response)
+ data = body(request).to_s
+ raise ArgumentError, "No data to save" if !data or data.empty?
+
+ format = request_format(request)
+ obj = indirection_request.model.convert_from(format, data)
+ result = save_object(indirection_request, obj)
+ return_yaml_response(response, result)
+ end
+
+ # resolve node name from peer's ip address
+ # this is used when the request is unauthenticated
+ def resolve_node(result)
+ begin
+ return Resolv.getname(result[:ip])
+ rescue => detail
+ Puppet.err "Could not resolve #{result[:ip]}: #{detail}"
+ end
+ result[:ip]
+ end
+
+ private
+
+ def return_yaml_response(response, body)
+ set_content_type(response, Puppet::Network::FormatHandler.format("yaml"))
+ set_response(response, body.to_yaml)
+ end
+
+ # LAK:NOTE This has to be here for testing; it's a stub-point so
+ # we keep infinite recursion from happening.
+ def save_object(ind_request, object)
+ object.save(ind_request.key)
+ end
+
+ def get?(request)
+ http_method(request) == 'GET'
+ end
+
+ def put?(request)
+ http_method(request) == 'PUT'
+ end
+
+ def delete?(request)
+ http_method(request) == 'DELETE'
+ end
+
+ # methods to be overridden by the including web server class
+
+ def http_method(request)
+ raise NotImplementedError
+ end
+
+ def path(request)
+ raise NotImplementedError
+ end
+
+ def request_key(request)
+ raise NotImplementedError
+ end
+
+ def body(request)
+ raise NotImplementedError
+ end
+
+ def params(request)
+ raise NotImplementedError
+ end
+
+ def decode_params(params)
+ params.inject({}) do |result, ary|
+ param, value = ary
+ next result if param.nil? || param.empty?
+
+ param = param.to_sym
+
+ # These shouldn't be allowed to be set by clients
+ # in the query string, for security reasons.
+ next result if param == :node
+ next result if param == :ip
+ value = CGI.unescape(value)
+ if value =~ /^---/
+ value = YAML.load(value)
+ else
+ value = true if value == "true"
+ value = false if value == "false"
+ value = Integer(value) if value =~ /^\d+$/
+ value = value.to_f if value =~ /^\d+\.\d+$/
+ end
+ result[param] = value
+ result
+ end
+ end
end