diff options
author | Luke Kanies <luke@madstop.com> | 2008-07-28 11:23:08 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2008-07-29 00:51:22 -0500 |
commit | 4632cfd9e6ce0ff59dfa7562a02a1ae3f14488d4 (patch) | |
tree | 50f6c0ef591867bafe4ac9ea3c3f64d045bec573 /lib | |
parent | e3350caeec3a662b0b92ec2dee372563a493fa11 (diff) | |
download | puppet-4632cfd9e6ce0ff59dfa7562a02a1ae3f14488d4.tar.gz puppet-4632cfd9e6ce0ff59dfa7562a02a1ae3f14488d4.tar.xz puppet-4632cfd9e6ce0ff59dfa7562a02a1ae3f14488d4.zip |
All error and format handling works over REST except searching.
Searching operates on multiple instances, and I have not
yet figured out how we should handle converting multiple
instances to a given format -- we can't use the instance
method (e.g., to_yaml), because it would be on Array
instead of the class we're operating on. That would work
for yaml, but not, for instance, for xml.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/puppet/indirector/rest.rb | 22 | ||||
-rw-r--r-- | lib/puppet/network/http.rb | 2 | ||||
-rw-r--r-- | lib/puppet/network/http/handler.rb | 19 | ||||
-rw-r--r-- | lib/puppet/network/http/mongrel/rest.rb | 10 | ||||
-rw-r--r-- | lib/puppet/network/http/webrick/rest.rb | 10 |
5 files changed, 46 insertions, 17 deletions
diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index 8889dbc3e..20c837fc9 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -6,11 +6,21 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus # Figure out the content type, turn that into a format, and use the format # to extract the body of the response. def deserialize(response) - # Raise the http error if we didn't get a 'success' of some kind. - response.error! unless response.code =~ /^2/ + case response.code + when "404" + return nil + when /^2/ + unless response['content-type'] + raise "No content type in http response; cannot parse" + end - # Convert the response to a deserialized object. - model.convert_from(response['content-type'], response.body) + # Convert the response to a deserialized object. + model.convert_from(response['content-type'], response.body) + else + # Raise the http error if we didn't get a 'success' of some kind. + message = "Server returned %s: %s" % [response.code, response.message] + raise Net::HTTPError.new(message, response) + end end # Provide appropriate headers. @@ -32,9 +42,9 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus def search(request) if request.key - path = "/#{indirection.name}/#{request.key}" + path = "/#{indirection.name}s/#{request.key}" else - path = "/#{indirection.name}" + path = "/#{indirection.name}s" end deserialize network.get(path, headers) end diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb index c219859b6..3b81d38b5 100644 --- a/lib/puppet/network/http.rb +++ b/lib/puppet/network/http.rb @@ -1,4 +1,4 @@ -class Puppet::Network::HTTP +module Puppet::Network::HTTP def self.server_class_by_type(kind) case kind.to_sym when :webrick: diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index ba95d3d11..1a21bfea9 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -29,7 +29,7 @@ module Puppet::Network::HTTP::Handler return do_save(request, response) if put?(request) and singular?(request) raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'" rescue Exception => e - return do_exception(request, response, e) + return do_exception(response, e) end # Are we interacting with a singular instance? @@ -52,11 +52,22 @@ module Puppet::Network::HTTP::Handler raise NotImplementedError end + def do_exception(response, exception, status=400) + if exception.is_a?(Exception) + puts exception.backtrace if Puppet[:trace] + puts exception if Puppet[:trace] + end + set_content_type(response, "text/plain") + set_response(response, exception.to_s, status) + end + # Execute our find. def do_find(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path(request)}]") args = params(request) - result = model.find(key, args) + unless result = model.find(key, args) + return do_exception(response, "Could not find %s %s" % [model.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 @@ -114,10 +125,6 @@ module Puppet::Network::HTTP::Handler object.save(args) end - def do_exception(request, response, exception, status=400) - set_response(response, exception.to_s, status) - end - def find_model_for_handler(handler) Puppet::Indirector::Indirection.model(handler) || raise(ArgumentError, "Cannot locate indirection [#{handler}].") diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index d6c2e4679..d265dde86 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -49,7 +49,15 @@ class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler # produce the body of the response def set_response(response, result, status = 200) - response.start(status) do |head, body| + args = [status] + + # Set the 'reason' (or 'message', as it's called in Webrick), when + # we have a failure. + if status >= 300 + args << false << result + end + + response.start(*args) do |head, body| body.write(result) end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index c7cc06916..13f795fb2 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -22,7 +22,7 @@ class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet end def accept_header(request) - request[:accept] + request["accept"] end def http_method(request) @@ -45,12 +45,16 @@ class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet # Set the specified format as the content type of the response. def set_content_type(response, format) - response[:content_type] = format + response["content-type"] = format end def set_response(response, result, status = 200) response.status = status - response.body = result + if status >= 200 and status < 300 + response.body = result + else + response.reason_phrase = result + end end # Retrieve node/cert/ip information from the request object. |