diff options
| author | Nick Lewis <nick@puppetlabs.com> | 2011-04-12 17:11:02 -0700 |
|---|---|---|
| committer | Nick Lewis <nick@puppetlabs.com> | 2011-04-12 17:11:02 -0700 |
| commit | d748338e69b705585f9ac6bf2fd8da1e9163839b (patch) | |
| tree | 8cd3d4a945fd5df18317db51fabd3f27767d9db4 | |
| parent | 40adee4ade3a447a7397a71d76e042091bbbfbff (diff) | |
| parent | 46721411066926aff3a7d5bb6470d3b8aec1b47d (diff) | |
| download | puppet-d748338e69b705585f9ac6bf2fd8da1e9163839b.tar.gz puppet-d748338e69b705585f9ac6bf2fd8da1e9163839b.tar.xz puppet-d748338e69b705585f9ac6bf2fd8da1e9163839b.zip | |
Merge branch 'ticket/next/6117' into next
| -rw-r--r-- | lib/puppet/indirector/rest.rb | 12 | ||||
| -rw-r--r-- | lib/puppet/network/http/api/v1.rb | 8 | ||||
| -rwxr-xr-x | spec/unit/indirector/rest_spec.rb | 33 | ||||
| -rwxr-xr-x | spec/unit/network/http/api/v1_spec.rb | 26 |
4 files changed, 70 insertions, 9 deletions
diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index e50dc68ae..0d3997221 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -72,7 +72,17 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus end def find(request) - return nil unless result = deserialize(network(request).get(indirection2uri(request), headers)) + uri, body = request_to_uri_and_body(request) + uri_with_query_string = "#{uri}?#{body}" + http_connection = network(request) + # WEBrick in Ruby 1.9.1 only supports up to 1024 character lines in an HTTP request + # http://redmine.ruby-lang.org/issues/show/3991 + response = if "GET #{uri_with_query_string} HTTP/1.1\r\n".length > 1024 + http_connection.post(uri, body, headers) + else + http_connection.get(uri_with_query_string, headers) + end + result = deserialize response result.name = request.key if result.respond_to?(:name=) result end diff --git a/lib/puppet/network/http/api/v1.rb b/lib/puppet/network/http/api/v1.rb index 5fe143979..61307f01e 100644 --- a/lib/puppet/network/http/api/v1.rb +++ b/lib/puppet/network/http/api/v1.rb @@ -8,6 +8,9 @@ module Puppet::Network::HTTP::API::V1 :plural => :search, :singular => :find }, + "POST" => { + :singular => :find, + }, "PUT" => { :singular => :save }, @@ -41,6 +44,11 @@ module Puppet::Network::HTTP::API::V1 "/#{request.environment.to_s}/#{indirection}/#{request.escaped_key}#{request.query_string}" end + def request_to_uri_and_body(request) + indirection = request.method == :search ? pluralize(request.indirection_name.to_s) : request.indirection_name.to_s + ["/#{request.environment.to_s}/#{indirection}/#{request.escaped_key}", request.query_string.sub(/^\?/,'')] + end + def indirection_method(http_method, indirection) raise ArgumentError, "No support for http method #{http_method}" unless METHOD_MAP[http_method] diff --git a/spec/unit/indirector/rest_spec.rb b/spec/unit/indirector/rest_spec.rb index d9c3068e8..29d00f1eb 100755 --- a/spec/unit/indirector/rest_spec.rb +++ b/spec/unit/indirector/rest_spec.rb @@ -224,13 +224,32 @@ describe Puppet::Indirector::REST do @searcher.stubs(:network).returns(@connection) # neuter the network connection # Use a key with spaces, so we can test escaping - @request = Puppet::Indirector::Request.new(:foo, :find, "foo bar") + @request = Puppet::Indirector::Request.new(:foo, :find, "foo bar", :environment => "myenv") end - it "should call the GET http method on a network connection" do - @searcher.expects(:network).returns @connection - @connection.expects(:get).returns @response - @searcher.find(@request) + describe "with a large body" do + it "should use the POST http method" do + params = {} + 'aa'.upto('zz') do |s| + params[s] = 'foo' + end + + @request = Puppet::Indirector::Request.new(:foo, :find, "foo bar", params.merge(:environment => "myenv")) + + @connection.expects(:post).with do |uri, body| + uri == "/myenv/foo/foo%20bar" and body.split("&").sort == params.map {|key,value| "#{key}=#{value}"}.sort + end.returns(@response) + + @searcher.find(@request) + end + end + + describe "with a small body" do + it "should use the GET http method" do + @searcher.expects(:network).returns @connection + @connection.expects(:get).returns @response + @searcher.find(@request) + end end it "should deserialize and return the http response, setting name" do @@ -252,10 +271,8 @@ describe Puppet::Indirector::REST do @searcher.find(@request).should == instance end - it "should use the URI generated by the Handler module" do - @searcher.expects(:indirection2uri).with(@request).returns "/my/uri" - @connection.expects(:get).with { |path, args| path == "/my/uri" }.returns(@response) + @connection.expects(:get).with { |path, args| path == "/myenv/foo/foo%20bar?" }.returns(@response) @searcher.find(@request) end diff --git a/spec/unit/network/http/api/v1_spec.rb b/spec/unit/network/http/api/v1_spec.rb index 3da8cbfae..d16ff122a 100755 --- a/spec/unit/network/http/api/v1_spec.rb +++ b/spec/unit/network/http/api/v1_spec.rb @@ -68,6 +68,10 @@ describe Puppet::Network::HTTP::API::V1 do @tester.uri2indirection("GET", "/env/foo/bar", {})[1].should == :find end + it "should choose 'find' as the indirection method if the http method is a POST and the indirection name is singular" do + @tester.uri2indirection("POST", "/env/foo/bar", {})[1].should == :find + end + it "should choose 'head' as the indirection method if the http method is a HEAD and the indirection name is singular" do @tester.uri2indirection("HEAD", "/env/foo/bar", {})[1].should == :head end @@ -164,4 +168,26 @@ describe Puppet::Network::HTTP::API::V1 do end end + describe "when converting a request into a URI with body" do + before :each do + @request = Puppet::Indirector::Request.new(:foo, :find, "with spaces", :foo => :bar, :environment => "myenv") + end + + it "should use the environment as the first field of the URI" do + @tester.request_to_uri_and_body(@request).first.split("/")[1].should == "myenv" + end + + it "should use the indirection as the second field of the URI" do + @tester.request_to_uri_and_body(@request).first.split("/")[2].should == "foo" + end + + it "should use the escaped key as the remainder of the URI" do + escaped = URI.escape("with spaces") + @tester.request_to_uri_and_body(@request).first.split("/")[3].sub(/\?.+/, '').should == escaped + end + + it "should return the URI and body separately" do + @tester.request_to_uri_and_body(@request).should == ["/myenv/foo/with%20spaces", "foo=bar"] + end + end end |
