summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-07-28 11:23:08 -0500
committerLuke Kanies <luke@madstop.com>2008-07-29 00:51:22 -0500
commit4632cfd9e6ce0ff59dfa7562a02a1ae3f14488d4 (patch)
tree50f6c0ef591867bafe4ac9ea3c3f64d045bec573 /lib
parente3350caeec3a662b0b92ec2dee372563a493fa11 (diff)
downloadpuppet-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.rb22
-rw-r--r--lib/puppet/network/http.rb2
-rw-r--r--lib/puppet/network/http/handler.rb19
-rw-r--r--lib/puppet/network/http/mongrel/rest.rb10
-rw-r--r--lib/puppet/network/http/webrick/rest.rb10
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.