summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrice Figureau <brice-puppet@daysofwonder.com>2009-07-05 19:38:01 +0200
committerBrice Figureau <brice-puppet@daysofwonder.com>2009-07-05 22:46:05 +0200
commit1e83aadc749aea9d52281d4f4041f6144a7229c7 (patch)
treecedb6c50b6b5c365d010e48fc42a74b1a5dc823a
parentaaca17a26092f3fece9a835eddf3ad6b9cf82300 (diff)
downloadpuppet-1e83aadc749aea9d52281d4f4041f6144a7229c7.tar.gz
puppet-1e83aadc749aea9d52281d4f4041f6144a7229c7.tar.xz
puppet-1e83aadc749aea9d52281d4f4041f6144a7229c7.zip
Fix #2392 - use Content-Type for REST communication
There were two problems: * server->client communications is using Content-Type with the direct format name instead of the format mime-type. * client->server communications is not using Content-Type to send the format of the serialized object. Instead it is using the first member of the Accept header. The Accept header is usually reserved for the other side, ie what the client will accept when the server will respond. This patch makes sure s->c communication contains correct Content-Type headers. This patch also adds a Content-Type header containing the mime-type of the object sent by the client when saving. Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
-rw-r--r--lib/puppet/indirector/rest.rb2
-rw-r--r--lib/puppet/network/format_handler.rb25
-rw-r--r--lib/puppet/network/http/handler.rb44
-rw-r--r--lib/puppet/network/http/mongrel/rest.rb6
-rw-r--r--lib/puppet/network/http/rack/rest.rb7
-rw-r--r--lib/puppet/network/http/webrick/rest.rb6
-rwxr-xr-xspec/integration/indirector/rest.rb5
-rwxr-xr-xspec/unit/indirector/rest.rb9
-rwxr-xr-xspec/unit/network/format_handler.rb82
-rwxr-xr-xspec/unit/network/http/handler.rb56
-rwxr-xr-xspec/unit/network/http/mongrel/rest.rb5
-rwxr-xr-xspec/unit/network/http/rack/rest.rb5
-rwxr-xr-xspec/unit/network/http/webrick/rest.rb5
13 files changed, 209 insertions, 48 deletions
diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb
index 6903f9a0d..909be9a45 100644
--- a/lib/puppet/indirector/rest.rb
+++ b/lib/puppet/indirector/rest.rb
@@ -81,7 +81,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
def save(request)
raise ArgumentError, "PUT does not accept options" unless request.options.empty?
- deserialize network(request).put(indirection2uri(request), request.instance.render, headers)
+ deserialize network(request).put(indirection2uri(request), request.instance.render, headers.merge({ "Content-Type" => request.instance.mime }))
end
private
diff --git a/lib/puppet/network/format_handler.rb b/lib/puppet/network/format_handler.rb
index 0a7e9dcad..17b863fda 100644
--- a/lib/puppet/network/format_handler.rb
+++ b/lib/puppet/network/format_handler.rb
@@ -23,7 +23,7 @@ module Puppet::Network::FormatHandler
@format = format
end
- [:intern, :intern_multiple, :render, :render_multiple].each do |method|
+ [:intern, :intern_multiple, :render, :render_multiple, :mime].each do |method|
define_method(method) do |*args|
protect(method, args)
end
@@ -65,11 +65,28 @@ module Puppet::Network::FormatHandler
# Use a delegator to make sure any exceptions generated by our formats are
# handled intelligently.
def self.protected_format(name)
+ name = format_to_canonical_name(name)
@format_protectors ||= {}
@format_protectors[name] ||= FormatProtector.new(name)
@format_protectors[name]
end
+ # Return a format name given:
+ # * a format name
+ # * a mime-type
+ # * a format instance
+ def self.format_to_canonical_name(format)
+ case format
+ when Puppet::Network::Format
+ out = format
+ when %r{\w+/\w+}
+ out = mime(format)
+ when
+ out = format(format)
+ end
+ out.name
+ end
+
module ClassMethods
def format_handler
Puppet::Network::FormatHandler
@@ -123,6 +140,12 @@ module Puppet::Network::FormatHandler
Puppet::Network::FormatHandler.protected_format(format).render(self)
end
+ def mime(format = nil)
+ format ||= self.class.default_format
+
+ Puppet::Network::FormatHandler.protected_format(format).mime
+ end
+
def support_format?(name)
self.class.support_format?(name)
end
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb
index 7a2408c67..4df2c4141 100644
--- a/lib/puppet/network/http/handler.rb
+++ b/lib/puppet/network/http/handler.rb
@@ -17,8 +17,14 @@ module Puppet::Network::HTTP::Handler
raise NotImplementedError
end
- # Which format to use when serializing our response. Just picks
- # the first value in the accept header, at this point.
+ # 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"
@@ -28,12 +34,25 @@ module Puppet::Network::HTTP::Handler
header.split(/,\s*/).each do |name|
next unless format = Puppet::Network::FormatHandler.format(name)
next unless format.suitable?
- return name
+ return format
end
raise "No specified acceptable formats (%s) are functional on this machine" % header
end
+ def request_format(request)
+ if header = content_type_header(request)
+ format = Puppet::Network::FormatHandler.mime(header)
+ 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
@@ -106,9 +125,7 @@ module Puppet::Network::HTTP::Handler
def do_destroy(indirection_request, request, response)
result = indirection_request.model.destroy(indirection_request.key, indirection_request.to_hash)
- set_content_type(response, "yaml")
-
- set_response(response, result.to_yaml)
+ return_yaml_response(response, result)
end
# Execute our save.
@@ -116,14 +133,10 @@ module Puppet::Network::HTTP::Handler
data = body(request).to_s
raise ArgumentError, "No data to save" if !data or data.empty?
- format = format_to_use(request)
-
- obj = indirection_request.model.convert_from(format_to_use(request), data)
+ format = request_format(request)
+ obj = indirection_request.model.convert_from(format, data)
result = save_object(indirection_request, obj)
-
- set_content_type(response, "yaml")
-
- set_response(response, result.to_yaml)
+ return_yaml_response(response, result)
end
# resolve node name from peer's ip address
@@ -139,6 +152,11 @@ module Puppet::Network::HTTP::Handler
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)
diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb
index 369d4c6c4..fe1ed1088 100644
--- a/lib/puppet/network/http/mongrel/rest.rb
+++ b/lib/puppet/network/http/mongrel/rest.rb
@@ -15,6 +15,10 @@ class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler
request.params[ACCEPT_HEADER]
end
+ def content_type_header(request)
+ request.params["HTTP_CONTENT_TYPE"]
+ end
+
# which HTTP verb was used in this request
def http_method(request)
request.params[Mongrel::Const::REQUEST_METHOD]
@@ -41,7 +45,7 @@ class Puppet::Network::HTTP::MongrelREST < Mongrel::HttpHandler
end
def set_content_type(response, format)
- response.header['Content-Type'] = format
+ response.header['Content-Type'] = format_to_mime(format)
end
# produce the body of the response
diff --git a/lib/puppet/network/http/rack/rest.rb b/lib/puppet/network/http/rack/rest.rb
index e98bffc1e..f2ba39336 100644
--- a/lib/puppet/network/http/rack/rest.rb
+++ b/lib/puppet/network/http/rack/rest.rb
@@ -14,7 +14,7 @@ class Puppet::Network::HTTP::RackREST < Puppet::Network::HTTP::RackHttpHandler
end
def set_content_type(response, format)
- response[ContentType] = format
+ response[ContentType] = format_to_mime(format)
end
# produce the body of the response
@@ -28,6 +28,11 @@ class Puppet::Network::HTTP::RackREST < Puppet::Network::HTTP::RackHttpHandler
request.env[HEADER_ACCEPT]
end
+ # Retrieve the accept header from the http request.
+ def content_type_header(request)
+ request.env['HTTP_CONTENT_TYPE']
+ end
+
# Return which HTTP verb was used in this request.
def http_method(request)
request.request_method
diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb
index 5f77da87a..287fa39ac 100644
--- a/lib/puppet/network/http/webrick/rest.rb
+++ b/lib/puppet/network/http/webrick/rest.rb
@@ -27,6 +27,10 @@ class Puppet::Network::HTTP::WEBrickREST < WEBrick::HTTPServlet::AbstractServlet
request["accept"]
end
+ def content_type_header(request)
+ request["content-type"]
+ end
+
def http_method(request)
request.request_method
end
@@ -41,7 +45,7 @@ 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_to_mime(format)
end
def set_response(response, result, status = 200)
diff --git a/spec/integration/indirector/rest.rb b/spec/integration/indirector/rest.rb
index 27ffc95fe..077a74f1c 100755
--- a/spec/integration/indirector/rest.rb
+++ b/spec/integration/indirector/rest.rb
@@ -109,7 +109,7 @@ describe Puppet::Indirector::REST do
it "should use a supported format" do
Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
text = Marshal.dump(@model_instance)
- @model_instance.expects(:render).with("marshal").returns text
+ @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
Puppet::TestIndirectedFoo.find('bar')
end
end
@@ -345,8 +345,9 @@ describe Puppet::Indirector::REST do
it "should use a supported format" do
Puppet::TestIndirectedFoo.expects(:supported_formats).returns ["marshal"]
+ format = stub 'format'
text = Marshal.dump(@model_instance)
- @model_instance.expects(:render).with("marshal").returns text
+ @model_instance.expects(:render).with(Puppet::Network::FormatHandler.format("marshal")).returns text
Puppet::TestIndirectedFoo.find('bar')
end
end
diff --git a/spec/unit/indirector/rest.rb b/spec/unit/indirector/rest.rb
index 9f77deb55..696af9ae7 100755
--- a/spec/unit/indirector/rest.rb
+++ b/spec/unit/indirector/rest.rb
@@ -306,7 +306,7 @@ describe Puppet::Indirector::REST do
@connection = stub('mock http connection', :put => @response)
@searcher.stubs(:network).returns(@connection) # neuter the network connection
- @instance = stub 'instance', :render => "mydata"
+ @instance = stub 'instance', :render => "mydata", :mime => "mime"
@request = Puppet::Indirector::Request.new(:foo, :save, "foo bar")
@request.instance = @instance
end
@@ -350,6 +350,13 @@ describe Puppet::Indirector::REST do
@searcher.save(@request)
end
+ it "should provide a Content-Type header containing the mime-type of the sent object" do
+ @connection.expects(:put).with { |path, data, args| args['Content-Type'] == "mime" }.returns(@response)
+
+ @instance.expects(:mime).returns "mime"
+ @searcher.save(@request)
+ end
+
it "should deserialize and return the network response" do
@searcher.expects(:deserialize).with(@response).returns @instance
@searcher.save(@request).should equal(@instance)
diff --git a/spec/unit/network/format_handler.rb b/spec/unit/network/format_handler.rb
index 54409b92a..604ae1be3 100755
--- a/spec/unit/network/format_handler.rb
+++ b/spec/unit/network/format_handler.rb
@@ -71,7 +71,8 @@ describe Puppet::Network::FormatHandler do
it "should delegate all methods from the informative format to the specified format" do
format = mock 'format'
- Puppet::Network::FormatHandler.expects(:format).with(:myformat).returns format
+ format.stubs(:name).returns(:myformat)
+ Puppet::Network::FormatHandler.expects(:format).twice.with(:myformat).returns format
format.expects(:render).with("foo").returns "yay"
Puppet::Network::FormatHandler.protected_format(:myformat).render("foo").should == "yay"
@@ -79,7 +80,8 @@ describe Puppet::Network::FormatHandler do
it "should provide better logging if a failure is encountered when delegating from the informative format to the real format" do
format = mock 'format'
- Puppet::Network::FormatHandler.expects(:format).with(:myformat).returns format
+ format.stubs(:name).returns(:myformat)
+ Puppet::Network::FormatHandler.expects(:format).twice.with(:myformat).returns format
format.expects(:render).with("foo").raises "foo"
lambda { Puppet::Network::FormatHandler.protected_format(:myformat).render("foo") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
@@ -88,8 +90,12 @@ describe Puppet::Network::FormatHandler do
describe "when using formats" do
before do
@format = mock 'format'
- Puppet::Network::FormatHandler.stubs(:format).with(:my_format).returns @format
@format.stubs(:supported?).returns true
+ @format.stubs(:name).returns :my_format
+ Puppet::Network::FormatHandler.stubs(:format).with(:my_format).returns @format
+ Puppet::Network::FormatHandler.stubs(:mime).with("text/myformat").returns @format
+ Puppet::Network::Format.stubs(:===).returns false
+ Puppet::Network::Format.stubs(:===).with(@format).returns true
end
it "should be able to test whether a format is supported" do
@@ -110,6 +116,16 @@ describe Puppet::Network::FormatHandler do
FormatTester.convert_from(:my_format, "mydata")
end
+ it "should call the format-specific converter when asked to convert from a given format by mime-type" do
+ @format.expects(:intern).with(FormatTester, "mydata")
+ FormatTester.convert_from("text/myformat", "mydata")
+ end
+
+ it "should call the format-specific converter when asked to convert from a given format by format instance" do
+ @format.expects(:intern).with(FormatTester, "mydata")
+ FormatTester.convert_from(@format, "mydata")
+ end
+
it "should raise a FormatError when an exception is encountered when converting from a format" do
@format.expects(:intern).with(FormatTester, "mydata").raises "foo"
lambda { FormatTester.convert_from(:my_format, "mydata") }.should raise_error(Puppet::Network::FormatHandler::FormatError)
@@ -144,7 +160,7 @@ describe Puppet::Network::FormatHandler do
end
it "should create a format instance when asked" do
- format = stub 'format', :name => "foo"
+ format = stub 'format', :name => :foo
Puppet::Network::Format.expects(:new).with(:foo).returns format
Puppet::Network::FormatHandler.create(:foo)
end
@@ -202,8 +218,12 @@ describe Puppet::Network::FormatHandler do
FormatTester.new.should respond_to(:render)
end
+ it "should be able to get a format mime-type" do
+ FormatTester.new.should respond_to(:mime)
+ end
+
it "should raise a FormatError when a rendering error is encountered" do
- format = stub 'rendering format', :supported? => true
+ format = stub 'rendering format', :supported? => true, :name => :foo
Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
tester = FormatTester.new
@@ -213,7 +233,7 @@ describe Puppet::Network::FormatHandler do
end
it "should call the format-specific converter when asked to convert to a given format" do
- format = stub 'rendering format', :supported? => true
+ format = stub 'rendering format', :supported? => true, :name => :foo
Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
@@ -223,15 +243,59 @@ describe Puppet::Network::FormatHandler do
tester.render(:foo).should == "foo"
end
+ it "should call the format-specific converter when asked to convert to a given format by mime-type" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::FormatHandler.stubs(:mime).with("text/foo").returns format
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+
+ tester = FormatTester.new
+ format.expects(:render).with(tester).returns "foo"
+
+ tester.render("text/foo").should == "foo"
+ end
+
+ it "should call the format converter when asked to convert to a given format instance" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::Format.stubs(:===).with(format).returns(true)
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+
+ tester = FormatTester.new
+ format.expects(:render).with(tester).returns "foo"
+
+ tester.render(format).should == "foo"
+ end
+
it "should render to the default format if no format is provided when rendering" do
- format = stub 'rendering format', :supported? => true
- Puppet::Network::FormatHandler.stubs(:format).with("foo").returns format
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
- FormatTester.expects(:default_format).returns "foo"
+ FormatTester.expects(:default_format).returns :foo
tester = FormatTester.new
format.expects(:render).with(tester)
tester.render
end
+
+ it "should call the format-specific converter when asked for the mime-type of a given format" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+
+ tester = FormatTester.new
+ format.expects(:mime).returns "text/foo"
+
+ tester.mime(:foo).should == "text/foo"
+ end
+
+ it "should return the default format mime-type if no format is provided" do
+ format = stub 'rendering format', :supported? => true, :name => :foo
+ Puppet::Network::FormatHandler.stubs(:format).with(:foo).returns format
+
+ FormatTester.expects(:default_format).returns :foo
+ tester = FormatTester.new
+
+ format.expects(:mime).returns "text/foo"
+ tester.mime.should == "text/foo"
+ end
end
end
diff --git a/spec/unit/network/http/handler.rb b/spec/unit/network/http/handler.rb
index 8ef6e00d1..a0c817361 100755
--- a/spec/unit/network/http/handler.rb
+++ b/spec/unit/network/http/handler.rb
@@ -57,13 +57,14 @@ describe Puppet::Network::HTTP::Handler do
# Stub out the interface we require our including classes to
# implement.
def stub_server_interface
- @handler.stubs(:accept_header ).returns "format_one,format_two"
- @handler.stubs(:set_content_type).returns "my_result"
- @handler.stubs(:set_response ).returns "my_result"
- @handler.stubs(:path ).returns "/my_handler/my_result"
- @handler.stubs(:http_method ).returns("GET")
- @handler.stubs(:params ).returns({})
- @handler.stubs(:content_type ).returns("text/plain")
+ @handler.stubs(:accept_header ).returns "format_one,format_two"
+ @handler.stubs(:content_type_header).returns "text/yaml"
+ @handler.stubs(:set_content_type ).returns "my_result"
+ @handler.stubs(:set_response ).returns "my_result"
+ @handler.stubs(:path ).returns "/my_handler/my_result"
+ @handler.stubs(:http_method ).returns("GET")
+ @handler.stubs(:params ).returns({})
+ @handler.stubs(:content_type ).returns("text/plain")
end
it "should create an indirection request from the path, parameters, and http method" do
@@ -134,8 +135,11 @@ describe Puppet::Network::HTTP::Handler do
@model_class.stubs(:find).returns @result
- @format = stub 'format', :suitable? => true
+ @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
Puppet::Network::FormatHandler.stubs(:format).returns @format
+
+ @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
+ Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
end
it "should use the indirection request to find the model class" do
@@ -161,7 +165,7 @@ describe Puppet::Network::HTTP::Handler do
it "should set the content type to the first format specified in the accept header" do
@handler.expects(:accept_header).with(@request).returns "one,two"
- @handler.expects(:set_content_type).with(@response, "one")
+ @handler.expects(:set_content_type).with(@response, @oneformat)
@handler.do_find(@irequest, @request, @response)
end
@@ -182,14 +186,15 @@ describe Puppet::Network::HTTP::Handler do
Puppet::Network::FormatHandler.expects(:format).with("foo").returns foo
Puppet::Network::FormatHandler.expects(:format).with("bar").returns bar
- @handler.expects(:set_content_type).with(@response, "bar") # the suitable one
+ @handler.expects(:set_content_type).with(@response, bar) # the suitable one
@handler.do_find(@irequest, @request, @response)
end
it "should render the result using the first format specified in the accept header" do
+
@handler.expects(:accept_header).with(@request).returns "one,two"
- @result.expects(:render).with("one")
+ @result.expects(:render).with(@oneformat)
@handler.do_find(@irequest, @request, @response)
end
@@ -218,8 +223,8 @@ describe Puppet::Network::HTTP::Handler do
it "should serialize the result in with the appropriate format" do
@model_instance = stub('model instance')
- @handler.expects(:format_to_use).returns "one"
- @model_instance.expects(:render).with("one").returns "my_rendered_object"
+ @handler.expects(:format_to_use).returns(@oneformat)
+ @model_instance.expects(:render).with(@oneformat).returns "my_rendered_object"
@model_class.stubs(:find).returns(@model_instance)
@handler.do_find(@irequest, @request, @response)
end
@@ -236,8 +241,11 @@ describe Puppet::Network::HTTP::Handler do
@model_class.stubs(:render_multiple).returns "my rendered instances"
@model_class.stubs(:search).returns(@result)
- @format = stub 'format', :suitable? => true
+ @format = stub 'format', :suitable? => true, :mime => "text/format", :name => "format"
Puppet::Network::FormatHandler.stubs(:format).returns @format
+
+ @oneformat = stub 'one', :suitable? => true, :mime => "text/one", :name => "one"
+ Puppet::Network::FormatHandler.stubs(:format).with("one").returns @oneformat
end
it "should use the indirection request to find the model" do
@@ -261,7 +269,7 @@ describe Puppet::Network::HTTP::Handler do
it "should set the content type to the first format returned by the accept header" do
@handler.expects(:accept_header).with(@request).returns "one,two"
- @handler.expects(:set_content_type).with(@response, "one")
+ @handler.expects(:set_content_type).with(@response, @oneformat)
@handler.do_search(@irequest, @request, @response)
end
@@ -271,7 +279,7 @@ describe Puppet::Network::HTTP::Handler do
@model_class.stubs(:search).returns(@result)
- @model_class.expects(:render_multiple).with("one", @result).returns "my rendered instances"
+ @model_class.expects(:render_multiple).with(@oneformat, @result).returns "my rendered instances"
@handler.expects(:set_response).with { |response, data| data == "my rendered instances" }
@handler.do_search(@irequest, @request, @response)
@@ -341,14 +349,17 @@ describe Puppet::Network::HTTP::Handler do
before do
@irequest = stub 'indirection_request', :method => :save, :indirection_name => "my_handler", :to_hash => {}, :key => "key", :model => @model_class
@handler.stubs(:body).returns('my stuff')
+ @handler.stubs(:content_type_header).returns("text/yaml")
@result = stub 'result', :render => "the result"
@model_instance = stub('indirected model instance', :save => true)
@model_class.stubs(:convert_from).returns(@model_instance)
- @format = stub 'format', :suitable? => true
+ @format = stub 'format', :suitable? => true, :name => "format", :mime => "text/format"
Puppet::Network::FormatHandler.stubs(:format).returns @format
+ @yamlformat = stub 'yaml', :suitable? => true, :name => "yaml", :mime => "text/yaml"
+ Puppet::Network::FormatHandler.stubs(:format).with("yaml").returns @yamlformat
end
it "should use the indirection request to find the model" do
@@ -390,7 +401,16 @@ describe Puppet::Network::HTTP::Handler do
end
it "should set the content to yaml" do
- @handler.expects(:set_content_type).with(@response, "yaml")
+ @handler.expects(:set_content_type).with(@response, @yamlformat)
+ @handler.do_save(@irequest, @request, @response)
+ end
+
+ it "should use the content-type header to know the body format" do
+ @handler.expects(:content_type_header).returns("text/format")
+ Puppet::Network::FormatHandler.stubs(:mime).with("text/format").returns @format
+
+ @model_class.expects(:convert_from).with { |format, body| format == "format" }.returns @model_instance
+
@handler.do_save(@irequest, @request, @response)
end
end
diff --git a/spec/unit/network/http/mongrel/rest.rb b/spec/unit/network/http/mongrel/rest.rb
index abd573a25..5dd3d6475 100755
--- a/spec/unit/network/http/mongrel/rest.rb
+++ b/spec/unit/network/http/mongrel/rest.rb
@@ -43,6 +43,11 @@ describe "Puppet::Network::HTTP::MongrelREST" do
@handler.accept_header(@request).should == "myaccept"
end
+ it "should return the Content-Type parameter as the Content-Type header" do
+ @params.expects(:[]).with("HTTP_CONTENT_TYPE").returns "mycontent"
+ @handler.content_type_header(@request).should == "mycontent"
+ end
+
it "should use the REQUEST_METHOD as the http method" do
@params.expects(:[]).with(Mongrel::Const::REQUEST_METHOD).returns "mymethod"
@handler.http_method(@request).should == "mymethod"
diff --git a/spec/unit/network/http/rack/rest.rb b/spec/unit/network/http/rack/rest.rb
index 1e3efe9ca..3a36a0b67 100755
--- a/spec/unit/network/http/rack/rest.rb
+++ b/spec/unit/network/http/rack/rest.rb
@@ -40,6 +40,11 @@ describe "Puppet::Network::HTTP::RackREST" do
@handler.accept_header(req).should == "myaccept"
end
+ it "should return the HTTP_CONTENT_TYPE parameter as the content type header" do
+ req = mk_req('/', 'HTTP_CONTENT_TYPE' => 'mycontent')
+ @handler.content_type_header(req).should == "mycontent"
+ end
+
it "should use the REQUEST_METHOD as the http method" do
req = mk_req('/', :method => 'mymethod')
@handler.http_method(req).should == "mymethod"
diff --git a/spec/unit/network/http/webrick/rest.rb b/spec/unit/network/http/webrick/rest.rb
index 9d9f20026..55099055c 100755
--- a/spec/unit/network/http/webrick/rest.rb
+++ b/spec/unit/network/http/webrick/rest.rb
@@ -37,6 +37,11 @@ describe Puppet::Network::HTTP::WEBrickREST do
@handler.accept_header(@request).should == "foobar"
end
+ it "should use the 'content-type' request header as the Content-Type header" do
+ @request.expects(:[]).with("content-type").returns "foobar"
+ @handler.content_type_header(@request).should == "foobar"
+ end
+
it "should use the request method as the http method" do
@request.expects(:request_method).returns "FOO"
@handler.http_method(@request).should == "FOO"